From 25838b795f79f53d31e3f41bdec191a300cfe3d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 19 Mar 2019 10:23:56 +0100 Subject: [PATCH] Introduce tools for transport-specific code And use those tools in a few places. For now the purpose is just to validate those tools before using them in all occurrences of transport-specific code. The effect of these changes was measured with the following script: ``` set -eu build() { printf "\n$1\n" CC=arm-none-eabi-gcc CFLAGS='-Werror -Os -march=armv6-m -mthumb' \ AR=arm-none-eabi-ar LD=arm-none-eabi-ld make clean lib >/dev/null arm-none-eabi-size -t library/libmbedtls.a } git checkout -- include/mbedtls/config.h scripts/config.pl unset MBEDTLS_NET_C scripts/config.pl unset MBEDTLS_TIMING_C scripts/config.pl unset MBEDTLS_FS_IO scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY build "both" scripts/config.pl unset MBEDTLS_SSL_PROTO_TLS build "DTLS-only" scripts/config.pl set MBEDTLS_SSL_PROTO_TLS scripts/config.pl unset MBEDTLS_SSL_PROTO_DTLS scripts/config.pl unset MBEDTLS_SSL_DTLS_HELLO_VERIFY scripts/config.pl unset MBEDTLS_SSL_DTLS_ANTI_REPLAY scripts/config.pl unset MBEDTLS_SSL_DTLS_BADMAC_LIMIT scripts/config.pl unset MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE build "TLS-only" git checkout -- include/mbedtls/config.h ``` The output of the script is as follows: ``` both text data bss dec hex filename 1820 0 4 1824 720 debug.o (ex library/libmbedtls.a) 0 0 0 0 0 net_sockets.o (ex library/libmbedtls.a) 548 0 0 548 224 ssl_cache.o (ex library/libmbedtls.a) 11155 0 596 11751 2de7 ssl_ciphersuites.o (ex library/libmbedtls.a) 17160 0 0 17160 4308 ssl_cli.o (ex library/libmbedtls.a) 460 0 0 460 1cc ssl_cookie.o (ex library/libmbedtls.a) 17637 0 0 17637 44e5 ssl_srv.o (ex library/libmbedtls.a) 800 0 0 800 320 ssl_ticket.o (ex library/libmbedtls.a) 39322 60 0 39382 99d6 ssl_tls.o (ex library/libmbedtls.a) 88902 60 600 89562 15dda (TOTALS) DTLS-only text data bss dec hex filename 1820 0 4 1824 720 debug.o (ex library/libmbedtls.a) 0 0 0 0 0 net_sockets.o (ex library/libmbedtls.a) 548 0 0 548 224 ssl_cache.o (ex library/libmbedtls.a) 11155 0 596 11751 2de7 ssl_ciphersuites.o (ex library/libmbedtls.a) 17072 0 0 17072 42b0 ssl_cli.o (ex library/libmbedtls.a) 460 0 0 460 1cc ssl_cookie.o (ex library/libmbedtls.a) 17565 0 0 17565 449d ssl_srv.o (ex library/libmbedtls.a) 800 0 0 800 320 ssl_ticket.o (ex library/libmbedtls.a) 38953 60 0 39013 9865 ssl_tls.o (ex library/libmbedtls.a) 88373 60 600 89033 15bc9 (TOTALS) TLS-only text data bss dec hex filename 1820 0 4 1824 720 debug.o (ex library/libmbedtls.a) 0 0 0 0 0 net_sockets.o (ex library/libmbedtls.a) 548 0 0 548 224 ssl_cache.o (ex library/libmbedtls.a) 11155 0 596 11751 2de7 ssl_ciphersuites.o (ex library/libmbedtls.a) 14916 0 0 14916 3a44 ssl_cli.o (ex library/libmbedtls.a) 460 0 0 460 1cc ssl_cookie.o (ex library/libmbedtls.a) 15852 0 0 15852 3dec ssl_srv.o (ex library/libmbedtls.a) 800 0 0 800 320 ssl_ticket.o (ex library/libmbedtls.a) 27623 60 0 27683 6c23 ssl_tls.o (ex library/libmbedtls.a) 73174 60 600 73834 1206a (TOTALS) ``` It can be seen that a DTLS-only build is now starting to be a bit smaller than a dual-mode build, which is the purpose of the new build option. --- include/mbedtls/ssl_internal.h | 61 +++++++++++++++++++++++++++++++--- library/ssl_tls.c | 8 +++-- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 45ea26ae2..173b6d58b 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -264,6 +264,57 @@ #define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) #define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) +/* + * Helpers for code specific to TLS or DTLS. + * + * Goals for these helpers: + * - generate minimal code, eg don't test if mode is DTLS in a DTLS-only build + * - make the flow clear to the compiler, ie that in dual-mode builds, + * when there are two branchs, exactly one of them is taken + * - preserve readability + * + * There are three macros: + * - MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) + * - MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) + * - MBEDTLS_SSL_TRANSPORT_ELSE + * + * The first two are macros rather than static inline functions because some + * compilers (eg arm-none-eabi-gcc 5.4.1 20160919) don't propagate constants + * well enough for us with static inline functions. + * + * Usage 1 (can replace DTLS with TLS): + * #if defined(MBEDTLS_SSL_PROTO_DTLS) + * if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) ) + * // DTLS-specific code + * #endif + * + * Usage 2 (can swap DTLS and TLS); + * #if defined(MBEDTLS_SSL_PROTO_DTLS) + * if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) ) + * // DTLS-specific code + * MBEDTLS_SSL_TRANSPORT_ELSE + * #endif + * #if defined(MBEDTLS_SSL_PROTO_TLS) + * // TLS-specific code + * #endif + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_PROTO_TLS) /* both */ +#define MBEDTLS_SSL_TRANSPORT__BOTH /* shorcut for future tests */ +#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) \ + ( (transport) == MBEDTLS_SSL_TRANSPORT_STREAM ) +#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) \ + ( (transport) == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) +#define MBEDTLS_SSL_TRANSPORT_ELSE else +#elif defined(MBEDTLS_SSL_PROTO_DTLS) /* DTLS only */ +#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) 0 +#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) 1 +#define MBEDTLS_SSL_TRANSPORT_ELSE /* empty: no other branch */ +#else /* TLS only */ +#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) 1 +#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) 0 +#define MBEDTLS_SSL_TRANSPORT_ELSE /* empty: no other branch */ +#endif /* TLS and/or DTLS */ + #ifdef __cplusplus extern "C" { #endif @@ -905,12 +956,14 @@ static inline size_t mbedtls_ssl_out_hdr_len( const mbedtls_ssl_context *ssl ) static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 12 ); -#else +#if !defined(MBEDTLS_SSL_PROTO__BOTH) ((void) ssl); #endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + return( 12 ); +#endif return( 4 ); } diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9afcc96e8..4cfef3f57 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3023,7 +3023,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) } #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) { uint32_t timeout; @@ -3164,8 +3164,9 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) ssl->in_left = ret; } - else -#endif + MBEDTLS_SSL_TRANSPORT_ELSE +#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if defined(MBEDTLS_SSL_PROTO_TLS) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", ssl->in_left, nb_want ) ); @@ -3212,6 +3213,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) ssl->in_left += ret; } } +#endif /* MBEDTLS_SSL_PROTO_TLS */ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );