From 7f2f062a5d9edb60bf6d5c80b537cabb57324e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 3 Sep 2015 10:44:32 +0200 Subject: [PATCH 01/73] Fix possible client crash on API misuse --- ChangeLog | 5 +++++ library/ssl_cli.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index d3636f00a..fdab585dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,11 @@ Features * Added support for yotta as a build system. * Primary open source license changed to Apache 2.0 license. +Security + * Fix possible client-side NULL pointer dereference (read) when the client + tries to continue the handshake after it failed (a misuse of the API). + (Found by GDS Labs using afl-fuzz, patch provided by GDS Labs.) + Bugfix * Fix segfault in the benchmark program when benchmarking DHM. * Fix build error with CMake and pre-4.5 versions of GCC (found by Hugo diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 5a9c43222..c82e2e70a 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1771,6 +1771,12 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, ssl->handshake->pmslen = 48; + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + /* * Now write it out, encrypted */ @@ -1873,6 +1879,12 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) int ret; const mbedtls_ecp_keypair *peer_key; + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, MBEDTLS_PK_ECKEY ) ) { @@ -2182,6 +2194,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + /* * Verify signature */ From dbd23079d0f2f571bf8aa27569a8b8fac0176f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 4 Sep 2015 10:20:17 +0200 Subject: [PATCH 02/73] Add option reconnect_hard to ssl_client2 - interrupt the connection abruptly (no close_notify) - reconnect from the same port while server sill has an active connection from this port. Some real-world clients do that, see section 4.2.8 of RFC 6347. --- programs/ssl/ssl_client2.c | 45 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 99c2d2a5e..758ebf34a 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -90,6 +90,7 @@ int main( void ) #define DFL_DHMLEN -1 #define DFL_RECONNECT 0 #define DFL_RECO_DELAY 0 +#define DFL_RECONNECT_HARD 0 #define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED #define DFL_ALPN_STRING NULL #define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM @@ -238,6 +239,7 @@ int main( void ) " exchanges=%%d default: 1\n" \ " reconnect=%%d default: 0 (disabled)\n" \ " reco_delay=%%d default: 0 seconds\n" \ + " reconnect_hard=%%d default: 0 (disabled)\n" \ USAGE_TICKETS \ USAGE_MAX_FRAG_LEN \ USAGE_TRUNC_HMAC \ @@ -293,6 +295,7 @@ struct options int dhmlen; /* minimum DHM params len in bits */ int reconnect; /* attempt to resume session */ int reco_delay; /* delay in seconds before resuming session */ + int reconnect_hard; /* unexpectedly reconnect from the same port */ int tickets; /* enable / disable session tickets */ const char *alpn_string; /* ALPN supported protocols */ int transport; /* TLS or DTLS? */ @@ -481,6 +484,7 @@ int main( int argc, char *argv[] ) opt.dhmlen = DFL_DHMLEN; opt.reconnect = DFL_RECONNECT; opt.reco_delay = DFL_RECO_DELAY; + opt.reconnect_hard = DFL_RECONNECT_HARD; opt.tickets = DFL_TICKETS; opt.alpn_string = DFL_ALPN_STRING; opt.transport = DFL_TRANSPORT; @@ -603,6 +607,12 @@ int main( int argc, char *argv[] ) if( opt.reco_delay < 0 ) goto usage; } + else if( strcmp( p, "reconnect_hard" ) == 0 ) + { + opt.reconnect_hard = atoi( q ); + if( opt.reconnect_hard < 0 || opt.reconnect_hard > 1 ) + goto usage; + } else if( strcmp( p, "tickets" ) == 0 ) { opt.tickets = atoi( q ); @@ -1479,7 +1489,38 @@ send_request: } /* - * 7b. Continue doing data exchanges? + * 7b. Simulate hard reset and reconnect from same port? + */ + if( opt.reconnect_hard != 0 ) + { + opt.reconnect_hard = 0; + + mbedtls_printf( " . Restarting connection from same port..." ); + fflush( stdout ); + + if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_session_reset returned -0x%x\n\n", -ret ); + goto exit; + } + + while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) + { + if( ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); + goto exit; + } + } + + mbedtls_printf( " ok\n" ); + + goto send_request; + } + + /* + * 7c. Continue doing data exchanges? */ if( --opt.exchanges > 0 ) goto send_request; @@ -1489,6 +1530,7 @@ send_request: */ close_notify: mbedtls_printf( " . Closing the connection..." ); + fflush( stdout ); /* No error checking, the connection might be closed already */ do ret = mbedtls_ssl_close_notify( &ssl ); @@ -1513,7 +1555,6 @@ reconnect: #endif mbedtls_printf( " . Reconnecting with saved session..." ); - fflush( stdout ); if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 ) { From 26d227ddfc5bf6283b44be0618a85fc3cebde63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 4 Sep 2015 10:53:25 +0200 Subject: [PATCH 03/73] Add config flag for support of client port reuse --- include/mbedtls/config.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 66657da55..4956d0476 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1134,6 +1134,20 @@ */ #define MBEDTLS_SSL_DTLS_HELLO_VERIFY +/** + * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + * + * Enable server-side support for clients that reconnect from the same port. + * + * Some clients unexpectedly close the connection and try to reconnect using the + * same source port. This needs special support from the server to handle the + * new connection securely, as described in section 4.1.8 of RFC 6347. This + * flag enables that support. + * + * Comment this to disable support for clients reusing the source port. + */ +#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + /** * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT * From 9650205df7fbe16facf1972aa07e4301300e8d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 4 Sep 2015 12:58:55 +0200 Subject: [PATCH 04/73] Start detecting epoch 0 ClientHellos --- library/ssl_tls.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 14ee521ca..ded856948 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3341,13 +3341,35 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) if( rec_epoch != ssl->in_epoch ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " - "expected %d, received %d", - ssl->in_epoch, rec_epoch ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + "expected %d, received %d", + ssl->in_epoch, rec_epoch ) ); + +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ + defined(MBEDTLS_SSL_SRV_C) + /* + * Check for an epoch 0 ClientHello. We can't use in_msg here to + * access the first byte of record content (handshake type), as we + * have an active transform (possibly iv_len != 0), so use the + * fact that the record header len is 13 instead. + */ + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + rec_epoch == 0 && + ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_left > 13 && + ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " + "from the same port" ) ); + } + else +#endif /* MBEDTLS_SSL_DLTS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) + /* Replay detection only works for the current epoch */ + if( rec_epoch == ssl->in_epoch && + mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); From 11331fc25b2ed61cdb196e65e3b7b6c5c67a017d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 10:30:55 +0200 Subject: [PATCH 05/73] First working dirty version - uses too much resources - wrong API --- library/ssl_tls.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ded856948..75e14d5a6 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3250,6 +3250,113 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ + defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ + defined(MBEDTLS_SSL_SRV_C) +/* Dummy timer callbacks (temporary) */ +static void ssl_dummy_set_timer(void *ctx, uint32_t int_ms, uint32_t fin_ms) { + (void) ctx; (void) int_ms; (void) fin_ms; } +static int ssl_dummy_get_timer(void *ctx) { (void) ctx; return( 0 ); } + +/* Dummy recv callback (temporary) */ +static int ssl_dummy_recv(void *ctx, unsigned char *buf, size_t len) { + (void) ctx; (void) buf; (void) len; return( 0 ); } + +/* + * Handle possible client reconnect with the same UDP quadruplet + * (RFC 6347 Section 4.2.8). + * + * Called by ssl_parse_record_header() in case we receive an epoch 0 record + * that looks like a ClientHello. + * + * - if the input looks wrong, + * return MBEDTLS_ERR_SSL_INVALID_RECORD (ignore this record) + * - if the input looks like a ClientHello without cookies, + * send back HelloVerifyRequest, then + * return MBEDTLS_ERR_SSL_INVALID_RECORD (ignore this record) + * - if the input looks like a ClientHello with a valid cookie, + * reset the session of the current context, and + * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT (WIP: TODO) + * + * Currently adopts a heavyweight strategy by allocating a secondary ssl + * context. Will be refactored into something more acceptable later. + */ +static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) +{ + int ret; + mbedtls_ssl_context tmp_ssl; + int cookie_is_good; + + mbedtls_ssl_init( &tmp_ssl ); + + /* Prepare temporary ssl context */ + ret = mbedtls_ssl_setup( &tmp_ssl, ssl->conf ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 0, "nested ssl_setup", ret ); + ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + goto cleanup; + } + + mbedtls_ssl_set_timer_cb( &tmp_ssl, NULL, ssl_dummy_set_timer, + ssl_dummy_get_timer ); + + ret = mbedtls_ssl_set_client_transport_id( &tmp_ssl, + ssl->cli_id, ssl->cli_id_len ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 0, "nested set_client_id", ret ); + ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + goto cleanup; + } + + mbedtls_ssl_set_bio( &tmp_ssl, ssl->p_bio, ssl->f_send, + ssl_dummy_recv, NULL ); + + memcpy( tmp_ssl.in_buf, ssl->in_buf, ssl->in_left ); + tmp_ssl.in_left = ssl->in_left; + + tmp_ssl.state = MBEDTLS_SSL_CLIENT_HELLO; + + /* Parse packet and check if cookie is good */ + ret = mbedtls_ssl_handshake_step( &tmp_ssl ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 0, "nested handshake_step", ret ); + ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + goto cleanup; + } + + cookie_is_good = tmp_ssl.handshake->verify_cookie_len == 0; + MBEDTLS_SSL_DEBUG_MSG( 0, ( "good ClientHello with %s cookie", + cookie_is_good ? "good" : "bad" ) ); + + /* Send HelloVerifyRequest? */ + if( !cookie_is_good ) + { + ret = mbedtls_ssl_handshake_step( &tmp_ssl ); + MBEDTLS_SSL_DEBUG_RET( 0, "nested handshake_step", ret ); + + ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + goto cleanup; + } + + /* We should retrieve the content of the ClientHello from tmp_ssl, + * instead let's play it dirty for this temporary version and just trust + * that the client will resend */ + mbedtls_ssl_session_reset( ssl ); + + /* ret = ... */ + +cleanup: + mbedtls_ssl_free( &tmp_ssl ); + + return( ret ); +} +#endif /* MBEDTLS_SSL_PROTO_DTLS && + MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && + MBEDTLS_SSL_SRV_C */ + /* * ContentType type; * ProtocolVersion version; @@ -3360,6 +3467,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " "from the same port" ) ); + return( ssl_handle_possible_reconnect( ssl ) ); } else #endif /* MBEDTLS_SSL_DLTS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ From be619c1264686e2c0e06de3b5ff6cdbe9360ea13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 11:21:21 +0200 Subject: [PATCH 06/73] Clean up error codes --- include/mbedtls/ssl.h | 1 + library/error.c | 2 ++ library/ssl_tls.c | 26 +++++++++++++------------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index bd88918ca..8ff453929 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -125,6 +125,7 @@ #define MBEDTLS_ERR_SSL_WANT_READ -0x6900 /**< Connection requires a read call. */ #define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */ #define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ +#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */ /* * Various constants diff --git a/library/error.c b/library/error.c index a7de11007..a1cf83aed 100644 --- a/library/error.c +++ b/library/error.c @@ -428,6 +428,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" ); if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) ) mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) ) + mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); #endif /* MBEDTLS_SSL_TLS_C */ #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 75e14d5a6..c4dfd61e7 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3276,7 +3276,7 @@ static int ssl_dummy_recv(void *ctx, unsigned char *buf, size_t len) { * return MBEDTLS_ERR_SSL_INVALID_RECORD (ignore this record) * - if the input looks like a ClientHello with a valid cookie, * reset the session of the current context, and - * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT (WIP: TODO) + * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT * * Currently adopts a heavyweight strategy by allocating a secondary ssl * context. Will be refactored into something more acceptable later. @@ -3293,8 +3293,7 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) ret = mbedtls_ssl_setup( &tmp_ssl, ssl->conf ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 0, "nested ssl_setup", ret ); - ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + MBEDTLS_SSL_DEBUG_RET( 1, "nested ssl_setup", ret ); goto cleanup; } @@ -3305,8 +3304,7 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) ssl->cli_id, ssl->cli_id_len ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 0, "nested set_client_id", ret ); - ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + MBEDTLS_SSL_DEBUG_RET( 1, "nested set_client_id", ret ); goto cleanup; } @@ -3322,22 +3320,20 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) ret = mbedtls_ssl_handshake_step( &tmp_ssl ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 0, "nested handshake_step", ret ); - ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + MBEDTLS_SSL_DEBUG_RET( 1, "nested handshake_step", ret ); goto cleanup; } cookie_is_good = tmp_ssl.handshake->verify_cookie_len == 0; - MBEDTLS_SSL_DEBUG_MSG( 0, ( "good ClientHello with %s cookie", + MBEDTLS_SSL_DEBUG_MSG( 1, ( "good ClientHello with %s cookie", cookie_is_good ? "good" : "bad" ) ); /* Send HelloVerifyRequest? */ if( !cookie_is_good ) { ret = mbedtls_ssl_handshake_step( &tmp_ssl ); - MBEDTLS_SSL_DEBUG_RET( 0, "nested handshake_step", ret ); - - ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + if( ret != 0 ) + MBEDTLS_SSL_DEBUG_RET( 1, "nested handshake_step", ret ); goto cleanup; } @@ -3346,11 +3342,14 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) * that the client will resend */ mbedtls_ssl_session_reset( ssl ); - /* ret = ... */ + ret = MBEDTLS_ERR_SSL_CLIENT_RECONNECT; cleanup: mbedtls_ssl_free( &tmp_ssl ); + if( ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) + ret = MBEDTLS_ERR_SSL_INVALID_RECORD; + return( ret ); } #endif /* MBEDTLS_SSL_PROTO_DTLS && @@ -3658,7 +3657,8 @@ read_record_header: if( ( ret = ssl_parse_record_header( ssl ) ) != 0 ) { #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) { /* Ignore bad record and get next one; drop the whole datagram * since current header cannot be trusted to find the next record From 3f09b6d4c209f42d9cfe8f1de1bb7285c50d2a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 11:58:14 +0200 Subject: [PATCH 07/73] Fix API --- library/ssl_tls.c | 43 +++++++++++++++++++++++++++++--------- programs/ssl/ssl_server2.c | 7 +++++++ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index c4dfd61e7..4addeb7d9 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3262,6 +3262,9 @@ static int ssl_dummy_get_timer(void *ctx) { (void) ctx; return( 0 ); } static int ssl_dummy_recv(void *ctx, unsigned char *buf, size_t len) { (void) ctx; (void) buf; (void) len; return( 0 ); } +/* Forward declatation */ +static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); + /* * Handle possible client reconnect with the same UDP quadruplet * (RFC 6347 Section 4.2.8). @@ -3337,10 +3340,13 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) goto cleanup; } - /* We should retrieve the content of the ClientHello from tmp_ssl, - * instead let's play it dirty for this temporary version and just trust - * that the client will resend */ - mbedtls_ssl_session_reset( ssl ); + /* Reset context while preserving some information */ + ret = ssl_session_reset_int( ssl, 1 ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); + goto cleanup; + } ret = MBEDTLS_ERR_SSL_CLIENT_RECONNECT; @@ -5253,8 +5259,11 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, /* * Reset an initialized and used SSL context for re-use while retaining * all application-set variables, function pointers and data. + * + * If partial is non-zero, keep data in the input buffer and client ID. + * (Use when a DTLS client reconnects from the same port.) */ -int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) +static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) { int ret; @@ -5278,7 +5287,8 @@ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) ssl->in_msg = ssl->in_buf + 13; ssl->in_msgtype = 0; ssl->in_msglen = 0; - ssl->in_left = 0; + if( partial == 0 ) + ssl->in_left = 0; #if defined(MBEDTLS_SSL_PROTO_DTLS) ssl->next_record_offset = 0; ssl->in_epoch = 0; @@ -5304,7 +5314,8 @@ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) ssl->transform_out = NULL; memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); - memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); + if( partial == 0 ) + memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_reset != NULL ) @@ -5337,9 +5348,12 @@ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) #endif #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - mbedtls_free( ssl->cli_id ); - ssl->cli_id = NULL; - ssl->cli_id_len = 0; + if( partial == 0 ) + { + mbedtls_free( ssl->cli_id ); + ssl->cli_id = NULL; + ssl->cli_id_len = 0; + } #endif if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) @@ -5348,6 +5362,15 @@ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) return( 0 ); } +/* + * Reset an initialized and used SSL context for re-use while retaining + * all application-set variables, function pointers and data. + */ +int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) +{ + return( ssl_session_reset_int( ssl, 0 ) ); +} + /* * SSL set accessors */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index f169291eb..7fc9fa05f 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1838,6 +1838,12 @@ reset: } #endif + if( ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) + { + mbedtls_printf( " ! Client initiated reconnection from same port\n" ); + goto handshake; + } + #ifdef MBEDTLS_ERROR_C if( ret != 0 ) { @@ -1903,6 +1909,7 @@ reset: /* * 4. Handshake */ +handshake: mbedtls_printf( " . Performing the SSL/TLS handshake..." ); fflush( stdout ); From d745a1a9b761cc12b00700b2bac7620616b2f202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 12:40:43 +0200 Subject: [PATCH 08/73] Add tests for hard reconnect --- tests/ssl-opt.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 77db588db..ba6e578c1 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2867,6 +2867,28 @@ run_test "DTLS cookie: enabled, nbio" \ -s "hello verification requested" \ -S "SSL - The requested feature is not available" +# Tests for client reconnecting from the same port with DTLS + +run_test "DTLS client reconnect from same port: reference" \ + "$P_SRV dtls=1 exchanges=2" \ + "$P_CLI dtls=1 exchanges=2 debug_level=2" \ + 0 \ + -C "resend" \ + -S "Client initiated reconnection from same port" + +run_test "DTLS client reconnect from same port: reconnect" \ + "$P_SRV dtls=1 exchanges=2" \ + "$P_CLI dtls=1 exchanges=2 debug_level=2 reconnect_hard=1" \ + 0 \ + -C "resend" \ + -s "Client initiated reconnection from same port" + +run_test "DTLS client reconnect from same port: reconnect, nbio" \ + "$P_SRV dtls=1 exchanges=2 nbio=2" \ + "$P_CLI dtls=1 exchanges=2 debug_level=2 reconnect_hard=1" \ + 0 \ + -s "Client initiated reconnection from same port" + # Tests for various cases of client authentication with DTLS # (focused on handshake flows and message parsing) From 5f50104c52eafccacdd45fa4548b376a00350b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 3 Sep 2015 20:03:15 +0200 Subject: [PATCH 09/73] Add counter-measure against RSA-CRT attack https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/ --- ChangeLog | 5 +++++ library/rsa.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3636f00a..8be2cdde8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,11 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.1.0 released 2015-09-04 +Security + * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 + signatures. (Found by Florian Weimer, Red Hat.) + https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/ + Features * Added support for yotta as a build system. * Primary open source license changed to Apache 2.0 license. diff --git a/library/rsa.c b/library/rsa.c index f4ab6b2a6..3883d0921 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -51,6 +51,8 @@ #else #include #define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free #endif /* @@ -1005,6 +1007,11 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, size_t nb_pad, olen, oid_size = 0; unsigned char *p = sig; const char *oid = NULL; + unsigned char *sig_try = NULL, *verif = NULL; + size_t i; + unsigned char diff; + volatile unsigned char diff_no_optimize; + int ret; if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -1067,9 +1074,39 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, memcpy( p, hash, hashlen ); } - return( ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, sig, sig ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) ); + if( mode == MBEDTLS_RSA_PUBLIC ) + return( mbedtls_rsa_public( ctx, sig, sig ) ); + + /* + * In order to prevent Lenstra's attack, make the signature in a + * temporary buffer and check it before returning it. + */ + sig_try = mbedtls_calloc( 1, ctx->len ); + verif = mbedtls_calloc( 1, ctx->len ); + if( sig_try == NULL || verif == NULL ) + return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); + + MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) ); + MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) ); + + /* Compare in constant time just in case */ + for( diff = 0, i = 0; i < ctx->len; i++ ) + diff |= verif[i] ^ sig[i]; + diff_no_optimize = diff; + + if( diff_no_optimize != 0 ) + { + ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED; + goto cleanup; + } + + memcpy( sig, sig_try, ctx->len ); + +cleanup: + mbedtls_free( sig_try ); + mbedtls_free( verif ); + + return( ret ); } #endif /* MBEDTLS_PKCS1_V15 */ From 14c2574a9da15dbdc8add4824528e967169b5d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 15:12:45 +0200 Subject: [PATCH 10/73] Update Changelog --- ChangeLog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index d3636f00a..b4b1f61a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.1.1 released 2015-09-?? + +Changes + * When a client initiates a reconnect from the same port as a live + connection, if cookie verification is available + (MBEDTLS_SSL_DTLS_HELLO_VERIFY defined in config.h, and usable cookie + callbacks set with mbedtls_ssl_conf_dtls_cookies()), this will be + detected and mbedtls_ssl_read() will return + MBEDTLS_ERR_SSL_CLIENT_RECONNECT - it is then possible to start a new + handshake with the same context. (See RFC 6347 section 4.2.8.) + = mbed TLS 2.1.0 released 2015-09-04 Features From 3a2a4485d486462331a2528a5774781db9f866c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 15:36:09 +0200 Subject: [PATCH 11/73] Update documentation --- include/mbedtls/ssl.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8ff453929..c04070d87 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1170,6 +1170,11 @@ typedef int mbedtls_ssl_cookie_check_t( void *ctx, * the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected * on the first handshake attempt when this is enabled. * + * \note This is also necessary to handle client reconnection from + * the same port as described in RFC 6347 section 4.2.8 (only + * the variant with cookies is supported currently). See + * comments on \c mbedtls_ssl_read() for details. + * * \param conf SSL configuration * \param f_cookie_write Cookie write callback * \param f_cookie_check Cookie check callback @@ -2139,7 +2144,23 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); * * \return the number of bytes read, or * 0 for EOF, or - * a negative error code. + * MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT (see below), or + * another negative error code. + * + * \note When this function return MBEDTLS_ERR_SSL_CLIENT_RECONNECT + * (which can only happen server-side), it means that a client + * is initiating a new connection using the same source port. + * You can either treat that as a connection close and wait + * for the client to resend a ClientHello, or directly + * continue with \c mbedtls_ssl_handshake() with the same + * context (as it has beeen reset internally). Either way, you + * should make sure this is seen by the application as a new + * connection: application state, if any, should be reset, and + * most importantly the identity of the client must be checked + * again. WARNING: not validating the identity of the client + * again, or not transmitting the new identity to the + * application layer, would allow authentication bypass! */ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ); From 222cb8db2251ae3463f5159eb55ca378bfc85307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 15:43:59 +0200 Subject: [PATCH 12/73] Tune related documentation while at it --- include/mbedtls/ssl.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index c04070d87..7110e1ccf 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2095,29 +2095,35 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session * * \param ssl SSL context * - * \return 0 if successful, MBEDTLS_ERR_SSL_WANT_READ, - * MBEDTLS_ERR_SSL_WANT_WRITE, or a specific SSL error code. + * \return 0 if successful, or + * MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or + * MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED (see belowe), or + * a specific SSL error code. * - * \note If this function returns non-zero, then the ssl context + * \note If this function returns something other than 0 or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context * becomes unusable, and you should either free it or call * \c mbedtls_ssl_session_reset() on it before re-using it. - * If DTLS is in use, then you may choose to handle + * + * \note If DTLS is in use, then you may choose to handle * MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging - * purposes, but you still need to reset/free the context. + * purposes, as it is an expected return value rather than an + * actual error, but you still need to reset/free the context. */ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); /** * \brief Perform a single step of the SSL handshake * - * Note: the state of the context (ssl->state) will be at + * \note The state of the context (ssl->state) will be at * the following state after execution of this function. * Do not call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. * * \param ssl SSL context * - * \return 0 if successful, MBEDTLS_ERR_SSL_WANT_READ, - * MBEDTLS_ERR_SSL_WANT_WRITE, or a specific SSL error code. + * \return 0 if successful, or + * MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or + * a specific SSL error code. */ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); From 2088e2ebd9bef9eac9b7b5909234f9d498b8c8c3 Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Tue, 8 Sep 2015 16:53:18 +0100 Subject: [PATCH 13/73] fix const-ness of argument to mbedtls_ssl_conf_cert_profile Otherwise, it's impossible to pass in a pointer to mbedtls_x509_crt_profile_next! --- include/mbedtls/ssl.h | 2 +- library/ssl_tls.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index bd88918ca..907bba181 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1381,7 +1381,7 @@ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, * \param profile Profile to use */ void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, - mbedtls_x509_crt_profile *profile ); + const mbedtls_x509_crt_profile *profile ); /** * \brief Set the data required to verify peer certificate diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 14ee521ca..f1d2dd201 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5372,7 +5372,7 @@ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, #if defined(MBEDTLS_X509_CRT_PARSE_C) void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, - mbedtls_x509_crt_profile *profile ) + const mbedtls_x509_crt_profile *profile ) { conf->cert_profile = profile; } From 62c74bb78a5840e6db4dddd24a5854ff59928bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Sep 2015 17:50:29 +0200 Subject: [PATCH 14/73] Stop wasting resources Use a custom function that minimally parses the message an creates a reply without the overhead of a full SSL context. Also fix dependencies: needs DTLS_HELLO_VERIFY for the cookie types, and let's also depend on SRV_C as is doesn't make sense on client. --- include/mbedtls/check_config.h | 5 + include/mbedtls/config.h | 3 + library/ssl_tls.c | 246 +++++++++++++++++++++------------ 3 files changed, 169 insertions(+), 85 deletions(-) diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index cb707e9bc..2280caba7 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -421,6 +421,11 @@ #error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ + ( !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) || !defined(MBEDTLS_SSL_SRV_C) ) +#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) #error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 4956d0476..381e82b11 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1144,6 +1144,9 @@ * new connection securely, as described in section 4.1.8 of RFC 6347. This * flag enables that support. * + * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY + * MBEDTLS_SSL_SRV_C + * * Comment this to disable support for clients reusing the source port. */ #define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4addeb7d9..02cfaf1b9 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3250,21 +3250,136 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ - defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ - defined(MBEDTLS_SSL_SRV_C) -/* Dummy timer callbacks (temporary) */ -static void ssl_dummy_set_timer(void *ctx, uint32_t int_ms, uint32_t fin_ms) { - (void) ctx; (void) int_ms; (void) fin_ms; } -static int ssl_dummy_get_timer(void *ctx) { (void) ctx; return( 0 ); } - -/* Dummy recv callback (temporary) */ -static int ssl_dummy_recv(void *ctx, unsigned char *buf, size_t len) { - (void) ctx; (void) buf; (void) len; return( 0 ); } - -/* Forward declatation */ +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) +/* Forward declaration */ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); +/* + * Without any SSL context, check if a datagram looks like a ClientHello with + * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message. + * Both input and input include full DTLS headers. + * + * - if cookie is valid, return 0 + * - if ClientHello looks superficially valid but cookie is not, + * fill obuf and set olen, then + * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED + * - otherwise return a specific error code + */ +static int ssl_check_dtls_clihlo_cookie( + mbedtls_ssl_cookie_write_t *f_cookie_write, + mbedtls_ssl_cookie_check_t *f_cookie_check, + void *p_cookie, + const unsigned char *cli_id, size_t cli_id_len, + const unsigned char *in, size_t in_len, + unsigned char *obuf, size_t buf_len, size_t *olen ) +{ + size_t sid_len, cookie_len; + unsigned char *p; + + if( f_cookie_write == NULL || f_cookie_check == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + /* + * Structure of ClientHello with record and handshake headers, + * and expected values. We don't need to check a lot, more checks will be + * done when actually parsing the ClientHello - skipping those checks + * avoids code duplication and does not make cookie forging any easier. + * + * 0-0 ContentType type; copied, must be handshake + * 1-2 ProtocolVersion version; copied + * 3-4 uint16 epoch; copied, must be 0 + * 5-10 uint48 sequence_number; copied + * 11-12 uint16 length; (ignored) + * + * 13-13 HandshakeType msg_type; (ignored) + * 14-16 uint24 length; (ignored) + * 17-18 uint16 message_seq; copied + * 19-21 uint24 fragment_offset; copied, must be 0 + * 22-24 uint24 fragment_length; (ignored) + * + * 25-26 ProtocolVersion client_version; (ignored) + * 27-58 Random random; (ignored) + * 59-xx SessionID session_id; 1 byte len + sid_len content + * 60+ opaque cookie<0..2^8-1>; 1 byte len + content + * ... + * + * Minimum length is 61 bytes. + */ + if( in_len < 61 || + in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || + in[3] != 0 || in[4] != 0 || + in[19] != 0 || in[20] != 0 || in[21] != 0 ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + sid_len = in[59]; + if( sid_len > in_len - 61 ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + cookie_len = in[60 + sid_len]; + if( cookie_len > in_len - 60 ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len, + cli_id, cli_id_len ) == 0 ) + { + /* Valid cookie */ + return( 0 ); + } + + /* + * If we get here, we've got an invalid cookie, let's prepare HVR. + * + * 0-0 ContentType type; copied + * 1-2 ProtocolVersion version; copied + * 3-4 uint16 epoch; copied + * 5-10 uint48 sequence_number; copied + * 11-12 uint16 length; olen - 13 + * + * 13-13 HandshakeType msg_type; hello_verify_request + * 14-16 uint24 length; olen - 25 + * 17-18 uint16 message_seq; copied + * 19-21 uint24 fragment_offset; copied + * 22-24 uint24 fragment_length; olen - 25 + * + * 25-26 ProtocolVersion server_version; 0xfe 0xff + * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie + * + * Minimum length is 28. + */ + if( buf_len < 28 ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + /* Copy most fields and adapt others */ + memcpy( obuf, in, 25 ); + obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; + obuf[25] = 0xfe; + obuf[26] = 0xff; + + /* Generate and write actual cookie */ + p = obuf + 28; + if( f_cookie_write( p_cookie, + &p, obuf + buf_len, cli_id, cli_id_len ) != 0 ) + { + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + *olen = p - obuf; + + /* Go back and fill length fields */ + obuf[27] = (unsigned char)( *olen - 28 ); + + obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 ); + obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 ); + obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) ); + + obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 ); + obuf[12] = (unsigned char)( ( *olen - 13 ) ); + + return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); +} + /* * Handle possible client reconnect with the same UDP quadruplet * (RFC 6347 Section 4.2.8). @@ -3272,95 +3387,57 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); * Called by ssl_parse_record_header() in case we receive an epoch 0 record * that looks like a ClientHello. * - * - if the input looks wrong, - * return MBEDTLS_ERR_SSL_INVALID_RECORD (ignore this record) * - if the input looks like a ClientHello without cookies, * send back HelloVerifyRequest, then - * return MBEDTLS_ERR_SSL_INVALID_RECORD (ignore this record) + * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED * - if the input looks like a ClientHello with a valid cookie, * reset the session of the current context, and * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT + * - if anything goes wrong, return a specific error code * - * Currently adopts a heavyweight strategy by allocating a secondary ssl - * context. Will be refactored into something more acceptable later. + * mbedtls_ssl_read_record() will ignore the record if anything else than + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned (we never return 0). */ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) { int ret; - mbedtls_ssl_context tmp_ssl; - int cookie_is_good; + size_t len; - mbedtls_ssl_init( &tmp_ssl ); + ret = ssl_check_dtls_clihlo_cookie( + ssl->conf->f_cookie_write, + ssl->conf->f_cookie_check, + ssl->conf->p_cookie, + ssl->cli_id, ssl->cli_id_len, + ssl->in_buf, ssl->in_left, + ssl->out_buf, MBEDTLS_SSL_MAX_CONTENT_LEN, &len ); - /* Prepare temporary ssl context */ - ret = mbedtls_ssl_setup( &tmp_ssl, ssl->conf ); - if( ret != 0 ) + MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); + + if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) { - MBEDTLS_SSL_DEBUG_RET( 1, "nested ssl_setup", ret ); - goto cleanup; + /* Dont 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 ); + + return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); } - mbedtls_ssl_set_timer_cb( &tmp_ssl, NULL, ssl_dummy_set_timer, - ssl_dummy_get_timer ); - - ret = mbedtls_ssl_set_client_transport_id( &tmp_ssl, - ssl->cli_id, ssl->cli_id_len ); - if( ret != 0 ) + if( ret == 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "nested set_client_id", ret ); - goto cleanup; + /* Got a valid cookie, partially reset context */ + if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); + return( ret ); + } + + return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT ); } - mbedtls_ssl_set_bio( &tmp_ssl, ssl->p_bio, ssl->f_send, - ssl_dummy_recv, NULL ); - - memcpy( tmp_ssl.in_buf, ssl->in_buf, ssl->in_left ); - tmp_ssl.in_left = ssl->in_left; - - tmp_ssl.state = MBEDTLS_SSL_CLIENT_HELLO; - - /* Parse packet and check if cookie is good */ - ret = mbedtls_ssl_handshake_step( &tmp_ssl ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "nested handshake_step", ret ); - goto cleanup; - } - - cookie_is_good = tmp_ssl.handshake->verify_cookie_len == 0; - MBEDTLS_SSL_DEBUG_MSG( 1, ( "good ClientHello with %s cookie", - cookie_is_good ? "good" : "bad" ) ); - - /* Send HelloVerifyRequest? */ - if( !cookie_is_good ) - { - ret = mbedtls_ssl_handshake_step( &tmp_ssl ); - if( ret != 0 ) - MBEDTLS_SSL_DEBUG_RET( 1, "nested handshake_step", ret ); - goto cleanup; - } - - /* Reset context while preserving some information */ - ret = ssl_session_reset_int( ssl, 1 ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); - goto cleanup; - } - - ret = MBEDTLS_ERR_SSL_CLIENT_RECONNECT; - -cleanup: - mbedtls_ssl_free( &tmp_ssl ); - - if( ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) - ret = MBEDTLS_ERR_SSL_INVALID_RECORD; - return( ret ); } -#endif /* MBEDTLS_SSL_PROTO_DTLS && - MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && - MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ /* * ContentType type; @@ -3456,8 +3533,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) "expected %d, received %d", ssl->in_epoch, rec_epoch ) ); -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ - defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) /* * Check for an epoch 0 ClientHello. We can't use in_msg here to * access the first byte of record content (handshake type), as we @@ -3475,7 +3551,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) return( ssl_handle_possible_reconnect( ssl ) ); } else -#endif /* MBEDTLS_SSL_DLTS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_DLTS_CLIENT_PORT_REUSE */ return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } From 22311ae62e591bc49e69a6a85cc794da2d8c704e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 Sep 2015 11:22:58 +0200 Subject: [PATCH 15/73] Improve help message of ssl_*2.c --- programs/ssl/ssl_client2.c | 2 +- programs/ssl/ssl_server2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 758ebf34a..c090db909 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -223,7 +223,7 @@ int main( void ) " debug_level=%%d default: 0 (disabled)\n" \ " nbio=%%d default: 0 (blocking I/O)\n" \ " options: 1 (non-blocking), 2 (added delays)\n" \ - " read_timeout=%%d default: 0 (no timeout)\n" \ + " read_timeout=%%d default: 0 ms (no timeout)\n" \ " max_resend=%%d default: 0 (no resend on timeout)\n" \ "\n" \ USAGE_DTLS \ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 7fc9fa05f..bd4d1d1b4 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -301,7 +301,7 @@ int main( void ) " debug_level=%%d default: 0 (disabled)\n" \ " nbio=%%d default: 0 (blocking I/O)\n" \ " options: 1 (non-blocking), 2 (added delays)\n" \ - " read_timeout=%%d default: 0 (no timeout)\n" \ + " read_timeout=%%d default: 0 ms (no timeout)\n" \ "\n" \ USAGE_DTLS \ USAGE_COOKIES \ From 259db910238b67623305047bb491b5fc98d67829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 Sep 2015 11:37:17 +0200 Subject: [PATCH 16/73] Add test without cookies Tune existing tests while at it --- tests/ssl-opt.sh | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index ba6e578c1..6387af573 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2869,26 +2869,38 @@ run_test "DTLS cookie: enabled, nbio" \ # Tests for client reconnecting from the same port with DTLS +not_with_valgrind # spurious resend run_test "DTLS client reconnect from same port: reference" \ - "$P_SRV dtls=1 exchanges=2" \ - "$P_CLI dtls=1 exchanges=2 debug_level=2" \ + "$P_SRV dtls=1 exchanges=2 read_timeout=1000" \ + "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000" \ 0 \ -C "resend" \ + -S "The operation timed out" \ -S "Client initiated reconnection from same port" +not_with_valgrind # spurious resend run_test "DTLS client reconnect from same port: reconnect" \ - "$P_SRV dtls=1 exchanges=2" \ - "$P_CLI dtls=1 exchanges=2 debug_level=2 reconnect_hard=1" \ + "$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" \ 0 \ -C "resend" \ + -S "The operation timed out" \ -s "Client initiated reconnection from same port" run_test "DTLS client reconnect from same port: reconnect, nbio" \ - "$P_SRV dtls=1 exchanges=2 nbio=2" \ - "$P_CLI dtls=1 exchanges=2 debug_level=2 reconnect_hard=1" \ + "$P_SRV dtls=1 exchanges=2 read_timeout=1000 nbio=2" \ + "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000 reconnect_hard=1" \ 0 \ + -S "The operation timed out" \ -s "Client initiated reconnection from same port" +run_test "DTLS client reconnect from same port: no cookies" \ + "$P_SRV dtls=1 exchanges=2 read_timeout=1000 cookies=0" \ + "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000 reconnect_hard=1" \ + 1 \ + -s "The operation timed out" \ + -S "Client initiated reconnection from same port" + # Tests for various cases of client authentication with DTLS # (focused on handshake flows and message parsing) From ab05d23b29239d3af908505083f7ab684b8a6d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 Sep 2015 11:50:00 +0200 Subject: [PATCH 17/73] Update generated file --- library/version_features.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/version_features.c b/library/version_features.c index c2f30f21c..196b93c88 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -369,6 +369,9 @@ static const char *features[] = { #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) "MBEDTLS_SSL_DTLS_HELLO_VERIFY", #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) + "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) "MBEDTLS_SSL_DTLS_BADMAC_LIMIT", #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ From 2ed05a049ab0b565f5460148c0f7f01f89aed5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 Sep 2015 11:52:28 +0200 Subject: [PATCH 18/73] Fix typos --- library/ssl_tls.c | 2 +- programs/pkey/pk_sign.c | 2 +- programs/pkey/rsa_sign.c | 2 +- programs/pkey/rsa_verify.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 02cfaf1b9..b631e2609 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3551,7 +3551,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) return( ssl_handle_possible_reconnect( ssl ) ); } else -#endif /* MBEDTLS_SSL_DLTS_CLIENT_PORT_REUSE */ +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c index 606fc93d7..322e8aff0 100644 --- a/programs/pkey/pk_sign.c +++ b/programs/pkey/pk_sign.c @@ -40,7 +40,7 @@ int main( void ) { mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or " - "MBEDTLS_SHA256_C and/or MBEDLTS_MD_C and/or " + "MBEDTLS_SHA256_C and/or MBEDTLS_MD_C and/or " "MBEDTLS_PK_PARSE_C and/or MBEDTLS_FS_IO and/or " "MBEDTLS_CTR_DRBG_C not defined.\n"); return( 0 ); diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c index 469ad9f5d..e897c6519 100644 --- a/programs/pkey/rsa_sign.c +++ b/programs/pkey/rsa_sign.c @@ -40,7 +40,7 @@ int main( void ) { mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_RSA_C and/or " - "MBEDLTS_MD_C and/or " + "MBEDTLS_MD_C and/or " "MBEDTLS_SHA256_C and/or MBEDTLS_FS_IO not defined.\n"); return( 0 ); } diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c index 9d48a18ee..ade36dc83 100644 --- a/programs/pkey/rsa_verify.c +++ b/programs/pkey/rsa_verify.c @@ -39,7 +39,7 @@ int main( void ) { mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_RSA_C and/or " - "MBEDLTS_MD_C and/or " + "MBEDTLS_MD_C and/or " "MBEDTLS_SHA256_C and/or MBEDTLS_FS_IO not defined.\n"); return( 0 ); } From c2ed8029ff8cec7907f31eac02921edde07cb698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 Sep 2015 12:15:13 +0200 Subject: [PATCH 19/73] Fix ChangeLog - misplaced entries --- ChangeLog | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b1973256..03ae5b947 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,21 +1,21 @@ mbed TLS ChangeLog (Sorted per branch, date) -= mbed TLS 2.1.0 released 2015-09-04 += mbed TLS 2.1.1 released 2015-09-?? Security * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 signatures. (Found by Florian Weimer, Red Hat.) https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/ + * Fix possible client-side NULL pointer dereference (read) when the client + tries to continue the handshake after it failed (a misuse of the API). + (Found by GDS Labs using afl-fuzz, patch provided by GDS Labs.) + += mbed TLS 2.1.0 released 2015-09-04 Features * Added support for yotta as a build system. * Primary open source license changed to Apache 2.0 license. -Security - * Fix possible client-side NULL pointer dereference (read) when the client - tries to continue the handshake after it failed (a misuse of the API). - (Found by GDS Labs using afl-fuzz, patch provided by GDS Labs.) - Bugfix * Fix segfault in the benchmark program when benchmarking DHM. * Fix build error with CMake and pre-4.5 versions of GCC (found by Hugo From ddfe5d20d1290d98cb00df7838d997c0e2e67086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 Sep 2015 12:46:16 +0200 Subject: [PATCH 20/73] Tune dependencies Don't depend on srv.c in config.h, but add explicit checks. This is more in line with other options that only make sense server-side, and also it allows to test full config minus srv.c more easily. --- include/mbedtls/check_config.h | 2 +- include/mbedtls/config.h | 1 - library/ssl_tls.c | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 2280caba7..8dadbe1c5 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -422,7 +422,7 @@ #endif #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ - ( !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) || !defined(MBEDTLS_SSL_SRV_C) ) + !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) #error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" #endif diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 381e82b11..9fdac600f 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1145,7 +1145,6 @@ * flag enables that support. * * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY - * MBEDTLS_SSL_SRV_C * * Comment this to disable support for clients reusing the source port. */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index b631e2609..66745d5af 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3250,7 +3250,7 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) /* Forward declaration */ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); @@ -3437,7 +3437,7 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) return( ret ); } -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ /* * ContentType type; @@ -3533,7 +3533,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) "expected %d, received %d", ssl->in_epoch, rec_epoch ) ); -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) /* * Check for an epoch 0 ClientHello. We can't use in_msg here to * access the first byte of record content (handshake type), as we @@ -3551,7 +3551,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) return( ssl_handle_possible_reconnect( ssl ) ); } else -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } From a6b95f01cc8feb9d9099c4de4ade00cedf2c9ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 Sep 2015 13:47:28 +0200 Subject: [PATCH 21/73] Print I/O buffer size in memory.sh --- scripts/memory.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/memory.sh b/scripts/memory.sh index 0738e7de2..3dad2899c 100755 --- a/scripts/memory.sh +++ b/scripts/memory.sh @@ -52,6 +52,8 @@ do_config() scripts/config.pl unset $FLAG done + grep -F SSL_MAX_CONTENT_LEN $CONFIG_H || echo 'SSL_MAX_CONTENT_LEN=16384' + printf " Executable size... " make clean From a25cab8beaab65ebe434b637ea29f34e6b672c4c Mon Sep 17 00:00:00 2001 From: Embedthis Software Date: Wed, 9 Sep 2015 08:49:48 -0700 Subject: [PATCH 22/73] FIX: compiler warning with recvfrom on 64-bit --- library/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/net.c b/library/net.c index b892df91b..b5d06888b 100644 --- a/library/net.c +++ b/library/net.c @@ -319,7 +319,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, /* UDP: wait for a message, but keep it in the queue */ char buf[1] = { 0 }; - ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, + ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, (struct sockaddr *) &client_addr, &n ); #if defined(_WIN32) From 4f6882a8a3d6871ef5027c260e91e1a22e5e598c Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Fri, 11 Sep 2015 17:12:46 +0100 Subject: [PATCH 23/73] Update config.h Typo in RFC x-ref comment. --- include/mbedtls/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 9fdac600f..6e9d8f3df 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1141,7 +1141,7 @@ * * Some clients unexpectedly close the connection and try to reconnect using the * same source port. This needs special support from the server to handle the - * new connection securely, as described in section 4.1.8 of RFC 6347. This + * new connection securely, as described in section 4.2.8 of RFC 6347. This * flag enables that support. * * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY From 1a57af16072d20f566d702c68824fe81af213fa8 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Fri, 11 Sep 2015 17:14:16 +0100 Subject: [PATCH 24/73] Update ssl.h Typo --- include/mbedtls/ssl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 7110e1ccf..512c76717 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2097,7 +2097,7 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session * * \return 0 if successful, or * MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or - * MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED (see belowe), or + * MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED (see below), or * a specific SSL error code. * * \note If this function returns something other than 0 or From 0789aed39d545394e61e9edb0178cf46d08ded00 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Fri, 11 Sep 2015 17:15:17 +0100 Subject: [PATCH 25/73] Update ssl_tls.c Typo --- library/ssl_tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 66745d5af..fa1530be6 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3257,7 +3257,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); /* * Without any SSL context, check if a datagram looks like a ClientHello with * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message. - * Both input and input include full DTLS headers. + * Both input and output include full DTLS headers. * * - if cookie is valid, return 0 * - if ClientHello looks superficially valid but cookie is not, From 74ca8d07ada9514cec876365b35e0328da1357c7 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Fri, 11 Sep 2015 17:22:40 +0100 Subject: [PATCH 26/73] Update ssl_tls.c Clarification in comments to ssl_handle_possible_reconnect() --- library/ssl_tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fa1530be6..0e7bd4d20 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3396,7 +3396,7 @@ static int ssl_check_dtls_clihlo_cookie( * - if anything goes wrong, return a specific error code * * mbedtls_ssl_read_record() will ignore the record if anything else than - * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned (we never return 0). + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned. */ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) { From d0bf6a38913b2f4762ea1ec75472dba4b4d6d596 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Fri, 11 Sep 2015 17:34:49 +0100 Subject: [PATCH 27/73] Update ssl_tls.c Clarification in comments --- library/ssl_tls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 0e7bd4d20..2abd18b05 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3396,7 +3396,8 @@ static int ssl_check_dtls_clihlo_cookie( * - if anything goes wrong, return a specific error code * * mbedtls_ssl_read_record() will ignore the record if anything else than - * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned. + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function + * cannot not return 0. */ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) { From 8a52a7468df34c49e4e75ffd525e9c7c514a247d Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Fri, 11 Sep 2015 19:44:34 +0100 Subject: [PATCH 28/73] Added PR to Changelog for NWilson --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index d3636f00a..4eb289101 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,6 +50,8 @@ Changes Hugo Leisink) (#210). * Add mbedtls_ssl_get_max_frag_len() to query the current maximum fragment length. + * Made X509 profile pointer const in mbedtls_ssl_conf_cert_profile() to allow + use of mbedtls_x509_crt_profile_next. (found by NWilson) = mbed TLS 2.0.0 released 2015-07-13 From d69f14bed817b222d5607a36cf8da4c282fe726e Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Fri, 11 Sep 2015 20:00:20 +0100 Subject: [PATCH 29/73] Updated Changelog for new version --- ChangeLog | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4eb289101..17f0e80a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.1.1 released 2015-09-?? + +Changes + * Made X509 profile pointer const in mbedtls_ssl_conf_cert_profile() to allow + use of mbedtls_x509_crt_profile_next. (found by NWilson) + = mbed TLS 2.1.0 released 2015-09-04 Features @@ -50,8 +56,6 @@ Changes Hugo Leisink) (#210). * Add mbedtls_ssl_get_max_frag_len() to query the current maximum fragment length. - * Made X509 profile pointer const in mbedtls_ssl_conf_cert_profile() to allow - use of mbedtls_x509_crt_profile_next. (found by NWilson) = mbed TLS 2.0.0 released 2015-07-13 From c57556e52aa0c0028f98528bd7139ca0c56092eb Mon Sep 17 00:00:00 2001 From: Jeremie Miller Date: Sat, 12 Sep 2015 09:57:23 -0600 Subject: [PATCH 30/73] tiny spelling fixes --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 79943d10a..bcc0a32c0 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx ### Yotta -[yotta](http://yottabuild.org) is a package manager and build system developped by mbed; it is the build system of mbed OS. To install it on your platform, please follow the yotta [installation instructions](http://docs.yottabuild.org/#installing). +[yotta](http://yottabuild.org) is a package manager and build system developed by mbed; it is the build system of mbed OS. To install it on your platform, please follow the yotta [installation instructions](http://docs.yottabuild.org/#installing). Once yotta is installed, you can use it to download the latest version of mbed TLS form the yotta registry with: @@ -64,7 +64,7 @@ In order to run the tests, enter: make check -The tests need Perl to be built and run. If you don't have Perl installed, you can skip buiding the tests with: +The tests need Perl to be built and run. If you don't have Perl installed, you can skip building the tests with: make no_test @@ -122,7 +122,7 @@ To list other available CMake options, use: cmake -LH -Note that, with CMake, if you want to change the compiler or its options after you already ran CMake, you need to clear its cache first, eg (using GNU find): +Note that, with CMake, if you want to change the compiler or its options after you already ran CMake, you need to clear its cache first, e.g. (using GNU find): find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} + CC=gcc CFLAGS='-fstack-protector-strong -Wa,--noexecstack' cmake . From a1a1128f7d916d3574c92e03a54cdb8f8103f2ef Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Mon, 14 Sep 2015 21:30:40 +0100 Subject: [PATCH 31/73] Updated ChangeLog for fix #275 --- ChangeLog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 17f0e80a9..37c79f6ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.1.1 released 2015-09-?? +Bugfix + * Fix warning when using a 64bit platform. (found by embedthis) (#275) + Changes * Made X509 profile pointer const in mbedtls_ssl_conf_cert_profile() to allow use of mbedtls_x509_crt_profile_next. (found by NWilson) From 6ad23b98552ebf1f123fe52172a65700aac1610a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 15 Sep 2015 12:57:46 +0200 Subject: [PATCH 32/73] Make failing test more robust Let the client retry longer, to make sure the server will time out before the client gives up. Make it really longer to get a deterministic client exit status (make sure it has time to reconnect after the server timeout). --- tests/ssl-opt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 6387af573..e49441301 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2896,8 +2896,8 @@ run_test "DTLS client reconnect from same port: reconnect, nbio" \ run_test "DTLS client reconnect from same port: no cookies" \ "$P_SRV dtls=1 exchanges=2 read_timeout=1000 cookies=0" \ - "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000 reconnect_hard=1" \ - 1 \ + "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-8000 reconnect_hard=1" \ + 0 \ -s "The operation timed out" \ -S "Client initiated reconnection from same port" From ea5370d4a2df4956b32f66007c820e4578328094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 15 Sep 2015 15:11:28 +0200 Subject: [PATCH 33/73] Don't allow reconnect during handshake Especially for resumed handshake, it's entirely possible for an epoch=0 ClientHello to be retransmitted or arrive so late that the server is already at epoch=1. There is no good way to detect whether it's that or a reconnect. However: - a late ClientHello seems more likely that client going down and then up again in the middle of a handshake - even if that's the case, we'll time out on that handshake soon enough - we don't want to break handshake flows that used to work So the safest option is to not treat that as a reconnect. --- library/ssl_tls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 2abd18b05..463a6b115 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3542,6 +3542,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) * fact that the record header len is 13 instead. */ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && rec_epoch == 0 && ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && ssl->in_left > 13 && From 5e4c206b7751737e1169f7eec1563874cedd3f63 Mon Sep 17 00:00:00 2001 From: Pascal Bach Date: Tue, 15 Sep 2015 21:38:12 +0200 Subject: [PATCH 34/73] Make config check include for configs examples more consistent This way all config examples work when used like described in the README. --- configs/config-ccm-psk-tls1_2.h | 2 +- configs/config-picocoin.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/config-ccm-psk-tls1_2.h b/configs/config-ccm-psk-tls1_2.h index bd370919c..aee10b86f 100644 --- a/configs/config-ccm-psk-tls1_2.h +++ b/configs/config-ccm-psk-tls1_2.h @@ -80,6 +80,6 @@ */ #define MBEDTLS_SSL_MAX_CONTENT_LEN 512 -#include "check_config.h" +#include "mbedtls/check_config.h" #endif /* MBEDTLS_CONFIG_H */ diff --git a/configs/config-picocoin.h b/configs/config-picocoin.h index 426987224..26b24a9e2 100644 --- a/configs/config-picocoin.h +++ b/configs/config-picocoin.h @@ -66,6 +66,6 @@ #define MBEDTLS_SHA1_C #define MBEDTLS_SHA256_C -#include "check_config.h" +#include "mbedtls/check_config.h" #endif /* MBEDTLS_CONFIG_H */ From f7022d1131243a4aa745261a436eebab81c0757d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 16 Sep 2015 11:32:18 +0200 Subject: [PATCH 35/73] Fix bug in server parsing point formats extension There is only one length byte but for some reason we skipped two, resulting in reading one byte past the end of the extension. Fortunately, even if that extension is at the very end of the ClientHello, it can't be at the end of the buffer since the ClientHello length is at most SSL_MAX_CONTENT_LEN and the buffer has some more room after that for MAC and so on. So there is no buffer overread. Possible consequences are: - nothing, if the next byte is 0x00, which is a comment first byte for other extensions, which is why the bug remained unnoticed - using a point format that was not offered by the peer if next byte is 0x01. In that case the peer will reject our ServerKeyExchange message and the handshake will fail. - thinking that we don't have a common point format even if we do, which will cause us to immediately abort the handshake. None of these are a security issue. The same bug was fixed client-side in fd35af15 --- ChangeLog | 4 +++- library/ssl_srv.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37c79f6ff..be3861416 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,9 @@ mbed TLS ChangeLog (Sorted per branch, date) Bugfix * Fix warning when using a 64bit platform. (found by embedthis) (#275) - + * Fix off-by-one error in parsing Supported Point Format extension that + caused some handshakes to fail. + Changes * Made X509 profile pointer const in mbedtls_ssl_conf_cert_profile() to allow use of mbedtls_x509_crt_profile_next. (found by NWilson) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index ca1e7b804..b48a609ee 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -299,7 +299,7 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - p = buf + 2; + p = buf + 1; while( list_size > 0 ) { if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || From 8cea8ad8b825b0bf5884054af7499f1d5c3ebeb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 17 Sep 2015 11:58:45 +0200 Subject: [PATCH 36/73] Bump version to 2.1.1 --- ChangeLog | 2 +- doxygen/input/doc_mainpage.h | 2 +- doxygen/mbedtls.doxyfile | 2 +- include/mbedtls/version.h | 8 ++++---- library/CMakeLists.txt | 6 +++--- tests/suites/test_suite_version.data | 4 ++-- yotta/data/module.json | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 584dd658e..95a2bfcab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ mbed TLS ChangeLog (Sorted per branch, date) -= mbed TLS 2.1.1 released 2015-09-16 += mbed TLS 2.1.1 released 2015-09-17 Security * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index ca7cd1d94..076f24dc9 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -21,7 +21,7 @@ */ /** - * @mainpage mbed TLS v2.1.0 source code documentation + * @mainpage mbed TLS v2.1.1 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 6ca97c106..e5cd908df 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8 # 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.1.0" +PROJECT_NAME = "mbed TLS v2.1.1" # 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 da76e76cb..d09726439 100644 --- a/include/mbedtls/version.h +++ b/include/mbedtls/version.h @@ -39,16 +39,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 1 -#define MBEDTLS_VERSION_PATCH 0 +#define MBEDTLS_VERSION_PATCH 1 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02010000 -#define MBEDTLS_VERSION_STRING "2.1.0" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.1.0" +#define MBEDTLS_VERSION_NUMBER 0x02010100 +#define MBEDTLS_VERSION_STRING "2.1.1" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.1.1" #if defined(MBEDTLS_VERSION_C) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index c458117d4..ea43ccbae 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -138,15 +138,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY) add_library(mbedcrypto SHARED ${src_crypto}) - set_target_properties(mbedcrypto PROPERTIES VERSION 2.1.0 SOVERSION 0) + set_target_properties(mbedcrypto PROPERTIES VERSION 2.1.1 SOVERSION 0) target_link_libraries(mbedcrypto ${libs}) add_library(mbedx509 SHARED ${src_x509}) - set_target_properties(mbedx509 PROPERTIES VERSION 2.1.0 SOVERSION 0) + set_target_properties(mbedx509 PROPERTIES VERSION 2.1.1 SOVERSION 0) target_link_libraries(mbedx509 ${libs} mbedcrypto) add_library(mbedtls SHARED ${src_tls}) - set_target_properties(mbedtls PROPERTIES VERSION 2.1.0 SOVERSION 10) + set_target_properties(mbedtls PROPERTIES VERSION 2.1.1 SOVERSION 10) target_link_libraries(mbedtls ${libs} mbedx509) install(TARGETS mbedtls mbedx509 mbedcrypto diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index 29ea2d22d..ef8a579ce 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.1.0" +check_compiletime_version:"2.1.1" Check runtime library version -check_runtime_version:"2.1.0" +check_runtime_version:"2.1.1" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0 diff --git a/yotta/data/module.json b/yotta/data/module.json index 5b57cc209..997cd10b9 100644 --- a/yotta/data/module.json +++ b/yotta/data/module.json @@ -1,6 +1,6 @@ { "name": "mbedtls", - "version": "2.1.0", + "version": "2.1.1", "description": "The mbed TLS crypto/SSL/TLS library", "licenses": [ { From ca4fb7154a0cae45387c99dc201e7710629286b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 18 Sep 2015 14:36:57 +0200 Subject: [PATCH 37/73] Fix mbed examples after minar upgrade --- yotta/data/example-authcrypt/main.cpp | 2 +- yotta/data/example-benchmark/main.cpp | 2 +- yotta/data/example-hashing/main.cpp | 2 +- yotta/data/example-selftest/main.cpp | 2 +- yotta/data/example-tls-client/main.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/yotta/data/example-authcrypt/main.cpp b/yotta/data/example-authcrypt/main.cpp index 2f49aa91c..257a1adf1 100644 --- a/yotta/data/example-authcrypt/main.cpp +++ b/yotta/data/example-authcrypt/main.cpp @@ -187,7 +187,7 @@ static void run() { } void app_start(int, char*[]) { - minar::Scheduler::postCallback(FunctionPointer0(run).bind()); + minar::Scheduler::postCallback(mbed::util::FunctionPointer0(run).bind()); } #else diff --git a/yotta/data/example-benchmark/main.cpp b/yotta/data/example-benchmark/main.cpp index 6ac2a29e8..1a6c7ae7a 100644 --- a/yotta/data/example-benchmark/main.cpp +++ b/yotta/data/example-benchmark/main.cpp @@ -947,7 +947,7 @@ static void run() { } void app_start(int, char*[]) { - minar::Scheduler::postCallback(FunctionPointer0(run).bind()); + minar::Scheduler::postCallback(mbed::util::FunctionPointer0(run).bind()); } #endif /* TARGET_LIKE_MBED */ diff --git a/yotta/data/example-hashing/main.cpp b/yotta/data/example-hashing/main.cpp index 4ef3665fe..7603cbee6 100644 --- a/yotta/data/example-hashing/main.cpp +++ b/yotta/data/example-hashing/main.cpp @@ -167,7 +167,7 @@ static void run() { } void app_start(int, char*[]) { - minar::Scheduler::postCallback(FunctionPointer0(run).bind()); + minar::Scheduler::postCallback(mbed::util::FunctionPointer0(run).bind()); } #else diff --git a/yotta/data/example-selftest/main.cpp b/yotta/data/example-selftest/main.cpp index 22fd4661f..046a54850 100644 --- a/yotta/data/example-selftest/main.cpp +++ b/yotta/data/example-selftest/main.cpp @@ -258,7 +258,7 @@ static void run() { } void app_start(int, char*[]) { - minar::Scheduler::postCallback(FunctionPointer0(run).bind()); + minar::Scheduler::postCallback(mbed::util::FunctionPointer0(run).bind()); } #else diff --git a/yotta/data/example-tls-client/main.cpp b/yotta/data/example-tls-client/main.cpp index 684f1c16e..907cfb6d4 100644 --- a/yotta/data/example-tls-client/main.cpp +++ b/yotta/data/example-tls-client/main.cpp @@ -513,7 +513,7 @@ void app_start(int, char*[]) { printf("Client IP Address is %s\r\n", eth.getIPAddress()); - mbed::FunctionPointer1 fp(hello, &HelloHTTPS::startTest); + mbed::util::FunctionPointer1 fp(hello, &HelloHTTPS::startTest); minar::Scheduler::postCallback(fp.bind(HTTPS_PATH)); } From 2f056a0aee83074527073f278c9f9498b20f8965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 18 Sep 2015 14:37:54 +0200 Subject: [PATCH 38/73] Try to run yotta update for yotta build test But accept failures in case we're offline --- tests/scripts/yotta-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/yotta-build.sh b/tests/scripts/yotta-build.sh index 59cedf42b..2648d3e29 100755 --- a/tests/scripts/yotta-build.sh +++ b/tests/scripts/yotta-build.sh @@ -6,7 +6,7 @@ set -eu yotta/create-module.sh cd yotta/module -# yt update # needs network +yt update || true # needs network yotta_build() { From 8f98842e38028986a99f29259d42403786a16f4f Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Tue, 22 Sep 2015 10:10:36 +0100 Subject: [PATCH 39/73] Refined credits in ChangeLog for fuzzing issue Changed GDS to Gotham Digital Science --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 95a2bfcab..c9e48e244 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,7 +8,7 @@ Security https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/ * Fix possible client-side NULL pointer dereference (read) when the client tries to continue the handshake after it failed (a misuse of the API). - (Found by GDS Labs using afl-fuzz, patch provided by GDS Labs.) + (Found and patch provided by Fabian Foerg, Gotham Digital Science using afl-fuzz.) Bugfix * Fix warning when using a 64bit platform. (found by embedthis) (#275) From f592e8eaf6f970489c57e02ac35c3f6721c51413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 22 Sep 2015 15:01:18 +0200 Subject: [PATCH 40/73] Update yotta dependency version We've had a bit of a race between us adapting to changes in 0.3.x and the sockets author reverting those changes in the 0.3.x line and pushing them to 0.4.0. Let's use the newest and greatest sockets :) --- yotta/data/module.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yotta/data/module.json b/yotta/data/module.json index 997cd10b9..9a9e8a164 100644 --- a/yotta/data/module.json +++ b/yotta/data/module.json @@ -1,6 +1,6 @@ { "name": "mbedtls", - "version": "2.1.1", + "version": "2.1.2", "description": "The mbed TLS crypto/SSL/TLS library", "licenses": [ { @@ -13,6 +13,6 @@ "mbed": { "cmsis-core": "~0.2.3" } }, "testTargetDependencies": { - "mbed": { "sockets": "~0.3.0" } + "mbed": { "sockets": "~0.4.0" } } } From 588ad50c5ab3eac08b978c9255958bca6bc5cb48 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Fri, 25 Sep 2015 04:27:22 +0200 Subject: [PATCH 41/73] Fix a fairly common typo in comments --- ChangeLog | 2 +- include/mbedtls/ctr_drbg.h | 2 +- include/mbedtls/hmac_drbg.h | 2 +- include/mbedtls/pkcs11.h | 2 +- include/mbedtls/ssl.h | 2 +- include/mbedtls/timing.h | 4 ++-- library/ssl_tls.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9e48e244..48e73d2ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -113,7 +113,7 @@ API Changes mbedtls_gcm_init() -> mbedtls_gcm_setkey() mbedtls_hmac_drbg_init() -> mbedtls_hmac_drbg_seed(_buf)() mbedtls_ctr_drbg_init() -> mbedtls_ctr_drbg_seed() - Note that for mbetls_ssl_setup(), you need to be done setting up the + Note that for mbedtls_ssl_setup(), you need to be done setting up the ssl_config structure before calling it. * Most ssl_set_xxx() functions (all except ssl_set_bio(), ssl_set_hostname(), ssl_set_session() and ssl_set_client_transport_id(), plus diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index a04933021..059d3c5c9 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -111,7 +111,7 @@ mbedtls_ctr_drbg_context; /** * \brief CTR_DRBG context initialization - * Makes the context ready for mbetls_ctr_drbg_seed() or + * Makes the context ready for mbedtls_ctr_drbg_seed() or * mbedtls_ctr_drbg_free(). * * \param ctx CTR_DRBG context to be initialized diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index 4ffc6468b..e01055802 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -98,7 +98,7 @@ typedef struct /** * \brief HMAC_DRBG context initialization - * Makes the context ready for mbetls_hmac_drbg_seed(), + * Makes the context ready for mbedtls_hmac_drbg_seed(), * mbedtls_hmac_drbg_seed_buf() or * mbedtls_hmac_drbg_free(). * diff --git a/include/mbedtls/pkcs11.h b/include/mbedtls/pkcs11.h index aa549fd6b..7632929cb 100644 --- a/include/mbedtls/pkcs11.h +++ b/include/mbedtls/pkcs11.h @@ -54,7 +54,7 @@ typedef struct { } mbedtls_pkcs11_context; /** - * Initialize a mbetls_pkcs11_context. + * Initialize a mbedtls_pkcs11_context. * (Just making memory references valid.) */ void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ); diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 2d7beb359..d23b1bedb 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -840,7 +840,7 @@ int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ); /** * \brief Initialize an SSL context - * Just makes the context ready for mbetls_ssl_setup() or + * Just makes the context ready for mbedtls_ssl_setup() or * mbedtls_ssl_free() * * \param ssl SSL context diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h index cc8754c80..ae7a713e7 100644 --- a/include/mbedtls/timing.h +++ b/include/mbedtls/timing.h @@ -92,7 +92,7 @@ void mbedtls_set_alarm( int seconds ); * (See \c mbedtls_timing_get_delay().) * * \param data Pointer to timing data - * Must point to a valid \c mbetls_timing_delay_context struct. + * Must point to a valid \c mbedtls_timing_delay_context struct. * \param int_ms First (intermediate) delay in milliseconds. * \param fin_ms Second (final) delay in milliseconds. * Pass 0 to cancel the current delay. @@ -104,7 +104,7 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); * (Memory helper: number of delays passed.) * * \param data Pointer to timing data - * Must point to a valid \c mbetls_timing_delay_context struct. + * Must point to a valid \c mbedtls_timing_delay_context struct. * * \return -1 if cancelled (fin_ms = 0) * 0 if none of the delays are passed, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d9b05fd1f..92132900a 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6993,7 +6993,7 @@ static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { #endif /* - * Load default in mbetls_ssl_config + * Load default in mbedtls_ssl_config */ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, int endpoint, int transport, int preset ) From 89f77623b8539a84fb18dc92f739b5bb791d7cb0 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Sun, 27 Sep 2015 22:50:49 +0100 Subject: [PATCH 42/73] Added max length checking of hostname --- include/mbedtls/ssl.h | 3 +++ library/ssl_tls.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 2d7beb359..780aa62a9 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -139,6 +139,9 @@ #define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ #define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ +#define MBEDTLS_SSL_MAX_HOST_NAME 255 /*!< Maximum host name +defined in RFC 1035 */ + /* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c * NONE must be zero so that memset()ing structure to zero works */ #define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d9b05fd1f..23165a43d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5833,6 +5833,9 @@ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) if( hostname_len + 1 == 0 ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); if( ssl->hostname == NULL ) From ed9976634fef41e34b6f7ffe59d9703cc2c04dc2 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Mon, 28 Sep 2015 02:14:30 +0100 Subject: [PATCH 43/73] Added bounds checking for TLS extensions IOTSSL-478 - Added checks to prevent buffer overflows. --- library/ssl_cli.c | 111 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index c82e2e70a..842f12c7f 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -60,6 +60,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t hostname_len; *olen = 0; @@ -72,6 +73,13 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, hostname_len = strlen( ssl->hostname ); + if( (size_t)(end - p) < hostname_len + 9 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for hostname" ) ); + return; + } + + /* * struct { * NameType name_type; @@ -115,6 +123,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; @@ -123,6 +132,12 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); + if( (size_t)(end - p) < 5 + ssl->verify_data_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + /* * Secure renegotiation */ @@ -149,6 +164,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t sig_alg_len = 0; const int *md; #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) @@ -162,9 +178,27 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); + for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) + { +#if defined(MBEDTLS_ECDSA_C) + sig_alg_len += 2; +#endif +#if defined(MBEDTLS_RSA_C) + sig_alg_len += 2; +#endif + } + + if( (size_t)(end - p) < sig_alg_len + 6 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + /* * Prepare signature_algorithms extension (TLS 1.2) */ + sig_alg_len = 0; + for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) { #if defined(MBEDTLS_ECDSA_C) @@ -214,6 +248,7 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; unsigned char *elliptic_curve_list = p + 6; size_t elliptic_curve_len = 0; const mbedtls_ecp_curve_info *info; @@ -227,6 +262,25 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); +#if defined(MBEDTLS_ECP_C) + for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) + { + info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); +#else + for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) + { +#endif + elliptic_curve_len += 2; + } + + if( (size_t)(end - p) < 6 + elliptic_curve_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + elliptic_curve_len = 0; + #if defined(MBEDTLS_ECP_C) for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) { @@ -260,12 +314,18 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - ((void) ssl); + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); + if( (size_t)(end - p) < 6 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); @@ -285,6 +345,7 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) { *olen = 0; @@ -293,6 +354,12 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); + if( (size_t)(end - p) < 5 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); @@ -310,6 +377,7 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) { @@ -319,6 +387,12 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); + if( (size_t)(end - p) < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); @@ -334,6 +408,7 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) @@ -345,6 +420,12 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " "extension" ) ); + if( (size_t)(end - p) < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); @@ -360,6 +441,7 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) @@ -371,6 +453,12 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " "extension" ) ); + if( (size_t)(end - p) < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); @@ -386,6 +474,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t tlen = ssl->session_negotiate->ticket_len; if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) @@ -396,6 +485,12 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); + if( (size_t)(end - p) < 4 + tlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); @@ -404,8 +499,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, *olen = 4; - if( ssl->session_negotiate->ticket == NULL || - ssl->session_negotiate->ticket_len == 0 ) + if( ssl->session_negotiate->ticket == NULL || tlen == 0 ) { return; } @@ -423,6 +517,8 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t alpnlen = 0; const char **cur; if( ssl->conf->alpn_list == NULL ) @@ -433,6 +529,15 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); + for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) + alpnlen += *p = (unsigned char)( strlen( *cur ) & 0xFF ); + + if( (size_t)(end - p) < 6 + alpnlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); From 58fb49531da29b5a744a0999c4b14eb6d00e0fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 28 Sep 2015 13:48:04 +0200 Subject: [PATCH 44/73] Fix potential buffer overflow in mpi_read_string() Found by Guido Vranken. Two possible integer overflows (during << 2 or addition in BITS_TO_LIMB()) could result in far too few memory to be allocated, then overflowing the buffer in the subsequent for loop. Both integer overflows happen when slen is close to or greater than SIZE_T_MAX >> 2 (ie 2^30 on a 32 bit system). Note: one could also avoid those overflows by changing BITS_TO_LIMB(s << 2) to CHARS_TO_LIMB(s >> 1) but the solution implemented looks more robust with respect to future code changes. --- ChangeLog | 9 +++++++++ library/bignum.c | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9e48e244..756080325 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.1.2 released 2015-??-?? + +Security + * Fix potential buffer overflow in mbedtls_mpi_read_string(). + Found by Guido Vranken. Not exploitable remotely in the context of TLS, + but might be in other uses. On 32 bit machines, requires reading a string + of close to or larger than 1GB to exploit; on 64 bit machines, would require + reading a string of close to or larger than 2^62 bytes. + = mbed TLS 2.1.1 released 2015-09-17 Security diff --git a/library/bignum.c b/library/bignum.c index 15cbf73fb..280bbfd85 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -38,6 +38,7 @@ #include "mbedtls/bn_mul.h" #include +#include #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" @@ -60,9 +61,10 @@ static void mbedtls_zeroize( void *v, size_t n ) { /* * Convert between bits/chars and number of limbs + * Divide first in order to avoid potential overflows */ -#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) -#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) +#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) +#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) /* * Initialize one MPI @@ -409,6 +411,9 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) if( radix == 16 ) { + if( slen > SIZE_T_MAX >> 2 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + n = BITS_TO_LIMBS( slen << 2 ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) ); From 24417f06feda5a0756c362146c932909c19b6673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 28 Sep 2015 18:09:45 +0200 Subject: [PATCH 45/73] Fix potential double-free in mbedtls_ssl_conf_psk() --- ChangeLog | 7 +++++++ library/ssl_tls.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index c9e48e244..f0c71fda4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.1.2 released 2015-??-?? + +Security + * Fix potential double-free if mbedtls_conf_psk() is called repeatedly on + the same mbedtls_ssl_config object and some memory allocations fail. + Found by Guido Vranken. Can not be forced remotely. + = mbed TLS 2.1.1 released 2015-09-17 Security diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d9b05fd1f..c1e29c782 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5707,7 +5707,9 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL ) { mbedtls_free( conf->psk ); + mbedtls_free( conf->psk_identity ); conf->psk = NULL; + conf->psk_identity = NULL; return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } From d02a1daca792e293c28760e3e3ab9897cee20bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 28 Sep 2015 18:34:48 +0200 Subject: [PATCH 46/73] Fix stack buffer overflow in pkcs12 --- ChangeLog | 7 +++++++ library/pkcs12.c | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c9e48e244..f2defa691 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.1.2 released 2015-??-?? + +Security + * Fix stack buffer overflow in pkcs12 decryption (used by + mbedtls_pk_parse_key(file)() when the password is > 129 bytes. + Found by Guido Vranken. Not triggerable remotely. + = mbed TLS 2.1.1 released 2015-09-17 Security diff --git a/library/pkcs12.c b/library/pkcs12.c index f1777eb70..7023b9dbc 100644 --- a/library/pkcs12.c +++ b/library/pkcs12.c @@ -86,6 +86,8 @@ static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, return( 0 ); } +#define PKCS12_MAX_PWDLEN 128 + static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, const unsigned char *pwd, size_t pwdlen, unsigned char *key, size_t keylen, @@ -94,7 +96,10 @@ static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_ty int ret, iterations; mbedtls_asn1_buf salt; size_t i; - unsigned char unipwd[258]; + unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; + + if( pwdlen > PKCS12_MAX_PWDLEN ) + return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); memset( &unipwd, 0, sizeof(unipwd) ); @@ -125,6 +130,8 @@ static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_ty return( 0 ); } +#undef PKCS12_MAX_PWDLEN + int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, const unsigned char *pwd, size_t pwdlen, const unsigned char *data, size_t len, From 9f81231fb84736c11fdae47b2f707c6e3127ddbb Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Mon, 28 Sep 2015 19:22:33 +0100 Subject: [PATCH 47/73] Revised hostname length check from review --- include/mbedtls/ssl.h | 3 +-- library/ssl_tls.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 780aa62a9..767b06633 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -139,8 +139,7 @@ #define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ #define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ -#define MBEDTLS_SSL_MAX_HOST_NAME 255 /*!< Maximum host name -defined in RFC 1035 */ +#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ /* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c * NONE must be zero so that memset()ing structure to zero works */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 23165a43d..9702971b4 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5833,7 +5833,7 @@ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) if( hostname_len + 1 == 0 ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME ) + if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); From 0fc94e9f8338ed13d1a94ec2b42e2d20051edecb Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Mon, 28 Sep 2015 20:52:04 +0100 Subject: [PATCH 48/73] Revised bounds checking on TLS extensions Revisions following review feedback --- library/ssl_cli.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 842f12c7f..825a74f6e 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -73,13 +73,12 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, hostname_len = strlen( ssl->hostname ); - if( (size_t)(end - p) < hostname_len + 9 ) + if( end < p || (size_t)( end - p ) < hostname_len + 9 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for hostname" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; } - /* * struct { * NameType name_type; @@ -132,7 +131,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); - if( (size_t)(end - p) < 5 + ssl->verify_data_len ) + if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -188,7 +187,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, #endif } - if( (size_t)(end - p) < sig_alg_len + 6 ) + if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -273,7 +272,7 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, elliptic_curve_len += 2; } - if( (size_t)(end - p) < 6 + elliptic_curve_len ) + if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -320,7 +319,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); - if( (size_t)(end - p) < 6 ) + if( end < p || (size_t)( end - p ) < 6 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -347,14 +346,15 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + *olen = 0; + if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) { - *olen = 0; return; } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); - if( (size_t)(end - p) < 5 ) + if( end < p || (size_t)( end - p ) < 5 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -379,15 +379,16 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + *olen = 0; + if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) { - *olen = 0; return; } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); - if( (size_t)(end - p) < 4 ) + if( end < p || (size_t)( end - p ) < 4 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -410,17 +411,18 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + *olen = 0; + if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - *olen = 0; return; } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " "extension" ) ); - if( (size_t)(end - p) < 4 ) + if( end < p || (size_t)( end - p ) < 4 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -443,17 +445,18 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + *olen = 0; + if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - *olen = 0; return; } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " "extension" ) ); - if( (size_t)(end - p) < 4 ) + if( end < p || (size_t)( end - p ) < 4 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -477,15 +480,16 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t tlen = ssl->session_negotiate->ticket_len; + *olen = 0; + if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) { - *olen = 0; return; } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); - if( (size_t)(end - p) < 4 + tlen ) + if( end < p || (size_t)( end - p ) < 4 + tlen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; @@ -521,9 +525,10 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, size_t alpnlen = 0; const char **cur; + *olen = 0; + if( ssl->conf->alpn_list == NULL ) { - *olen = 0; return; } @@ -532,7 +537,7 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) alpnlen += *p = (unsigned char)( strlen( *cur ) & 0xFF ); - if( (size_t)(end - p) < 6 + alpnlen ) + if( end < p || (size_t)( end - p ) < 6 + alpnlen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); return; From 04799a4274c814466f670f568ca442b8c1a2cbcb Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Tue, 29 Sep 2015 00:31:09 +0100 Subject: [PATCH 49/73] Fixed copy and paste error Accidental additional assignment in ssl_write_alpn_ext() --- ChangeLog | 12 +++++++++++- library/ssl_cli.c | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9e48e244..4eb8dd883 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ mbed TLS ChangeLog (Sorted per branch, date) -= mbed TLS 2.1.1 released 2015-09-17 += mbed TLS 2.1.2 released 2015-10-xx + +Security + * Added fix for CVE-2015-xxxxx to prevent heap corruption due to buffer + overflow of the hostname or session ticket. + +Changes + * Added checking of hostname length in mbedtls_ssl_set_hostname() to ensure + domain names are compliant with RFC 1035. + += mbe TLS 2.1.1 released 2015-09-17 Security * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 825a74f6e..1ba8648c9 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -535,7 +535,7 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) - alpnlen += *p = (unsigned char)( strlen( *cur ) & 0xFF ); + alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1; if( end < p || (size_t)( end - p ) < 6 + alpnlen ) { From 5624ec824e8a495c1fce5fe8a49907ef0852cbc1 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Tue, 29 Sep 2015 01:06:06 +0100 Subject: [PATCH 50/73] Reordered TLS extension fields in client Session ticket placed at end --- ChangeLog | 2 +- library/ssl_cli.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4eb8dd883..d4d859813 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,7 +10,7 @@ Changes * Added checking of hostname length in mbedtls_ssl_set_hostname() to ensure domain names are compliant with RFC 1035. -= mbe TLS 2.1.1 released 2015-09-17 += mbed TLS 2.1.1 released 2015-09-17 Security * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 1ba8648c9..32eae0f2a 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -909,13 +909,13 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); +#if defined(MBEDTLS_SSL_ALPN) + ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; #endif -#if defined(MBEDTLS_SSL_ALPN) - ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; #endif From 50a739f8c36efc93d52f162c852a47efc44b3d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 30 Sep 2015 16:28:38 +0200 Subject: [PATCH 51/73] Add test for base64 output length --- tests/suites/test_suite_base64.data | 52 ++++++++++++++++++----------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data index 3b66da165..da99ffa87 100644 --- a/tests/suites/test_suite_base64.data +++ b/tests/suites/test_suite_base64.data @@ -1,23 +1,41 @@ -Test case mbedtls_base64_encode #1 -mbedtls_base64_encode:"":"":1000:0 +Test case mbedtls_base64_encode #1 buffer just right +mbedtls_base64_encode:"":"":0:0 -Test case mbedtls_base64_encode #2 -mbedtls_base64_encode:"f":"Zg==":1000:0 +Test case mbedtls_base64_encode #2 buffer just right +mbedtls_base64_encode:"f":"Zg==":5:0 -Test case mbedtls_base64_encode #3 -mbedtls_base64_encode:"fo":"Zm8=":1000:0 +Test case mbedtls_base64_encode #2 buffer too small +mbedtls_base64_encode:"f":"Zg==":4:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -Test case mbedtls_base64_encode #4 -mbedtls_base64_encode:"foo":"Zm9v":1000:0 +Test case mbedtls_base64_encode #3 buffer just right +mbedtls_base64_encode:"fo":"Zm8=":5:0 -Test case mbedtls_base64_encode #5 -mbedtls_base64_encode:"foob":"Zm9vYg==":1000:0 +Test case mbedtls_base64_encode #3 buffer too small +mbedtls_base64_encode:"fo":"Zm8=":4:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -Test case mbedtls_base64_encode #6 -mbedtls_base64_encode:"fooba":"Zm9vYmE=":1000:0 +Test case mbedtls_base64_encode #4 buffer just right +mbedtls_base64_encode:"foo":"Zm9v":5:0 -Test case mbedtls_base64_encode #7 -mbedtls_base64_encode:"foobar":"Zm9vYmFy":1000:0 +Test case mbedtls_base64_encode #4 buffer too small +mbedtls_base64_encode:"foo":"Zm9v":4:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL + +Test case mbedtls_base64_encode #5 buffer just right +mbedtls_base64_encode:"foob":"Zm9vYg==":9:0 + +Test case mbedtls_base64_encode #5 buffer too small +mbedtls_base64_encode:"foob":"Zm9vYg==":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL + +Test case mbedtls_base64_encode #6 buffer just right +mbedtls_base64_encode:"fooba":"Zm9vYmE=":9:0 + +Test case mbedtls_base64_encode #6 buffer too small +mbedtls_base64_encode:"fooba":"Zm9vYmE=":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL + +Test case mbedtls_base64_encode #7 buffer just right +mbedtls_base64_encode:"foobar":"Zm9vYmFy":9:0 + +Test case mbedtls_base64_encode #7 buffer too small +mbedtls_base64_encode:"foobar":"Zm9vYmFy":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL Test case mbedtls_base64_decode #1 mbedtls_base64_decode:"":"":0 @@ -40,12 +58,6 @@ mbedtls_base64_decode:"Zm9vYmE=":"fooba":0 Test case mbedtls_base64_decode #7 mbedtls_base64_decode:"Zm9vYmFy":"foobar":0 -Base64 encode (buffer size just right) -mbedtls_base64_encode:"foobar":"Zm9vYmFy":9:0 - -Base64 encode (buffer size too small) -mbedtls_base64_encode:"foobar":"":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL - Base64 decode (Illegal character) mbedtls_base64_decode:"zm#=":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER From 0aa45c209a9a2c4409fe4b32a0a3bf50f00dce71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 30 Sep 2015 16:30:28 +0200 Subject: [PATCH 52/73] Fix potential overflow in base64_encode --- ChangeLog | 7 +++++++ include/mbedtls/base64.h | 3 +++ library/base64.c | 11 ++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9e48e244..187c1ee0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,13 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.1.1 released 2015-09-17 +Security + * Fix possible heap buffer overflow in base64_encoded() when the input + buffer is 512MB or larger on 32-bit platforms. + Found by Guido Vranken. Not trigerrable remotely in TLS. + += mbed TLS 2.1.1 released 2015-09-17 + Security * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 signatures. (Found by Florian Weimer, Red Hat.) diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h index 28a3a4c59..18e83120b 100644 --- a/include/mbedtls/base64.h +++ b/include/mbedtls/base64.h @@ -24,6 +24,7 @@ #define MBEDTLS_BASE64_H #include +#include #define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ #define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ @@ -44,6 +45,8 @@ extern "C" { * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. * *olen is always updated to reflect the amount * of data that has (or would have) been written. + * If that length cannot be represented, then no data is + * written to the buffer and *olen is set to SIZE_T_MAX. * * \note Call this function with dlen = 0 to obtain the * required buffer size in *olen diff --git a/library/base64.c b/library/base64.c index 16c254da9..8c9953805 100644 --- a/library/base64.c +++ b/library/base64.c @@ -85,15 +85,16 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, return( 0 ); } - n = ( slen << 3 ) / 6; + n = slen / 3 + ( slen % 3 != 0 ); - switch( ( slen << 3 ) - ( n * 6 ) ) + if( n > ( SIZE_T_MAX - 1 ) / 4 ) { - case 2: n += 3; break; - case 4: n += 2; break; - default: break; + *olen = SIZE_T_MAX; + return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); } + n *= 4; + if( dlen < n + 1 ) { *olen = n + 1; From a12e3c00bf90626a73ee87bb2dc0bedad79b4432 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Thu, 1 Oct 2015 01:59:33 +0100 Subject: [PATCH 53/73] Updated ChangeLog with credit --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index c9e48e244..1176c590d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.1.2 released 2015-10-xx + +Changes + * Fixed paths for check_config.h in example config files. (Found by bachp) + (#291) + = mbed TLS 2.1.1 released 2015-09-17 Security From bc1babb38759446b93ec53d82f0ec961cffe1b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 2 Oct 2015 11:16:47 +0200 Subject: [PATCH 54/73] Fix potential overflow in CertificateRequest --- ChangeLog | 6 ++++++ library/ssl_srv.c | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68b1255b9..57024a043 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,12 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.1.2 released 2015-10-xx +Security + * Fix potential heap buffer overflow in servers that perform client + authentication against a crafted CA cert. Cannot be triggered remotely + unless you allow third parties to pick trust CAs for client auth. + Found by Guido Vranken. + Changes * Fixed paths for check_config.h in example config files. (Found by bachp) (#291) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index b48a609ee..1bda53c46 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -2351,6 +2351,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) size_t dn_size, total_dn_size; /* excluding length bytes */ size_t ct_len, sa_len; /* including length bytes */ unsigned char *buf, *p; + const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const mbedtls_x509_crt *crt; int authmode; @@ -2471,10 +2472,14 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) total_dn_size = 0; while( crt != NULL && crt->version != 0 ) { - if( p - buf > 4096 ) - break; - dn_size = crt->subject_raw.len; + + if( end < p || (size_t)( end - p ) < 2 + dn_size ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); + break; + } + *p++ = (unsigned char)( dn_size >> 8 ); *p++ = (unsigned char)( dn_size ); memcpy( p, crt->subject_raw.p, dn_size ); From 5b8d1d65f746f1eae34225dfa6241d0401fbe746 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Sun, 4 Oct 2015 22:06:51 +0100 Subject: [PATCH 55/73] Fix for IOTSSL-473 Double free error Fix potential double-free in mbedtls_ssl_set_hs_psk(.) --- ChangeLog | 8 ++++++-- library/ssl_tls.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7310f3e91..e024af818 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,10 @@ mbed TLS ChangeLog (Sorted per branch, date) Security * Added fix for CVE-2015-xxxxx to prevent heap corruption due to buffer - overflow of the hostname or session ticket. + overflow of the hostname or session ticket. (Found by Guido Vranken). + * Fix potential double-free if mbedtls_ssl_set_hs_psk() is called more than + once in the same handhake and mbedtls_ssl_conf_psk() was used. + Found and patch provided by Guido Vranken. Cannot be forced remotely. Changes * Added checking of hostname length in mbedtls_ssl_set_hostname() to ensure @@ -20,7 +23,8 @@ Security https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/ * Fix possible client-side NULL pointer dereference (read) when the client tries to continue the handshake after it failed (a misuse of the API). - (Found and patch provided by Fabian Foerg, Gotham Digital Science using afl-fuzz.) + (Found and patch provided by Fabian Foerg, Gotham Digital Science using + afl-fuzz.) Bugfix * Fix warning when using a 64bit platform. (found by embedthis) (#275) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 71c99d3fc..43cbe0fc4 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5730,7 +5730,7 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); if( ssl->handshake->psk != NULL ) - mbedtls_free( ssl->conf->psk ); + mbedtls_free( ssl->handshake->psk ); if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) { From a45aa1399bcbcffadd600369c1f8d9016d7886ba Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Mon, 5 Oct 2015 00:26:36 +0100 Subject: [PATCH 56/73] Merge of IOTSSL-476 - Random malloc in pem_read() --- ChangeLog | 4 ++++ library/base64.c | 3 +++ library/pem.c | 3 +++ 3 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 63cedaa1c..2aa7a2182 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,10 @@ Security but might be in other uses. On 32 bit machines, requires reading a string of close to or larger than 1GB to exploit; on 64 bit machines, would require reading a string of close to or larger than 2^62 bytes. + * Fix potential random memory allocation in mbedtls_pem_read_buffer() + on crafted PEM input data. Found an fix provided by Guid Vranken. + Not triggerable remotely in TLS. Triggerable remotely if you accept PEM + data from an untrusted source. Changes * Added checking of hostname length in mbedtls_ssl_set_hostname() to ensure diff --git a/library/base64.c b/library/base64.c index 16c254da9..e468e2cbc 100644 --- a/library/base64.c +++ b/library/base64.c @@ -184,7 +184,10 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, } if( n == 0 ) + { + *olen = 0; return( 0 ); + } n = ( ( n * 6 ) + 7 ) >> 3; n -= j; diff --git a/library/pem.c b/library/pem.c index 541e870c3..1ee3966e1 100644 --- a/library/pem.c +++ b/library/pem.c @@ -316,6 +316,9 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ } + if( s1 == s2 ) + return( MBEDTLS_ERR_PEM_INVALID_DATA ); + ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER ) From c48b66bfb6efd3bdd2deab7f1cb6523da55402de Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Mon, 5 Oct 2015 10:18:17 +0100 Subject: [PATCH 57/73] Changed attribution for Guido Vranken --- ChangeLog | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index c527e0603..ca2e71780 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,22 +4,27 @@ mbed TLS ChangeLog (Sorted per branch, date) Security * Added fix for CVE-2015-xxxxx to prevent heap corruption due to buffer - overflow of the hostname or session ticket. Found by Guido Vranken. + overflow of the hostname or session ticket. Found by Guido Vranken, + Intelworks. * Fix potential double-free if mbedtls_ssl_set_hs_psk() is called more than once in the same handhake and mbedtls_ssl_conf_psk() was used. - Found and patch provided by Guido Vranken. Cannot be forced remotely. + Found and patch provided by Guido Vranken, Intelworks. Cannot be forced + remotely. * Fix stack buffer overflow in pkcs12 decryption (used by mbedtls_pk_parse_key(file)() when the password is > 129 bytes. - Found by Guido Vranken. Not triggerable remotely. + Found by Guido Vranken, Intelworks. Not triggerable remotely. * Fix potential buffer overflow in mbedtls_mpi_read_string(). - Found by Guido Vranken. Not exploitable remotely in the context of TLS, - but might be in other uses. On 32 bit machines, requires reading a string - of close to or larger than 1GB to exploit; on 64 bit machines, would require - reading a string of close to or larger than 2^62 bytes. + Found by Guido Vranken, Intelworks. Not exploitable remotely in the context + of TLS, but might be in other uses. On 32 bit machines, requires reading a + string of close to or larger than 1GB to exploit; on 64 bit machines, would + require reading a string of close to or larger than 2^62 bytes. * Fix potential random memory allocation in mbedtls_pem_read_buffer() - on crafted PEM input data. Found an fix provided by Guid Vranken. - Not triggerable remotely in TLS. Triggerable remotely if you accept PEM - data from an untrusted source. + on crafted PEM input data. Found and fix provided by Guido Vranken, + Intelworks. Not triggerable remotely in TLS. Triggerable remotely if you + accept PEM data from an untrusted source. + * Fix possible heap buffer overflow in base64_encoded() when the input + buffer is 512MB or larger on 32-bit platforms. Found by Guido Vranken, + Intelworks. Not trigerrable remotely in TLS. Changes * Added checking of hostname length in mbedtls_ssl_set_hostname() to ensure @@ -29,13 +34,6 @@ Changes = mbed TLS 2.1.1 released 2015-09-17 -Security - * Fix possible heap buffer overflow in base64_encoded() when the input - buffer is 512MB or larger on 32-bit platforms. - Found by Guido Vranken. Not trigerrable remotely in TLS. - -= mbed TLS 2.1.1 released 2015-09-17 - Security * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 signatures. (Found by Florian Weimer, Red Hat.) From 0223ab9d3885ebdf226a38bccfc1e765ed91704b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 11:40:01 +0100 Subject: [PATCH 58/73] Fix macroization of inline in C++ When compiling as C++, MSVC complains about our macroization of a keyword. Stop doing that as we know inline is always available in C++ --- ChangeLog | 3 +++ include/mbedtls/cipher.h | 3 ++- include/mbedtls/md.h | 3 ++- include/mbedtls/pkcs11.h | 3 ++- include/mbedtls/ssl_internal.h | 3 ++- library/debug.c | 3 ++- library/ecp.c | 3 ++- library/ecp_curves.c | 3 ++- 8 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68b1255b9..c596908c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.1.2 released 2015-10-xx +Bugfix + * Fix macroization of 'inline' keywork when building as C++. (#279) + Changes * Fixed paths for check_config.h in example config files. (Found by bachp) (#291) diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index 87d9c79f5..70000f5e6 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -46,7 +46,8 @@ #define MBEDTLS_CIPHER_MODE_STREAM #endif -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) #define inline __inline #endif diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h index 1834b5992..a70d7a60d 100644 --- a/include/mbedtls/md.h +++ b/include/mbedtls/md.h @@ -27,7 +27,8 @@ #include -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) #define inline __inline #endif diff --git a/include/mbedtls/pkcs11.h b/include/mbedtls/pkcs11.h index 7632929cb..2e8892813 100644 --- a/include/mbedtls/pkcs11.h +++ b/include/mbedtls/pkcs11.h @@ -37,7 +37,8 @@ #include -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) #define inline __inline #endif diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 73279a5ae..78c748cfa 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -41,7 +41,8 @@ #include "sha512.h" #endif -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) #define inline __inline #endif diff --git a/library/debug.c b/library/debug.c index 070f63a72..4752ab1a3 100644 --- a/library/debug.c +++ b/library/debug.c @@ -42,7 +42,8 @@ #define mbedtls_snprintf snprintf #endif -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) #define inline __inline #endif diff --git a/library/ecp.c b/library/ecp.c index 858540be2..64a47ab52 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -62,7 +62,8 @@ #define mbedtls_free free #endif -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) #define inline __inline #endif diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 68323c582..9a6e8eb18 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -31,7 +31,8 @@ #include -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) #define inline __inline #endif From 5a2e389811f10d873f21dd461cdee89a497c74de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 11:55:39 +0100 Subject: [PATCH 59/73] Remove inline workaround when not useful This header doesn't have nay inline function any more --- include/mbedtls/md.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h index a70d7a60d..77c2c6f68 100644 --- a/include/mbedtls/md.h +++ b/include/mbedtls/md.h @@ -27,11 +27,6 @@ #include -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */ #define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */ From cb6af00e2a10e43fc7eb5cb90249769edefb39a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 12:12:39 +0100 Subject: [PATCH 60/73] Add missing warning in doc Found by Nicholas Wilson fixes #288 --- include/mbedtls/config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 6e9d8f3df..68153efdc 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1246,6 +1246,8 @@ * If set, the X509 parser will not break-off when parsing an X509 certificate * and encountering an unknown critical extension. * + * \warning Depending on your PKI use, enabling this can be a security risk! + * * Uncomment to prevent an error. */ //#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION From 0431735299031100c2d80ffdb522487bff2ad811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 12:16:06 +0100 Subject: [PATCH 61/73] Fix compile error in net.c with musl libc fixes #278 --- ChangeLog | 4 ++++ library/net.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 68b1255b9..e3353d0d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.1.2 released 2015-10-xx +Bugfix + * Fix compile error in net.c with musl libc. Found and patch provided by + zhasha (#278). + Changes * Fixed paths for check_config.h in example config files. (Found by bachp) (#291) diff --git a/library/net.c b/library/net.c index b5d06888b..a77268c55 100644 --- a/library/net.c +++ b/library/net.c @@ -292,7 +292,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, struct sockaddr_storage client_addr; #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ - defined(_SOCKLEN_T_DECLARED) + defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t type_len = (socklen_t) sizeof( type ); #else From 2347bdd7b5e15780c06c1ac2085c2627e09f3e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 14:06:48 +0100 Subject: [PATCH 62/73] Upgrade yotta dependency versions --- yotta/data/module.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yotta/data/module.json b/yotta/data/module.json index 9a9e8a164..843667544 100644 --- a/yotta/data/module.json +++ b/yotta/data/module.json @@ -10,9 +10,9 @@ ], "dependencies": {}, "targetDependencies": { - "mbed": { "cmsis-core": "~0.2.3" } + "mbed": { "cmsis-core": "~0.3.0" } }, "testTargetDependencies": { - "mbed": { "sockets": "~0.4.0" } + "mbed": { "sockets": "~0.5.0" } } } From 0ccd4537bd7ee830311d329b5716f43305418d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 14:50:41 +0100 Subject: [PATCH 63/73] Fix yotta version dependencies again --- yotta/data/module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yotta/data/module.json b/yotta/data/module.json index 843667544..e480ade65 100644 --- a/yotta/data/module.json +++ b/yotta/data/module.json @@ -10,7 +10,7 @@ ], "dependencies": {}, "targetDependencies": { - "mbed": { "cmsis-core": "~0.3.0" } + "mbed": { "cmsis-core": "~0.2.3" } }, "testTargetDependencies": { "mbed": { "sockets": "~0.5.0" } From 2d7083435dbd60e800916b4380c90cd56c762691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 15:23:11 +0100 Subject: [PATCH 64/73] Fix references to non-standard SIZE_T_MAX Turns out C99 doesn't define SIZE_T_MAX, so let's not use it. --- include/mbedtls/base64.h | 4 ++-- library/base64.c | 6 ++++-- library/bignum.c | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h index 18e83120b..352c652db 100644 --- a/include/mbedtls/base64.h +++ b/include/mbedtls/base64.h @@ -24,7 +24,6 @@ #define MBEDTLS_BASE64_H #include -#include #define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ #define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ @@ -46,7 +45,8 @@ extern "C" { * *olen is always updated to reflect the amount * of data that has (or would have) been written. * If that length cannot be represented, then no data is - * written to the buffer and *olen is set to SIZE_T_MAX. + * written to the buffer and *olen is set to the maximum + * length representable as a size_t. * * \note Call this function with dlen = 0 to obtain the * required buffer size in *olen diff --git a/library/base64.c b/library/base64.c index fc44c15ae..3432e5fcd 100644 --- a/library/base64.c +++ b/library/base64.c @@ -69,6 +69,8 @@ static const unsigned char base64_dec_map[128] = 49, 50, 51, 127, 127, 127, 127, 127 }; +#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ + /* * Encode a buffer into base64 format */ @@ -87,9 +89,9 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, n = slen / 3 + ( slen % 3 != 0 ); - if( n > ( SIZE_T_MAX - 1 ) / 4 ) + if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 ) { - *olen = SIZE_T_MAX; + *olen = BASE64_SIZE_T_MAX; return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); } diff --git a/library/bignum.c b/library/bignum.c index 280bbfd85..628a6eedd 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -38,7 +38,6 @@ #include "mbedtls/bn_mul.h" #include -#include #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" @@ -59,6 +58,8 @@ static void mbedtls_zeroize( void *v, size_t n ) { #define biL (ciL << 3) /* bits in limb */ #define biH (ciL << 2) /* half limb size */ +#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ + /* * Convert between bits/chars and number of limbs * Divide first in order to avoid potential overflows @@ -411,7 +412,7 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) if( radix == 16 ) { - if( slen > SIZE_T_MAX >> 2 ) + if( slen > MPI_SIZE_T_MAX >> 2 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); n = BITS_TO_LIMBS( slen << 2 ); From 2ac9c60838b11a18f23a9abd923985b7d30f714d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 16:18:23 +0100 Subject: [PATCH 65/73] Add 'inline' workaround where needed Was previously using the workaround from md.h --- include/mbedtls/pk.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index acd9068b6..e5e78fba1 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -44,6 +44,11 @@ #include "ecdsa.h" #endif +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + #define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 /**< Memory allocation failed. */ #define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */ #define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 /**< Bad input parameters to function. */ @@ -59,7 +64,6 @@ #define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ #define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The signature is valid but its length is less than expected. */ - #ifdef __cplusplus extern "C" { #endif From ca056c7748df79f6d73f010623a4a1afcb686364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 18:21:34 +0100 Subject: [PATCH 66/73] Fix CVE number in ChangeLog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7cbbb3f74..4ae1a36c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.1.2 released 2015-10-xx Security - * Added fix for CVE-2015-xxxxx to prevent heap corruption due to buffer + * Added fix for CVE-2015-5291 to prevent heap corruption due to buffer overflow of the hostname or session ticket. Found by Guido Vranken, Intelworks. * Fix potential double-free if mbedtls_ssl_set_hs_psk() is called more than From c4e7d8a3817bbdee218328efa9e482217038152b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 5 Oct 2015 18:59:19 +0100 Subject: [PATCH 67/73] Bump version to 2.1.2 Yotta version bumped to 2.1.3, as we had to do one more patch release to the yotta registry to accommodate for dependencies updates. --- ChangeLog | 2 +- doxygen/input/doc_mainpage.h | 2 +- doxygen/mbedtls.doxyfile | 2 +- include/mbedtls/version.h | 8 ++++---- library/CMakeLists.txt | 6 +++--- tests/suites/test_suite_version.data | 4 ++-- yotta/data/module.json | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ae1a36c9..aa96b1848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ mbed TLS ChangeLog (Sorted per branch, date) -= mbed TLS 2.1.2 released 2015-10-xx += mbed TLS 2.1.2 released 2015-10-06 Security * Added fix for CVE-2015-5291 to prevent heap corruption due to buffer diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index 076f24dc9..16320da88 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -21,7 +21,7 @@ */ /** - * @mainpage mbed TLS v2.1.1 source code documentation + * @mainpage mbed TLS v2.1.2 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 e5cd908df..27b5d4b33 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8 # 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.1.1" +PROJECT_NAME = "mbed TLS v2.1.2" # 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 d09726439..8bc2708e9 100644 --- a/include/mbedtls/version.h +++ b/include/mbedtls/version.h @@ -39,16 +39,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 1 -#define MBEDTLS_VERSION_PATCH 1 +#define MBEDTLS_VERSION_PATCH 2 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02010100 -#define MBEDTLS_VERSION_STRING "2.1.1" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.1.1" +#define MBEDTLS_VERSION_NUMBER 0x02010200 +#define MBEDTLS_VERSION_STRING "2.1.2" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.1.2" #if defined(MBEDTLS_VERSION_C) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index ea43ccbae..da6604096 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -138,15 +138,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY) add_library(mbedcrypto SHARED ${src_crypto}) - set_target_properties(mbedcrypto PROPERTIES VERSION 2.1.1 SOVERSION 0) + set_target_properties(mbedcrypto PROPERTIES VERSION 2.1.2 SOVERSION 0) target_link_libraries(mbedcrypto ${libs}) add_library(mbedx509 SHARED ${src_x509}) - set_target_properties(mbedx509 PROPERTIES VERSION 2.1.1 SOVERSION 0) + set_target_properties(mbedx509 PROPERTIES VERSION 2.1.2 SOVERSION 0) target_link_libraries(mbedx509 ${libs} mbedcrypto) add_library(mbedtls SHARED ${src_tls}) - set_target_properties(mbedtls PROPERTIES VERSION 2.1.1 SOVERSION 10) + set_target_properties(mbedtls PROPERTIES VERSION 2.1.2 SOVERSION 10) target_link_libraries(mbedtls ${libs} mbedx509) install(TARGETS mbedtls mbedx509 mbedcrypto diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index ef8a579ce..a2955c662 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.1.1" +check_compiletime_version:"2.1.2" Check runtime library version -check_runtime_version:"2.1.1" +check_runtime_version:"2.1.2" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0 diff --git a/yotta/data/module.json b/yotta/data/module.json index e480ade65..1a65834cc 100644 --- a/yotta/data/module.json +++ b/yotta/data/module.json @@ -1,6 +1,6 @@ { "name": "mbedtls", - "version": "2.1.2", + "version": "2.1.3", "description": "The mbed TLS crypto/SSL/TLS library", "licenses": [ { From 07a92d720a882ecd73c4c16b6756cb784e84b5b5 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 9 Oct 2015 00:28:14 +0100 Subject: [PATCH 68/73] Fix minor spelling mistake in programs/pkey/gen_key.c --- programs/pkey/gen_key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index f60cad762..63a3aeb98 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -209,7 +209,7 @@ int main( int argc, char *argv[] ) ret = 1; mbedtls_printf( USAGE ); #if defined(MBEDTLS_ECP_C) - mbedtls_printf( " availabled ec_curve values:\n" ); + mbedtls_printf( " available ec_curve values:\n" ); curve_info = mbedtls_ecp_curve_list(); mbedtls_printf( " %s (default)\n", curve_info->name ); while( ( ++curve_info )->name != NULL ) From 63666ef1b7dbdceea56ea30d74780507e365d940 Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Fri, 9 Oct 2015 17:00:44 +0300 Subject: [PATCH 69/73] Fix yotta dependencies Recent changes in various repositories broke the build of the yotta module again :( This change fixes the build. Build tested with frdm-k64f-gcc. I didn't update the yotta version number because I don't know what is your policy with regards to version changes. --- yotta/data/module.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yotta/data/module.json b/yotta/data/module.json index 1a65834cc..51b95b231 100644 --- a/yotta/data/module.json +++ b/yotta/data/module.json @@ -10,9 +10,9 @@ ], "dependencies": {}, "targetDependencies": { - "mbed": { "cmsis-core": "~0.2.3" } + "mbed": { "cmsis-core": "~0.4.0" } }, "testTargetDependencies": { - "mbed": { "sockets": "~0.5.0" } + "mbed": { "sockets": "~0.6.0" } } } From 334a87be0bcf8319cb6dec883b8c128acc7d5ec4 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Wed, 14 Oct 2015 22:56:44 +0100 Subject: [PATCH 70/73] Corrected URL/reference to MPI library --- library/bignum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum.c b/library/bignum.c index 628a6eedd..58a4cd2de 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -22,7 +22,7 @@ * This MPI implementation is based on: * * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf - * http://www.stillhq.com/extracted/gnupg-api/mbedtls_mpi/ + * http://www.stillhq.com/extracted/gnupg-api/mpi/ * http://math.libtomcrypt.com/files/tommath.pdf */ From e3132a9e5a73496615268d66445b3d86f65c3931 Mon Sep 17 00:00:00 2001 From: Simon Butcher Date: Mon, 19 Oct 2015 19:28:41 +0100 Subject: [PATCH 71/73] Corrected misleading fn description in ssl_cache.h Mistake in comments spotted by Andris Mednis --- include/mbedtls/ssl_cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h index 53f043e97..18ec16a0d 100644 --- a/include/mbedtls/ssl_cache.h +++ b/include/mbedtls/ssl_cache.h @@ -121,7 +121,7 @@ void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeou #endif /* MBEDTLS_HAVE_TIME */ /** - * \brief Set the cache timeout + * \brief Set the maximun number of cache entries * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) * * \param cache SSL cache context From db90c82eb71a23ffcd82b64a7c029115b9749c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 20 Oct 2015 09:36:39 +0200 Subject: [PATCH 72/73] Fix typo in documentation --- include/mbedtls/ssl_cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h index 18ec16a0d..1155924a9 100644 --- a/include/mbedtls/ssl_cache.h +++ b/include/mbedtls/ssl_cache.h @@ -121,7 +121,7 @@ void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeou #endif /* MBEDTLS_HAVE_TIME */ /** - * \brief Set the maximun number of cache entries + * \brief Set the maximum number of cache entries * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) * * \param cache SSL cache context From b4d9d360e0b317d271906ec9f64afdbba05c041a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 20 Oct 2015 09:56:34 +0200 Subject: [PATCH 73/73] Bump yotta dependencies version --- yotta/data/module.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yotta/data/module.json b/yotta/data/module.json index 51b95b231..848ad03f9 100644 --- a/yotta/data/module.json +++ b/yotta/data/module.json @@ -1,6 +1,6 @@ { "name": "mbedtls", - "version": "2.1.3", + "version": "2.1.4", "description": "The mbed TLS crypto/SSL/TLS library", "licenses": [ { @@ -10,9 +10,9 @@ ], "dependencies": {}, "targetDependencies": { - "mbed": { "cmsis-core": "~0.4.0" } + "mbed": { "cmsis-core": "^1.0.0" } }, "testTargetDependencies": { - "mbed": { "sockets": "~0.6.0" } + "mbed": { "sockets": "^1.0.0" } } }