Allow configuration of read timeouts at compile-time

Introduces compile-time constants
- MBEDTLS_SSL_CONF_READ_TIMEOUT
- MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN
- MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX
which allow to configure the read timeouts and
minimum/maximum handshake timeout at compile time.

Impact on code-size:

|  | GCC 8.2.1 | ARMC5 5.06 | ARMC6 6.12 |
| --- | --- | --- | --- |
| `libmbedtls.a` before  | 23147 | 23781 | 26703 |
| `libmbedtls.a` after | 23131 | 23753 | 26673 |
| gain in Bytes | 16 | 28 | 30 |
This commit is contained in:
Hanno Becker 2019-06-13 10:14:59 +01:00
parent e0200dad63
commit 1f835fa22b
9 changed files with 161 additions and 15 deletions

View file

@ -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 \

View file

@ -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"

View file

@ -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

View file

@ -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.)

View file

@ -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(

View file

@ -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;

View file

@ -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 )
{

View file

@ -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 );

View file

@ -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 )