From 7f376f4ece7a3e71a51c91f094fe99981ca6f46f Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 12 Jun 2019 16:20:48 +0100 Subject: [PATCH] Allow compile-time configuration of DTLS anti replay Introduce MBEDTLS_SSL_CONF_ANTI_REPLAY to allow configuring the use/nonuse of DTLS anti replay protection at compile-time. Impact on code-size, measured with > ./scripts/baremetal.sh --rom --gcc --armc5 --armc6 | | GCC | ARMC5 | ARMC6 | | --- | --- | --- | --- | | `libmbedtls.a` before | 23559 | 24089 | 27921 | | `libmbedtls.a` after | 23511 | 24049 | 27903 | | gain in Bytes | 48 | 40 | 18 | --- configs/baremetal.h | 1 + include/mbedtls/config.h | 3 +++ include/mbedtls/ssl.h | 16 ++++++++++++---- include/mbedtls/ssl_internal.h | 17 +++++++++++++++++ library/ssl_tls.c | 20 ++++++++++++++------ programs/ssl/query_config.c | 8 ++++++++ programs/ssl/ssl_server2.c | 8 ++++++-- tests/ssl-opt.sh | 7 ++++++- 8 files changed, 67 insertions(+), 13 deletions(-) diff --git a/configs/baremetal.h b/configs/baremetal.h index 330b513fc..2a3e39af7 100644 --- a/configs/baremetal.h +++ b/configs/baremetal.h @@ -80,6 +80,7 @@ #define MBEDTLS_SSL_DTLS_CONNECTION_ID /* Compile-time fixed parts of the SSL configuration */ +#define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED #define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET \ MBEDTLS_SSL_EXTENDED_MS_ENABLED #define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET \ diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 2116521dc..1ff34dc47 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -3450,6 +3450,9 @@ * \{ */ +/* DTLS Anti replay */ +//#define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED + /* ExtendedMasterSecret extension * The following two options must be set/unset simultaneously. */ //#define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MS_ENABLED diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index b51708970..fbc61099f 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1070,8 +1070,10 @@ struct mbedtls_ssl_config #endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */ #endif #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) unsigned int anti_replay : 1; /*!< detect and prevent replay? */ -#endif +#endif /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */ #endif @@ -2016,14 +2018,16 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) /** * \brief Enable or disable anti-replay protection for DTLS. * (DTLS only, no effect on TLS.) * Default: enabled. * * \param conf SSL configuration - * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. + * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or + * MBEDTLS_SSL_ANTI_REPLAY_DISABLED. * * \warning Disabling this is a security risk unless the application * protocol handles duplicated packets in a safe way. You @@ -2031,9 +2035,13 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, * However, if your application already detects duplicated * packets and needs information about them to adjust its * transmission strategy, then you'll want to disable this. + * + * \note On constrained systems, this option can also be + * fixed at compile-time by defining the constant + * MBEDTLS_SSL_CONF_ANTI_REPLAY. */ void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY && !MBEDTLS_SSL_CONF_ANTI_REPLAY */ #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) /** diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 7009c4f8b..092819e31 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1085,6 +1085,23 @@ 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_DTLS_ANTI_REPLAY) +#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) +static inline unsigned int mbedtls_ssl_conf_get_anti_replay( + mbedtls_ssl_config const *conf ) +{ + return( conf->anti_replay ); +} +#else /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ +static inline unsigned int mbedtls_ssl_conf_get_anti_replay( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_ANTI_REPLAY ); +} +#endif /* MBEDTLS_SSL_CONF_ANTI_REPLAY */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ + #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) static inline unsigned int mbedtls_ssl_conf_get_ems( mbedtls_ssl_config const *conf ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fff20ff1b..c70bc21eb 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4322,8 +4322,11 @@ int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ) uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); uint64_t bit; - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + if( mbedtls_ssl_conf_get_anti_replay( ssl->conf ) == + MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + { return( 0 ); + } if( rec_seqnum > ssl->in_window_top ) return( 0 ); @@ -4346,8 +4349,11 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) { uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + if( mbedtls_ssl_conf_get_anti_replay( ssl->conf ) == + MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + { return; + } if( rec_seqnum > ssl->in_window_top ) { @@ -8054,12 +8060,13 @@ void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ) conf->transport = transport; } -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ) { - conf->anti_replay = mode; + conf->anti_replay = mode; } -#endif +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY && !MBEDTLS_SSL_CONF_ANTI_REPLAY */ #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ) @@ -10738,7 +10745,8 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->f_cookie_check = ssl_cookie_check_dummy; #endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; #endif diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index d45a6634f..35b3fe932 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -2578,6 +2578,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_PLATFORM_GMTIME_R_ALT */ +#if defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) + if( strcmp( "MBEDTLS_SSL_CONF_ANTI_REPLAY", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_ANTI_REPLAY ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_ANTI_REPLAY */ + #if defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) if( strcmp( "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET", config ) == 0 ) { diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 5d751b6a7..b76473f01 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -317,7 +317,8 @@ int main( void ) #define USAGE_COOKIES "" #endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) #define USAGE_ANTI_REPLAY \ " anti_replay=0/1 default: (library default: enabled)\n" #else @@ -1889,12 +1890,14 @@ int main( int argc, char *argv[] ) if( opt.cookies < -1 || opt.cookies > 1) goto usage; } +#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) else if( strcmp( p, "anti_replay" ) == 0 ) { opt.anti_replay = atoi( q ); if( opt.anti_replay < 0 || opt.anti_replay > 1) goto usage; } +#endif /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ else if( strcmp( p, "badmac_limit" ) == 0 ) { opt.badmac_limit = atoi( q ); @@ -2580,7 +2583,8 @@ int main( int argc, char *argv[] ) ; /* Nothing to do */ } -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) if( opt.anti_replay != DFL_ANTI_REPLAY ) mbedtls_ssl_conf_dtls_anti_replay( &conf, opt.anti_replay ); #endif diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 7bcba2438..6d71120dc 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -544,6 +544,11 @@ check_cmdline_compat() { "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET" check_cmdline_param_compat "enforce_extended_master_secret" \ "MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET" + + # DTLS anti replay protection configuration + check_cmdline_param_compat "anti_replay" \ + "MBEDTLS_SSL_CONF_ANTI_REPLAY" + } # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]] @@ -7669,7 +7674,7 @@ run_test "DTLS proxy: reference" \ not_with_valgrind # spurious resend due to timeout run_test "DTLS proxy: duplicate every packet" \ -p "$P_PXY duplicate=1" \ - "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \ + "$P_SRV dtls=1 dgram_packing=0 debug_level=2 anti_replay=1" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \ 0 \ -c "replayed record" \