diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 2d1e5fa2a1..04e43e39d7 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -32,6 +32,8 @@ #error "mbed TLS requires a platform with 8-bit chars" #endif +#include + #if defined(_WIN32) #if !defined(MBEDTLS_PLATFORM_C) #error "MBEDTLS_PLATFORM_C is required on Windows" @@ -849,6 +851,13 @@ #error "MBEDTLS_SSL_EARLY_DATA defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) && \ + ( !defined(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE) || \ + ( MBEDTLS_SSL_MAX_EARLY_DATA_SIZE < 0 ) || \ + ( MBEDTLS_SSL_MAX_EARLY_DATA_SIZE > UINT32_MAX ) ) +#error "MBEDTLS_SSL_MAX_EARLY_DATA_SIZE MUST be defined and in range(0..UINT32_MAX)" +#endif + #if defined(MBEDTLS_SSL_PROTO_DTLS) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_2) #error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 6b2e280d4e..78c3635433 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1673,6 +1673,23 @@ */ //#define MBEDTLS_SSL_EARLY_DATA +/** + * \def MBEDTLS_SSL_MAX_EARLY_DATA_SIZE + * + * The default maximum amount of 0-RTT data. See the documentation of + * \c mbedtls_ssl_tls13_conf_max_early_data_size() for more information. + * + * It must be positive and smaller than UINT32_MAX. + * + * If MBEDTLS_SSL_EARLY_DATA is not defined, this default value does not + * have any impact on the build. + * + * This feature is experimental, not completed and thus not ready for + * production. + * + */ +#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024 + /** * \def MBEDTLS_SSL_PROTO_DTLS * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 05ccee414a..3f48377b6d 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1527,6 +1527,12 @@ struct mbedtls_ssl_config int MBEDTLS_PRIVATE(early_data_enabled); /*!< Early data enablement: * - MBEDTLS_SSL_EARLY_DATA_DISABLED, * - MBEDTLS_SSL_EARLY_DATA_ENABLED */ + +#if defined(MBEDTLS_SSL_SRV_C) + /* The maximum amount of 0-RTT data. RFC 8446 section 4.6.1 */ + uint32_t MBEDTLS_PRIVATE(max_early_data_size); +#endif /* MBEDTLS_SSL_SRV_C */ + #endif /* MBEDTLS_SSL_EARLY_DATA */ #if defined(MBEDTLS_SSL_ALPN) @@ -1964,6 +1970,35 @@ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); */ void mbedtls_ssl_tls13_conf_early_data( mbedtls_ssl_config *conf, int early_data_enabled ); + +#if defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Set the maximum amount of 0-RTT data in bytes + * Default: #MBEDTLS_SSL_MAX_EARLY_DATA_SIZE + * + * This function sets the value of the max_early_data_size + * field of the early data indication extension included in + * the NewSessionTicket messages that the server may send. + * + * The value defines the maximum amount of 0-RTT data + * in bytes that a client will be allowed to send when using + * one of the tickets defined by the NewSessionTicket messages. + * + * \note When resuming a session using a ticket, if the server receives more + * early data than allowed for the ticket, it terminates the connection. + * The maximum amount of 0-RTT data should thus be large enough + * to allow a minimum of early data to be exchanged. + * + * \param[in] conf The SSL configuration to use. + * \param[in] max_early_data_size The maximum amount of 0-RTT data. + * + * \warning This interface is experimental and may change without notice. + * + */ +void mbedtls_ssl_tls13_conf_max_early_data_size( + mbedtls_ssl_config *conf, uint32_t max_early_data_size ); +#endif /* MBEDTLS_SSL_SRV_C */ + #endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA */ #if defined(MBEDTLS_X509_CRT_PARSE_C) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 83f2b3c3ee..332e42872e 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1704,6 +1704,15 @@ void mbedtls_ssl_tls13_conf_early_data( mbedtls_ssl_config *conf, { conf->early_data_enabled = early_data_enabled; } + +#if defined(MBEDTLS_SSL_SRV_C) +void mbedtls_ssl_tls13_conf_max_early_data_size( + mbedtls_ssl_config *conf, uint32_t max_early_data_size ) +{ + conf->max_early_data_size = max_early_data_size; +} +#endif /* MBEDTLS_SSL_SRV_C */ + #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ @@ -5117,6 +5126,15 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_3) + +#if defined(MBEDTLS_SSL_EARLY_DATA) + mbedtls_ssl_tls13_conf_early_data( conf, MBEDTLS_SSL_EARLY_DATA_DISABLED ); +#if defined(MBEDTLS_SSL_SRV_C) + mbedtls_ssl_tls13_conf_max_early_data_size( + conf, MBEDTLS_SSL_MAX_EARLY_DATA_SIZE ); +#endif +#endif /* MBEDTLS_SSL_EARLY_DATA */ + #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_conf_new_session_tickets( conf, MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index d0c41541ef..00624b5653 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -129,6 +129,7 @@ int main( void ) #define DFL_SNI NULL #define DFL_ALPN_STRING NULL #define DFL_CURVES NULL +#define DFL_MAX_EARLY_DATA_SIZE 0 #define DFL_SIG_ALGS NULL #define DFL_DHM_FILE NULL #define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM @@ -424,6 +425,15 @@ int main( void ) #define USAGE_ECJPAKE "" #endif +#if defined(MBEDTLS_SSL_EARLY_DATA) +#define USAGE_EARLY_DATA \ + " max_early_data_size=%%d default: -1 (disabled)\n" \ + " options: -1 (disabled), " \ + " >= 0 (enabled, max amount of early data )\n" +#else +#define USAGE_EARLY_DATA "" +#endif /* MBEDTLS_SSL_EARLY_DATA */ + #if defined(MBEDTLS_ECP_C) #define USAGE_CURVES \ " curves=a,b,c,d default: \"default\" (library default)\n" \ @@ -677,6 +687,7 @@ struct options const char *cid_val_renego; /* the CID to use for incoming messages * after renegotiation */ int reproducible; /* make communication reproducible */ + uint32_t max_early_data_size; /* max amount of early data */ int query_config_mode; /* whether to read config */ int use_srtp; /* Support SRTP */ int force_srtp_profile; /* SRTP protection profile to use or all */ @@ -1535,6 +1546,9 @@ int main( int argc, char *argv[] ) }; #endif /* MBEDTLS_SSL_DTLS_SRTP */ +#if defined(MBEDTLS_SSL_EARLY_DATA) + int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED; +#endif #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); #if defined(MBEDTLS_MEMORY_DEBUG) @@ -1691,6 +1705,7 @@ int main( int argc, char *argv[] ) opt.sni = DFL_SNI; opt.alpn_string = DFL_ALPN_STRING; opt.curves = DFL_CURVES; + opt.max_early_data_size = DFL_MAX_EARLY_DATA_SIZE; opt.sig_algs = DFL_SIG_ALGS; opt.dhm_file = DFL_DHM_FILE; opt.transport = DFL_TRANSPORT; @@ -1881,6 +1896,19 @@ int main( int argc, char *argv[] ) else if( strcmp( p, "sig_algs" ) == 0 ) opt.sig_algs = q; #endif +#if defined(MBEDTLS_SSL_EARLY_DATA) + else if( strcmp( p, "max_early_data_size" ) == 0 ) + { + long long value = atoll( q ); + tls13_early_data_enabled = + value >= 0 ? MBEDTLS_SSL_EARLY_DATA_ENABLED : + MBEDTLS_SSL_EARLY_DATA_DISABLED; + if( tls13_early_data_enabled ) + { + opt.max_early_data_size = atoi( q ); + } + } +#endif /* MBEDTLS_SSL_EARLY_DATA */ else if( strcmp( p, "renegotiation" ) == 0 ) { opt.renegotiation = (atoi( q )) ? @@ -2876,6 +2904,15 @@ int main( int argc, char *argv[] ) if( opt.cert_req_ca_list != DFL_CERT_REQ_CA_LIST ) mbedtls_ssl_conf_cert_req_ca_list( &conf, opt.cert_req_ca_list ); +#if defined(MBEDTLS_SSL_EARLY_DATA) + mbedtls_ssl_tls13_conf_early_data( &conf, tls13_early_data_enabled ); + if( tls13_early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED ) + { + mbedtls_ssl_tls13_conf_max_early_data_size( + &conf, opt.max_early_data_size ); + } +#endif /* MBEDTLS_SSL_EARLY_DATA */ + #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) /* exercise setting DN hints for server certificate request * (Intended for use where the client cert expected has been signed by