diff --git a/configs/baremetal.h b/configs/baremetal.h index c6ba057aa..37e2444c7 100644 --- a/configs/baremetal.h +++ b/configs/baremetal.h @@ -80,6 +80,9 @@ #define MBEDTLS_SSL_DTLS_CONNECTION_ID /* Compile-time fixed parts of the SSL configuration */ +#define MBEDTLS_SSL_CONF_READ_TIMEOUT 0 +#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN 1000 +#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX 16000 #define MBEDTLS_SSL_CONF_CID_LEN 0 #define MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID MBEDTLS_SSL_UNEXPECTED_CID_IGNORE #define MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION \ diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index a03812159..4487bd775 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -638,6 +638,13 @@ #error "MBEDTLS_SSL_CONF_CID_LEN and MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID must be defined simultaneously" #endif +#if ( defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \ + !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) ) || \ + ( !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \ + defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) ) +#error "MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN and MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX must be defined simultaneously" +#endif + #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) #error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 5af2e79d1..e87284017 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -3454,7 +3454,12 @@ //#define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED +/* Timeout */ +//#define MBEDTLS_SSL_CONF_READ_TIMEOUT 0 + /* DTLS-specific settings */ +//#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN +//#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX //#define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED //#define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0 //#define MBEDTLS_SSL_CONF_CID_LEN 0 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index e68eb1c9d..1d7c05d40 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1015,14 +1015,20 @@ struct mbedtls_ssl_config * Numerical settings (int then char) */ +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ +#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ #if defined(MBEDTLS_SSL_PROTO_DTLS) +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) uint32_t hs_timeout_min; /*!< initial value of the handshake retransmission timeout (ms) */ +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) uint32_t hs_timeout_max; /*!< maximum value of the handshake retransmission timeout (ms) */ -#endif +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ #if defined(MBEDTLS_SSL_RENEGOTIATION) int renego_max_records; /*!< grace period for renegotiation */ @@ -1692,6 +1698,7 @@ int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); #endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) /** * \brief Set the timeout period for mbedtls_ssl_read() * (Default: no timeout.) @@ -1705,10 +1712,14 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); * With non-blocking I/O, this will only work if timer * callbacks were set with \c mbedtls_ssl_set_timer_cb(). * + * \note On constrained systems, this option can also be configured + * at compile-time via MBEDTLS_SSL_CONF_READ_TIMEOUT. + * * \note With non-blocking I/O, you may also skip this function * altogether and handle timeouts at the application layer. */ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); +#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ /** * \brief Set the timer callbacks (Mandatory for DTLS.) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 57fe486e0..093c4ac13 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1085,6 +1085,53 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, * be fixed at compile time via one of MBEDTLS_SSL_SSL_CONF_XXX. */ +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) +static inline uint32_t mbedtls_ssl_conf_get_read_timeout( + mbedtls_ssl_config const *conf ) +{ + return( conf->read_timeout ); +} +#else /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ +static inline uint32_t mbedtls_ssl_conf_get_read_timeout( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_READ_TIMEOUT ); +} +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_min( + mbedtls_ssl_config const *conf ) +{ + return( conf->hs_timeout_min ); +} +#else /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_min( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN ); +} +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ + +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_max( + mbedtls_ssl_config const *conf ) +{ + return( conf->hs_timeout_max ); +} +#else /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_max( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ); +} +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) #if !defined(MBEDTLS_SSL_CONF_CID_LEN) static inline size_t mbedtls_ssl_conf_get_cid_len( diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 7729cbca6..95cf554f0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -318,8 +318,11 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) { uint32_t new_timeout; - if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) + if( ssl->handshake->retransmit_timeout >= + mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) ) + { return( -1 ); + } /* Implement the final paragraph of RFC 6347 section 4.1.1.1 * in the following way: after the initial transmission and a first @@ -327,7 +330,8 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) * This value is guaranteed to be deliverable (if not guaranteed to be * delivered) of any compliant IPv4 (and IPv6) network, and should work * on most non-IP stacks too. */ - if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min ) + if( ssl->handshake->retransmit_timeout != + mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ) ) { ssl->handshake->mtu = 508; MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); @@ -337,9 +341,9 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) /* Avoid arithmetic overflow and range overflow */ if( new_timeout < ssl->handshake->retransmit_timeout || - new_timeout > ssl->conf->hs_timeout_max ) + new_timeout > mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) ) { - new_timeout = ssl->conf->hs_timeout_max; + new_timeout = mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ); } ssl->handshake->retransmit_timeout = new_timeout; @@ -351,7 +355,7 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) { - ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; + ssl->handshake->retransmit_timeout = mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", ssl->handshake->retransmit_timeout ) ); } @@ -3011,7 +3015,9 @@ static int ssl_resend_hello_request( mbedtls_ssl_context *ssl ) * timeout if we were using the usual handshake doubling scheme */ if( ssl->conf->renego_max_records < 0 ) { - uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; + uint32_t ratio = + mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) / + mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ) + 1; unsigned char doublings = 1; while( ratio != 0 ) @@ -3152,7 +3158,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) timeout = ssl->handshake->retransmit_timeout; else - timeout = ssl->conf->read_timeout; + timeout = mbedtls_ssl_conf_get_read_timeout( ssl->conf ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) ); @@ -3227,8 +3233,8 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) if( ssl->f_recv_timeout != NULL ) { ret = ssl->f_recv_timeout( ssl->p_bio, - ssl->in_hdr + ssl->in_left, len, - ssl->conf->read_timeout ); + ssl->in_hdr + ssl->in_left, len, + mbedtls_ssl_conf_get_read_timeout( ssl->conf ) ); } else { @@ -8103,13 +8109,27 @@ void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, ssl->disable_datagram_packing = !allow_packing; } +#if !( defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) && \ + defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) ) void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ) { conf->hs_timeout_min = min; conf->hs_timeout_max = max; } -#endif +#else /* !( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN && + MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ) */ +void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, + uint32_t min, uint32_t max ) +{ + ((void) conf); + ((void) min); + ((void) max); +} +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN && + MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ + +#endif /* MBEDTLS_SSL_PROTO_DTLS */ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ) { @@ -8166,10 +8186,12 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ) } #endif +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) { conf->read_timeout = timeout; } +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, void *p_timer, @@ -9932,7 +9954,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) if( ssl->f_get_timer != NULL && ssl->f_get_timer( ssl->p_timer ) == -1 ) { - ssl_set_timer( ssl, ssl->conf->read_timeout ); + ssl_set_timer( ssl, + mbedtls_ssl_conf_get_read_timeout( ssl->conf ) ); } if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) @@ -10784,9 +10807,13 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_SSL_PROTO_DTLS) +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; -#endif +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ #if defined(MBEDTLS_SSL_RENEGOTIATION) conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index 99217ba6b..e58ddc4d5 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -2594,6 +2594,30 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_CONF_AUTHMODE */ +#if defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) + if( strcmp( "MBEDTLS_SSL_CONF_READ_TIMEOUT", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_READ_TIMEOUT ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ + +#if defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) + if( strcmp( "MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ + +#if defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) + if( strcmp( "MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ + #if defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) if( strcmp( "MBEDTLS_SSL_CONF_ANTI_REPLAY", config ) == 0 ) { diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 9e9a44bf3..391513b0c 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -307,6 +307,13 @@ int main( void ) #define USAGE_ALLOW_LEGACY_RENEGO "" #endif +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) +#define USAGE_READ_TIMEOUT \ + " read_timeout=%%d default: 0 ms (no timeout)\n" +#else +#define USAGE_READ_TIMEOUT "" +#endif + #define USAGE \ "\n usage: ssl_client2 param=<>...\n" \ "\n acceptable parameters:\n" \ @@ -325,7 +332,7 @@ int main( void ) " options: 1 (non-blocking), 2 (added delays)\n" \ " event=%%d default: 0 (loop)\n" \ " options: 1 (level-triggered, implies nbio=1),\n" \ - " read_timeout=%%d default: 0 ms (no timeout)\n" \ + USAGE_READ_TIMEOUT \ " max_resend=%%d default: 0 (no resend on timeout)\n" \ "\n" \ USAGE_DTLS \ @@ -921,8 +928,10 @@ int main( int argc, char *argv[] ) if( opt.event < 0 || opt.event > 2 ) goto usage; } +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) else if( strcmp( p, "read_timeout" ) == 0 ) opt.read_timeout = atoi( q ); +#endif else if( strcmp( p, "max_resend" ) == 0 ) { opt.max_resend = atoi( q ); @@ -1769,7 +1778,9 @@ int main( int argc, char *argv[] ) mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); +#endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_conf_session_tickets( &conf, opt.tickets ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index a4624fc78..707660f66 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -415,6 +415,13 @@ int main( void ) #define USAGE_ALLOW_LEGACY_RENEGO "" #endif +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) +#define USAGE_READ_TIMEOUT \ + " read_timeout=%%d default: 0 ms (no timeout)\n" +#else +#define USAGE_READ_TIMEOUT "" +#endif + #define USAGE \ "\n usage: ssl_server2 param=<>...\n" \ "\n acceptable parameters:\n" \ @@ -430,7 +437,7 @@ int main( void ) " options: 1 (non-blocking), 2 (added delays)\n" \ " event=%%d default: 0 (loop)\n" \ " options: 1 (level-triggered, implies nbio=1),\n" \ - " read_timeout=%%d default: 0 ms (no timeout)\n" \ + USAGE_READ_TIMEOUT \ "\n" \ USAGE_DTLS \ USAGE_COOKIES \ @@ -1575,8 +1582,10 @@ int main( int argc, char *argv[] ) if( opt.event < 0 || opt.event > 2 ) goto usage; } +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) else if( strcmp( p, "read_timeout" ) == 0 ) opt.read_timeout = atoi( q ); +#endif else if( strcmp( p, "buffer_size" ) == 0 ) { opt.buffer_size = atoi( q ); @@ -2927,7 +2936,9 @@ reset: goto exit; } +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )