diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index efd37127035f..f99891e2ccc4 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -163,6 +163,7 @@ #define MBEDTLS_ERR_SSL_BAD_HS_MISSING_EXTENSION_EXT -0x6795 /**< Missing extension. */ #define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x6796 /**< Received NewSessionTicket Post Handshake Message */ #define MBEDTLS_ERR_SSL_BAD_HS_CID_EXT -0x6797 /**< Received invalid CID extension */ +#define MBEDTLS_ERR_SSL_HANDSHAKE_EARLY_RETURN -0x6798 /**< Early return when the client is ready to send early data */ #define MBEDTLS_ERR_LAST 0x7F80 /**< This definition points to the last error code to have a correct parsing in error.c */ @@ -298,8 +299,9 @@ #define MBEDTLS_SSL_EARLY_DATA_DISABLED 0 #define MBEDTLS_SSL_EARLY_DATA_ENABLED 1 -#define MBEDTLS_SSL_EARLY_DATA_OFF 0 -#define MBEDTLS_SSL_EARLY_DATA_ON 1 +#define MBEDTLS_SSL_EARLY_DATA_STATE_DISABLED 0 +#define MBEDTLS_SSL_EARLY_DATA_STATE_OFF 1 /* early_data extension sent, cannot send early_data */ +#define MBEDTLS_SSL_EARLY_DATA_STATE_ON 2 /* early_data extension sent, can send early_data */ #define MBEDTLS_SSL_FORCE_RR_CHECK_OFF 0 #define MBEDTLS_SSL_FORCE_RR_CHECK_ON 1 @@ -1818,12 +1820,6 @@ struct mbedtls_ssl_context size_t early_data_server_buf_len; #endif /* MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_CLI_C) - /* Pointer to early data buffer to send. */ - const unsigned char* early_data_buf; - /* Length of early data to send. */ - size_t early_data_len; -#endif /* MBEDTLS_SSL_CLI_C */ #endif /* MBEDTLS_ZERO_RTT */ #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 5963b8163c77..efc2cdeb0d58 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -831,9 +831,10 @@ struct mbedtls_ssl_handshake_params #if defined(MBEDTLS_ZERO_RTT) mbedtls_ssl_tls1_3_early_secrets early_secrets; - /*!< Early data indication: - 0 -- MBEDTLS_SSL_EARLY_DATA_DISABLED (for no early data), and - 1 -- MBEDTLS_SSL_EARLY_DATA_ENABLED (for use early data) + /*!< Early data state + MBEDTLS_SSL_EARLY_DATA_STATE_DISABLED + MBEDTLS_SSL_EARLY_DATA_STATE_ON + MBEDTLS_SSL_EARLY_DATA_STATE_OFF */ int early_data; #endif /* MBEDTLS_ZERO_RTT */ diff --git a/library/ssl_msg.c b/library/ssl_msg.c index d3c765861085..ffb3039dce7e 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6423,14 +6423,16 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ #endif #if defined(MBEDTLS_ZERO_RTT) - /* TODO: What's the purpose of this check? */ - if( ( ssl->handshake != NULL ) && - ( ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_OFF ) ) + /* Finish handshake if cannot send early data. */ + if( ssl->handshake != NULL && + ( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER || + ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_STATE_ON ) ) #endif /* MBEDTLS_ZERO_RTT */ { if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { - if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) + ret = mbedtls_ssl_handshake( ssl ); + if( ret != 0 && ret != MBEDTLS_ERR_SSL_HANDSHAKE_EARLY_RETURN ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); return( ret ); @@ -6438,6 +6440,20 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ } } +#if defined(MBEDTLS_ZERO_RTT) + if ( ssl->handshake != NULL && + ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_STATE_ON ) + { + ret = mbedtls_ssl_flush_output( ssl ); + if (ret != 0 ) { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); + return ret; + } + MBEDTLS_SSL_DEBUG_MSG( 2, ( "write early_data" ) ); + } +#endif /* MBEDTLS_ZERO_RTT */ + #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) ret = ssl_write_split( ssl, buf, len ); #else diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3872aeec899e..97a4238a4239 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4709,11 +4709,6 @@ int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) ssl_mps_init( ssl ); #endif /* MBEDTLS_SSL_USE_MPS */ -#if defined(MBEDTLS_ZERO_RTT) && defined(MBEDTLS_SSL_CLI_C) - ssl->early_data_buf = NULL; - ssl->early_data_len = 0; -#endif /* MBEDTLS_ZERO_RTT && MBEDTLS_SSL_CLI_C */ - #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ if( ssl->session ) @@ -6499,6 +6494,7 @@ static int ssl_session_load( mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_NEW_SESSION_TICKET) && defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) minor_ver = MBEDTLS_SSL_MINOR_VERSION_4; /* TBD: For testing only */ + session->minor_ver = minor_ver; if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) { diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index b5dc733fca46..6aa81c3a1700 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -106,12 +106,6 @@ static int ssl_write_early_data_coordinate( mbedtls_ssl_context* ssl ); #if defined(MBEDTLS_ZERO_RTT) static int ssl_write_early_data_prepare( mbedtls_ssl_context* ssl ); - -/* Write early-data message */ -static int ssl_write_early_data_write( mbedtls_ssl_context* ssl, - unsigned char* buf, - size_t buflen, - size_t* olen ); #endif /* MBEDTLS_ZERO_RTT */ /* Update the state after handling the outgoing early-data message. */ @@ -124,65 +118,17 @@ static int ssl_write_early_data_postprocess( mbedtls_ssl_context* ssl ); int ssl_write_early_data_process( mbedtls_ssl_context* ssl ) { int ret; -#if defined(MBEDTLS_SSL_USE_MPS) - mbedtls_writer *msg; - unsigned char *buf; - mbedtls_mps_size_t buf_len, msg_len; -#endif /* MBEDTLS_SSL_USE_MPS */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write early data" ) ); + int early_data_status; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> prepare early data" ) ); - MBEDTLS_SSL_PROC_CHK_NEG( ssl_write_early_data_coordinate( ssl ) ); - if( ret == SSL_EARLY_DATA_WRITE ) + early_data_status = ssl_write_early_data_coordinate( ssl ); + if( early_data_status == SSL_EARLY_DATA_WRITE ) { #if defined(MBEDTLS_ZERO_RTT) - MBEDTLS_SSL_PROC_CHK( ssl_write_early_data_prepare( ssl ) ); - -#if defined(MBEDTLS_SSL_USE_MPS) - /* Make sure we can write a new message. */ - MBEDTLS_SSL_PROC_CHK( mbedtls_mps_flush( &ssl->mps.l4 ) ); - - MBEDTLS_SSL_PROC_CHK( mbedtls_mps_write_application( &ssl->mps.l4, - &msg ) ); - - /* Request write-buffer */ - MBEDTLS_SSL_PROC_CHK( mbedtls_writer_get( msg, MBEDTLS_MPS_SIZE_MAX, - &buf, &buf_len ) ); - - MBEDTLS_SSL_PROC_CHK( ssl_write_early_data_write( - ssl, buf, buf_len, &msg_len ) ); - - /* Commit message */ - MBEDTLS_SSL_PROC_CHK( mbedtls_writer_commit_partial( msg, - buf_len - msg_len ) ); - - MBEDTLS_SSL_PROC_CHK( mbedtls_mps_dispatch( &ssl->mps.l4 ) ); - -#else /* MBEDTLS_SSL_USE_MPS */ - - /* Make sure we can write a new message. */ - MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_flush_output( ssl ) ); - - /* Write early-data to message buffer. */ - MBEDTLS_SSL_PROC_CHK( ssl_write_early_data_write( ssl, ssl->out_msg, - MBEDTLS_SSL_MAX_CONTENT_LEN, - &ssl->out_msglen ) ); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; - - /* Dispatch message */ - MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ); - -#endif /* MBEDTLS_SSL_USE_MPS */ - #else /* MBEDTLS_ZERO_RTT */ - ((void) buf); - ((void) buf_len); - ((void) msg); - ((void) msg_len); /* Should never happen */ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - #endif /* MBEDTLS_ZERO_RTT */ } @@ -190,9 +136,15 @@ int ssl_write_early_data_process( mbedtls_ssl_context* ssl ) /* Update state */ MBEDTLS_SSL_PROC_CHK( ssl_write_early_data_postprocess( ssl ) ); +#if defined(MBEDTLS_ZERO_RTT) + if( early_data_status == SSL_EARLY_DATA_WRITE ) { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "return early for 0-RTT" ) ); + ret = MBEDTLS_ERR_SSL_HANDSHAKE_EARLY_RETURN; + } +#endif cleanup: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write early data" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= prepare early data" ) ); return( ret ); } @@ -200,7 +152,7 @@ int ssl_write_early_data_process( mbedtls_ssl_context* ssl ) static int ssl_write_early_data_coordinate( mbedtls_ssl_context* ssl ) { - if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_ON ) + if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_STATE_ON ) return( SSL_EARLY_DATA_SKIP ); return( SSL_EARLY_DATA_WRITE ); @@ -306,34 +258,6 @@ static int ssl_write_early_data_prepare( mbedtls_ssl_context* ssl ) return( 0 ); } -static int ssl_write_early_data_write( mbedtls_ssl_context* ssl, - unsigned char* buf, - size_t buflen, - size_t* olen ) -{ - if( ssl->early_data_len > buflen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return ( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - else - { - memcpy( buf, ssl->early_data_buf, ssl->early_data_len ); - -#if !defined(MBEDTLS_SSL_USE_MPS) - buf[ssl->early_data_len] = MBEDTLS_SSL_MSG_APPLICATION_DATA; - *olen = ssl->early_data_len + 1; - - MBEDTLS_SSL_DEBUG_BUF( 3, "Early Data", ssl->out_msg, *olen ); -#else - *olen = ssl->early_data_len; - MBEDTLS_SSL_DEBUG_BUF( 3, "Early Data", buf, ssl->early_data_len ); -#endif /* MBEDTLS_SSL_USE_MPS */ - } - - return( 0 ); -} - #else /* MBEDTLS_ZERO_RTT */ static int ssl_write_early_data_coordinate( mbedtls_ssl_context* ssl ) @@ -445,7 +369,7 @@ static int ssl_write_end_of_early_data_coordinate( mbedtls_ssl_context* ssl ) ((void) ssl); #if defined(MBEDTLS_ZERO_RTT) - if( ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_ON ) + if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_STATE_DISABLED) { if( ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_ACCEPTED ) return( SSL_END_OF_EARLY_DATA_WRITE ); @@ -2068,10 +1992,10 @@ int ssl_parse_encrypted_extensions_early_data_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_ON ) + if( ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_STATE_DISABLED ) { /* The server must not send the EarlyDataIndication if the - * client hasn't indicated the use of 0-RTT. */ + * client hasn't sent early_data extension. */ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -2099,16 +2023,6 @@ int mbedtls_ssl_get_early_data_status( mbedtls_ssl_context *ssl ) return( ssl->early_data_status ); } -int mbedtls_ssl_set_early_data( mbedtls_ssl_context *ssl, - const unsigned char *buffer, size_t len ) -{ - if( buffer == NULL || len == 0 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->early_data_buf = buffer; - ssl->early_data_len = len; - return( 0 ); -} #endif /* MBEDTLS_ZERO_RTT */ #if ( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) ) @@ -2804,7 +2718,7 @@ static int ssl_encrypted_extensions_parse( mbedtls_ssl_context* ssl, ssl, ext + 4, ext_size ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_parse_early_data_ext", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_parse_encrypted_extensions_early_data_ext", ret ); return( ret ); } break; @@ -2825,6 +2739,13 @@ static int ssl_encrypted_extensions_parse( mbedtls_ssl_context* ssl, } } +#if defined(MBEDTLS_ZERO_RTT) + if( mbedtls_ssl_get_early_data_status(ssl) == MBEDTLS_SSL_EARLY_DATA_REJECTED ) { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "early data rejected by server" ) ); + ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_STATE_OFF; + } +#endif /* MBEDTLS_ZERO_RTT */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse encrypted extension" ) ); return( ret ); @@ -3991,7 +3912,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) ret = ssl_write_early_data_process( ssl ); - if( ret != 0 ) + if( ret != 0 && ret != MBEDTLS_ERR_SSL_HANDSHAKE_EARLY_RETURN ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_early_data_process", ret ); break; @@ -4018,6 +3939,9 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) if( ssl->handshake->hello_retry_requests_received > 0 ) { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello_retry, turn off early_data" ) ); + ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_STATE_OFF; + /* If we received the HRR msg then we send another ClientHello */ #if defined(MBEDTLS_SSL_TLS13_COMPATIBILITY_MODE) /* If not offering early data, the client sends a dummy @@ -4176,6 +4100,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) break; } + ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_STATE_OFF; break; /* ----- WRITE CHANGE CIPHER SPEC ----*/ diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index d57427f1a62f..5e9171068873 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -3092,7 +3092,7 @@ int mbedtls_ssl_write_early_data_ext( mbedtls_ssl_context *ssl, ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "skip write early_data extension" ) ); - ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_OFF; + ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_STATE_DISABLED; return( 0 ); } } @@ -3106,7 +3106,7 @@ int mbedtls_ssl_write_early_data_ext( mbedtls_ssl_context *ssl, ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write early_data extension" ) ); - ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_OFF; + ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_STATE_DISABLED; return( 0 ); } } @@ -3135,7 +3135,7 @@ int mbedtls_ssl_write_early_data_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_SRV_C */ - ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_ON; + ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_STATE_ON; /* Write extension header */ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EARLY_DATA >> 8 ) & 0xFF ); diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 3095753edaeb..3ee58898b6d8 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1792,7 +1792,7 @@ static int ssl_read_end_of_early_data_coordinate( mbedtls_ssl_context* ssl ) #else /* MBEDTLS_ZERO_RTT */ static int ssl_read_end_of_early_data_coordinate( mbedtls_ssl_context* ssl ) { - if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_ON ) + if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_STATE_ON ) return( SSL_END_OF_EARLY_DATA_SKIP ); return( SSL_END_OF_EARLY_DATA_EXPECT ); @@ -1961,7 +1961,7 @@ static int ssl_read_early_data_coordinate( mbedtls_ssl_context* ssl ) { int ret; - if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_ON ) + if( ssl->handshake->early_data != MBEDTLS_SSL_EARLY_DATA_STATE_ON ) return( SSL_EARLY_DATA_SKIP ); /* Activate early data transform */ @@ -2426,7 +2426,7 @@ static int ssl_check_use_0rtt_handshake( mbedtls_ssl_context *ssl ) } /* Accept 0-RTT */ - ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_ON; + ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_STATE_ON; return( 0 ); } #endif /* MBEDTLS_ZERO_RTT*/ @@ -3004,7 +3004,7 @@ static int ssl_client_hello_postprocess( mbedtls_ssl_context* ssl, } #if defined(MBEDTLS_ZERO_RTT) - if( ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_ON ) + if( ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_STATE_ON ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "Generate 0-RTT keys" ) ); diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 3bffc67b2ad7..ebb0b7712100 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -3031,8 +3031,6 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && defined(MBEDTLS_ZERO_RTT) mbedtls_ssl_conf_early_data( &conf, opt.early_data, 0, NULL ); - mbedtls_ssl_set_early_data( &ssl, (const unsigned char*) early_data, - strlen( early_data ) ); #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && MBEDTLS_ZERO_RTT */ if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) @@ -3134,7 +3132,13 @@ int main( int argc, char *argv[] ) while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) { - if( ret != MBEDTLS_ERR_SSL_WANT_READ && + if ( ret == MBEDTLS_ERR_SSL_HANDSHAKE_EARLY_RETURN && + opt.early_data == MBEDTLS_SSL_EARLY_DATA_ENABLED ) + { + ret = mbedtls_ssl_write( &ssl, (const unsigned char*) early_data, strlen(early_data) ); + } + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ) { @@ -4043,12 +4047,6 @@ int main( int argc, char *argv[] ) } #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && defined(MBEDTLS_ZERO_RTT) - mbedtls_ssl_set_early_data( &ssl, (const unsigned char*) early_data, - strlen( early_data ) ); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && MBEDTLS_ZERO_RTT */ - - if( ( ret = mbedtls_net_connect( &server_fd, opt.server_addr, opt.server_port, opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ? @@ -4072,7 +4070,14 @@ int main( int argc, char *argv[] ) while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) { - if( ret != MBEDTLS_ERR_SSL_WANT_READ && + if ( ret == MBEDTLS_ERR_SSL_HANDSHAKE_EARLY_RETURN && + opt.early_data == MBEDTLS_SSL_EARLY_DATA_ENABLED ) + { + ret = mbedtls_ssl_write( &ssl, (const unsigned char*) early_data, strlen(early_data) ); + } + + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ) {