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 |
diff --git a/configs/baremetal.h b/configs/baremetal.h
index c6ba057..37e2444 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 a038121..4487bd7 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 5af2e79..e872840 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 e68eb1c..1d7c05d 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1015,14 +1015,20 @@
* 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 @@
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 @@
* 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 57fe486..093c4ac 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1085,6 +1085,53 @@
* 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 7729cbc..95cf554 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -318,8 +318,11 @@
{
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 @@
* 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 @@
/* 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 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 @@
* 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 @@
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 @@
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 @@
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 @@
}
#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 @@
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 @@
#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 99217ba..e58ddc4 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -2594,6 +2594,30 @@
}
#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 9e9a44b..391513b 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -307,6 +307,13 @@
#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 @@
" 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 @@
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 @@
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 a4624fc..707660f 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -415,6 +415,13 @@
#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 @@
" 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 @@
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 @@
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 )