From 39c7f7e3de79fb35a2b4de002cb9f65025142e75 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 15 Aug 2019 16:17:34 +0100 Subject: [PATCH 01/13] Remove TLS PRF function pointer from SSL handshake parameters --- include/mbedtls/ssl_internal.h | 3 - library/ssl_tls.c | 141 ++++++++++++++++++++------------- 2 files changed, 87 insertions(+), 57 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 32f593972..54d3bc732 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -502,9 +502,6 @@ struct mbedtls_ssl_handshake_params void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *); void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); - int (*tls_prf)(const unsigned char *, size_t, const char *, - const unsigned char *, size_t, - unsigned char *, size_t); #if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) mbedtls_ssl_ciphersuite_handle_t ciphersuite_info; diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 96276c2b6..8bcad1b55 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -865,10 +865,52 @@ static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char * #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -/* Type for the TLS PRF */ -typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *, - const unsigned char *, size_t, - unsigned char *, size_t); +/* + * Call the appropriate PRF function + */ +MBEDTLS_ALWAYS_INLINE +static inline int ssl_prf( int minor_ver, + mbedtls_md_type_t hash, + const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ +#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C) + (void) hash; +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + return( ssl3_prf( secret, slen, label, random, rlen, dstbuf, dlen ) ); + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) + return( tls1_prf( secret, slen, label, random, rlen, dstbuf, dlen ) ); + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA512_C) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && + hash == MBEDTLS_MD_SHA384 ) + { + return( tls_prf_sha384( secret, slen, label, random, rlen, + dstbuf, dlen ) ); + } + else +#endif +#if defined(MBEDTLS_SHA256_C) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + return( tls_prf_sha256( secret, slen, label, random, rlen, + dstbuf, dlen ) ); + } +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} /* * Populate a transform structure with session keys and all the other @@ -906,7 +948,6 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, #if defined(MBEDTLS_ZLIB_SUPPORT) int compression, #endif - ssl_tls_prf_t tls_prf, const unsigned char randbytes[64], int minor_ver, unsigned endpoint, @@ -1002,7 +1043,10 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, /* * Compute key block using the PRF */ - ret = tls_prf( master, 48, "key expansion", randbytes, 64, keyblk, 256 ); + ret = ssl_prf( minor_ver, + mbedtls_ssl_suite_get_mac( ciphersuite_info ), + master, 48, "key expansion", randbytes, 64, + keyblk, 256 ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); @@ -1304,7 +1348,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, #if defined(MBEDTLS_SSL_PROTO_SSL3) if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - handshake->tls_prf = ssl3_prf; handshake->calc_verify = ssl_calc_verify_ssl; handshake->calc_finished = ssl_calc_finished_ssl; } @@ -1313,7 +1356,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) { - handshake->tls_prf = tls1_prf; handshake->calc_verify = ssl_calc_verify_tls; handshake->calc_finished = ssl_calc_finished_tls; } @@ -1324,7 +1366,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && hash == MBEDTLS_MD_SHA384 ) { - handshake->tls_prf = tls_prf_sha384; handshake->calc_verify = ssl_calc_verify_tls_sha384; handshake->calc_finished = ssl_calc_finished_tls_sha384; } @@ -1333,7 +1374,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, #if defined(MBEDTLS_SHA256_C) if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - handshake->tls_prf = tls_prf_sha256; handshake->calc_verify = ssl_calc_verify_tls_sha256; handshake->calc_finished = ssl_calc_finished_tls_sha256; } @@ -1363,10 +1403,13 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, { int ret; -#if !defined(MBEDTLS_DEBUG_C) && !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - ssl = NULL; /* make sure we don't use it except for debug and EMS */ - (void) ssl; -#endif +/* #if !defined(MBEDTLS_DEBUG_C) && !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) */ +/* ssl = NULL; /\* make sure we don't use it except for debug and EMS *\/ */ +/* (void) ssl; */ +/* #endif */ + + mbedtls_ssl_ciphersuite_handle_t const ciphersuite = + mbedtls_ssl_handshake_get_ciphersuite( handshake ); #if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) if( handshake->resume != 0 ) @@ -1391,18 +1434,22 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret", session_hash, hash_len ); - ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, - "extended master secret", - session_hash, hash_len, - master, 48 ); + ret = ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( ciphersuite ), + handshake->premaster, handshake->pmslen, + "extended master secret", + session_hash, hash_len, + master, 48 ); } else #endif { - ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, - "master secret", - handshake->randbytes, 64, - master, 48 ); + ret = ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( ciphersuite ), + handshake->premaster, handshake->pmslen, + "master secret", + handshake->randbytes, 64, + master, 48 ); } if( ret != 0 ) { @@ -1470,7 +1517,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_ZLIB_SUPPORT) ssl->session_negotiate->compression, #endif - ssl->handshake->tls_prf, ssl->handshake->randbytes, mbedtls_ssl_get_minor_ver( ssl ), mbedtls_ssl_conf_get_endpoint( ssl->conf ), @@ -7517,8 +7563,12 @@ static void ssl_calc_finished_tls( mbedtls_md5_finish_ret( &md5, padbuf ); mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 36, buf, len ); + ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( session ) ) ), + session->master, 48, sender, + padbuf, 36, buf, len ); MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); @@ -7568,8 +7618,12 @@ static void ssl_calc_finished_tls_sha256( mbedtls_sha256_finish_ret( &sha256, padbuf ); - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 32, buf, len ); + ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( session ) ) ), + session->master, 48, sender, + padbuf, 32, buf, len ); MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); @@ -7617,8 +7671,12 @@ static void ssl_calc_finished_tls_sha384( mbedtls_sha512_finish_ret( &sha512, padbuf ); - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 48, buf, len ); + ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( session ) ) ), + session->master, 48, sender, + padbuf, 48, buf, len ); MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); @@ -11386,29 +11444,6 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, return( ssl_session_reset_int( ssl, 0 ) ); } -/* - * Helper to get TLS 1.2 PRF from ciphersuite - * (Duplicates bits of logic from ssl_set_handshake_prfs().) - */ -typedef int (*tls_prf_fn)( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ); -static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id ) -{ - mbedtls_ssl_ciphersuite_handle_t const info = - mbedtls_ssl_ciphersuite_from_id( ciphersuite_id ); - const mbedtls_md_type_t hash = mbedtls_ssl_suite_get_mac( info ); - -#if defined(MBEDTLS_SHA512_C) - if( hash == MBEDTLS_MD_SHA384 ) - return( tls_prf_sha384 ); -#else - (void) hash; -#endif - return( tls_prf_sha256 ); -} - /* * Deserialize context, see mbedtls_ssl_context_save() for format. * @@ -11529,8 +11564,6 @@ static int ssl_context_load( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_ZLIB_SUPPORT) ssl->session->compression, #endif - ssl_tls12prf_from_cs( - mbedtls_ssl_session_get_ciphersuite( ssl->session) ), p, /* currently pointing to randbytes */ MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */ mbedtls_ssl_conf_get_endpoint( ssl->conf ), From c2fb759f3bce1ef3c799e67f3e9838d3c7a639e8 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 15 Aug 2019 16:31:23 +0100 Subject: [PATCH 02/13] Remove TLS calc_finished function pointer from SSL handshake params --- include/mbedtls/ssl_internal.h | 1 - library/ssl_tls.c | 63 +++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 54d3bc732..481a76296 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -501,7 +501,6 @@ struct mbedtls_ssl_handshake_params void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *); - void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); #if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) mbedtls_ssl_ciphersuite_handle_t ciphersuite_info; diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8bcad1b55..beac684f0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -912,6 +912,47 @@ static inline int ssl_prf( int minor_ver, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } +MBEDTLS_ALWAYS_INLINE +static inline int ssl_calc_finished( int minor_ver, + mbedtls_md_type_t hash, + mbedtls_ssl_context *ssl, + unsigned char *buf, + int from ) +{ +#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C) + (void) hash; +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + ssl_calc_finished_ssl( ssl, buf, from ); + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) + ssl_calc_finished_tls( ssl, buf, from ); + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA512_C) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && + hash == MBEDTLS_MD_SHA384 ) + { + ssl_calc_finished_tls_sha384( ssl, buf, from ); + } + else +#endif +#if defined(MBEDTLS_SHA256_C) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + ssl_calc_finished_tls_sha256( ssl, buf, from ); + else +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + + return( 0 ); +} + /* * Populate a transform structure with session keys and all the other * necessary information. @@ -1349,7 +1390,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { handshake->calc_verify = ssl_calc_verify_ssl; - handshake->calc_finished = ssl_calc_finished_ssl; } else #endif @@ -1357,7 +1397,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) { handshake->calc_verify = ssl_calc_verify_tls; - handshake->calc_finished = ssl_calc_finished_tls; } else #endif @@ -1367,7 +1406,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, hash == MBEDTLS_MD_SHA384 ) { handshake->calc_verify = ssl_calc_verify_tls_sha384; - handshake->calc_finished = ssl_calc_finished_tls_sha384; } else #endif @@ -1375,7 +1413,6 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { handshake->calc_verify = ssl_calc_verify_tls_sha256; - handshake->calc_finished = ssl_calc_finished_tls_sha256; } else #endif @@ -7784,8 +7821,13 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) ssl_update_out_pointers( ssl, ssl->transform_negotiate ); - ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, - mbedtls_ssl_conf_get_endpoint( ssl->conf ) ); + ssl_calc_finished( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( + ssl->session_negotiate ) ) ), + ssl, ssl->out_msg + 4, + mbedtls_ssl_conf_get_endpoint( ssl->conf ) ); /* * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites @@ -7921,8 +7963,13 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); - ssl->handshake->calc_finished( ssl, buf, - mbedtls_ssl_conf_get_endpoint( ssl->conf ) ^ 1 ); + ssl_calc_finished( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( + ssl->session_negotiate ) ) ), + ssl, buf, + mbedtls_ssl_conf_get_endpoint( ssl->conf ) ^ 1 ); if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) { From 533f5b1d8dcf6d2a7eda2b836739903d4e47c222 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 15 Aug 2019 16:56:35 +0100 Subject: [PATCH 03/13] Remove ssl_optimize_checksum() This function is called on client-only once the ciphersuite has been chosen and it it is known which digest the client will need for the handshake transcript throughout the handshake, and causes all other unneeded handshake transcripts to be discontinued. (On the server, we cannot call this function because we don't know which hash the client will those in its CertificateVerify message). However, the benefit of this call is marginal, since transcript hash computation is negligible compared to asymmetric crypto, and moreover the handshake transcript contexts for the unused digests are still stored in the SSL handshake parameter structure and not freed until the end of the handshake. Finally, if we're running on a _really_ constrained client, there will be only one hash function enabled anyway, and in this case the checksum optimization has no effect. This commit therefore removes checksum optimization altogether, saving some code on constrained systems. --- library/ssl_cli.c | 1 - library/ssl_tls.c | 75 ++++------------------------------------------- 2 files changed, 6 insertions(+), 70 deletions(-) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index a90303da1..fd59d2c0b 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1823,7 +1823,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - mbedtls_ssl_optimize_checksum( ssl, server_suite_info ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index beac684f0..e5f979d32 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -834,12 +834,8 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen, #endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t ); -#endif +static void ssl_update_checksum( mbedtls_ssl_context *, + const unsigned char *, size_t ); #if defined(MBEDTLS_SSL_PROTO_SSL3) static void ssl_calc_verify_ssl( const mbedtls_ssl_context *, unsigned char *, size_t * ); @@ -853,13 +849,11 @@ static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ) #if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SHA256_C) -static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t ); static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char *, size_t * ); static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); #endif #if defined(MBEDTLS_SHA512_C) -static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t ); static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char *, size_t * ); static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); #endif @@ -7378,40 +7372,11 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) return( 0 ); } -void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info ) -{ - ((void) ciphersuite_info); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_get_minor_ver( ssl ) < MBEDTLS_SSL_MINOR_VERSION_3 ) - ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( mbedtls_ssl_suite_get_mac( ciphersuite_info ) == MBEDTLS_MD_SHA384 ) - ssl->handshake->update_checksum = ssl_update_checksum_sha384; - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( mbedtls_ssl_suite_get_mac( ciphersuite_info ) != MBEDTLS_MD_SHA384 ) - ssl->handshake->update_checksum = ssl_update_checksum_sha256; - else -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return; - } -} - void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) { #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 ); + mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 ); mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 ); #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_2) @@ -7424,8 +7389,8 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ } -static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) +static void ssl_update_checksum( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) { #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) @@ -7442,34 +7407,6 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ } -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); - mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); -} -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); -} -#endif - -#if defined(MBEDTLS_SHA512_C) -static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); -} -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - #if defined(MBEDTLS_SSL_PROTO_SSL3) static void ssl_calc_finished_ssl( mbedtls_ssl_context *ssl, unsigned char *buf, int from ) @@ -8064,7 +8001,7 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - handshake->update_checksum = ssl_update_checksum_start; + handshake->update_checksum = ssl_update_checksum; #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) From 8a4b59049b224ba0d8673c75fcb8f638de17f841 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 15 Aug 2019 17:04:57 +0100 Subject: [PATCH 04/13] Remove checksum update function pointer from SSL handshake params --- include/mbedtls/ssl_internal.h | 4 +++- library/ssl_srv.c | 4 ++-- library/ssl_tls.c | 15 ++++----------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 481a76296..236a1f8e7 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -499,7 +499,6 @@ struct mbedtls_ssl_handshake_params #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *); #if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) @@ -1838,6 +1837,9 @@ static inline int mbedtls_ssl_session_get_compression( #endif } +void mbedtls_ssl_update_checksum( mbedtls_ssl_context *, + const unsigned char *, size_t ); + #define MBEDTLS_SSL_CHK(f) do { if( ( ret = f ) < 0 ) goto cleanup; } while( 0 ) #if defined(MBEDTLS_USE_TINYCRYPT) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index c25482d18..3b9b70e34 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -1138,7 +1138,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) return( ret ); } - ssl->handshake->update_checksum( ssl, buf + 2, n ); + mbedtls_ssl_update_checksum( ssl, buf + 2, n ); buf = ssl->in_msg; n = ssl->in_left - 5; @@ -1523,7 +1523,7 @@ read_record_header: MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len ); - ssl->handshake->update_checksum( ssl, buf, msg_len ); + mbedtls_ssl_update_checksum( ssl, buf, msg_len ); /* * Handshake layer: diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e5f979d32..4e4903fdf 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -834,9 +834,6 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen, #endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -static void ssl_update_checksum( mbedtls_ssl_context *, - const unsigned char *, size_t ); - #if defined(MBEDTLS_SSL_PROTO_SSL3) static void ssl_calc_verify_ssl( const mbedtls_ssl_context *, unsigned char *, size_t * ); static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); @@ -4158,7 +4155,7 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) /* Update running hashes of handshake messages seen */ if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) - ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); + mbedtls_ssl_update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); } /* Either send now, or just save to be sent (and resent) later */ @@ -4615,9 +4612,7 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) mbedtls_ssl_handshake_params * const hs = ssl->handshake; if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) - { - ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); - } + mbedtls_ssl_update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); /* Handshake message is complete, increment counter */ #if defined(MBEDTLS_SSL_PROTO_DTLS) @@ -7389,8 +7384,8 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ } -static void ssl_update_checksum( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) +void mbedtls_ssl_update_checksum( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) { #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) @@ -8001,8 +7996,6 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - handshake->update_checksum = ssl_update_checksum; - #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs ); From 8443491280a81dc53faf056a2f02f2f3d2de0936 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 15 Aug 2019 17:07:52 +0100 Subject: [PATCH 05/13] Make SSL checksum update function inline This saves a few bytes in configurations where only one hash is enabled, and configurations allowing multiple hashes probably don't care about code-size anyway. --- include/mbedtls/ssl_internal.h | 20 ++++++++++++++++++-- library/ssl_tls.c | 18 ------------------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 236a1f8e7..79ddc23ee 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1837,8 +1837,24 @@ static inline int mbedtls_ssl_session_get_compression( #endif } -void mbedtls_ssl_update_checksum( mbedtls_ssl_context *, - const unsigned char *, size_t ); +MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_update_checksum( + mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); + mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} #define MBEDTLS_SSL_CHK(f) do { if( ( ret = f ) < 0 ) goto cleanup; } while( 0 ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4e4903fdf..bbd2e4483 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7384,24 +7384,6 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ } -void mbedtls_ssl_update_checksum( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); - mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) - mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); -#endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - #if defined(MBEDTLS_SSL_PROTO_SSL3) static void ssl_calc_finished_ssl( mbedtls_ssl_context *ssl, unsigned char *buf, int from ) From 2f41b248c1c470da0d1e141d341e0c8cf094d021 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 15 Aug 2019 17:29:43 +0100 Subject: [PATCH 06/13] Remove calc_verify SSL function pointer --- include/mbedtls/ssl_internal.h | 9 +++-- library/ssl_cli.c | 5 ++- library/ssl_srv.c | 13 ++++++- library/ssl_tls.c | 71 +++++++--------------------------- 4 files changed, 34 insertions(+), 64 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 79ddc23ee..536316e67 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -499,8 +499,6 @@ struct mbedtls_ssl_handshake_params #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *); - #if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) mbedtls_ssl_ciphersuite_handle_t ciphersuite_info; #endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ @@ -1006,7 +1004,6 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); unsigned char mbedtls_ssl_hash_from_md_alg( int md ); -int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ); #if defined(MBEDTLS_ECP_C) int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); @@ -1856,6 +1853,12 @@ MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_update_checksum( #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ } +int mbedtls_ssl_calc_verify( int minor_ver, + mbedtls_md_type_t hash, + mbedtls_ssl_context const *ssl, + unsigned char *dst, + size_t *hlen ); + #define MBEDTLS_SSL_CHK(f) do { if( ( ret = f ) < 0 ) goto cleanup; } while( 0 ) #if defined(MBEDTLS_USE_TINYCRYPT) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index fd59d2c0b..4e99a801b 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -3889,7 +3889,10 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) sign: #endif - ssl->handshake->calc_verify( ssl, hash, &hashlen ); + mbedtls_ssl_calc_verify( + mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( ciphersuite_info ), + ssl, hash, &hashlen ); #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 3b9b70e34..39edd834d 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -4524,7 +4524,14 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) */ md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] ); - if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) ) + if( +#if defined(MBEDTLS_SHA512_C) + md_alg != MBEDTLS_MD_SHA384 && +#endif +#if defined(MBEDTLS_SHA256_C) + md_alg != MBEDTLS_MD_SHA256 && +#endif + 1 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" " for verify message" ) ); @@ -4593,7 +4600,9 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) /* Calculate hash and verify signature */ { size_t dummy_hlen; - ssl->handshake->calc_verify( ssl, hash, &dummy_hlen ); + mbedtls_ssl_calc_verify( + mbedtls_ssl_get_minor_ver( ssl ), + md_alg, ssl, hash, &dummy_hlen ); } if( ( ret = mbedtls_pk_verify( peer_pk, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index bbd2e4483..f23b0953e 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1359,19 +1359,11 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, return( 0 ); } -/* - * Set appropriate PRF function and other SSL / TLS 1.0/1.1 / TLS1.2 functions - * - * Inputs: - * - SSL/TLS minor version - * - hash associated with the ciphersuite (only used by TLS 1.2) - * - * Outputs: - * - the tls_prf, calc_verify and calc_finished members of handshake structure - */ -static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, - int minor_ver, - mbedtls_md_type_t hash ) +int mbedtls_ssl_calc_verify( int minor_ver, + mbedtls_md_type_t hash, + mbedtls_ssl_context const *ssl, + unsigned char *dst, + size_t *hlen ) { #if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C) (void) hash; @@ -1379,16 +1371,12 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, #if defined(MBEDTLS_SSL_PROTO_SSL3) if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - handshake->calc_verify = ssl_calc_verify_ssl; - } + ssl_calc_verify_ssl( ssl, dst, hlen ); else #endif #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) - { - handshake->calc_verify = ssl_calc_verify_tls; - } + ssl_calc_verify_tls( ssl, dst, hlen ); else #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_2) @@ -1396,14 +1384,14 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake, if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && hash == MBEDTLS_MD_SHA384 ) { - handshake->calc_verify = ssl_calc_verify_tls_sha384; + ssl_calc_verify_tls_sha384( ssl, dst, hlen ); } else #endif #if defined(MBEDTLS_SHA256_C) if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - handshake->calc_verify = ssl_calc_verify_tls_sha256; + ssl_calc_verify_tls_sha256( ssl, dst, hlen ); } else #endif @@ -1457,7 +1445,10 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, unsigned char session_hash[48]; size_t hash_len; - handshake->calc_verify( ssl, session_hash, &hash_len ); + mbedtls_ssl_calc_verify( + mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( ciphersuite ), + ssl, session_hash, &hash_len ); MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret", session_hash, hash_len ); @@ -1494,21 +1485,9 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) { int ret; - mbedtls_ssl_ciphersuite_handle_t const ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); - /* Set PRF, calc_verify and calc_finished function pointers */ - ret = ssl_set_handshake_prfs( ssl->handshake, - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( ciphersuite_info ) ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_set_handshake_prfs", ret ); - return( ret ); - } - /* Compute master secret if needed */ ret = ssl_compute_master( ssl->handshake, ssl->session_negotiate->master, @@ -12369,30 +12348,6 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, } #endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) -{ - switch( md ) - { -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_SSL_HASH_SHA384: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; - break; -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_SSL_HASH_SHA256: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; - break; -#endif - - default: - return( MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH ); - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, From 8671e7b9f7bea77db5f3bd7dd7705002a28b1781 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Aug 2019 09:55:15 +0100 Subject: [PATCH 07/13] Remove redundant SHA-1 code-path in TLS-1.2 handling of CrtVrfy SHA-1 is no longer offered nor accepted for the client's CertificateVerify message in TLS 1.2. See 0a64170. --- library/ssl_srv.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 39edd834d..b058e7c81 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -4539,11 +4539,6 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) goto exit; } -#if !defined(MBEDTLS_MD_SHA1) - if( MBEDTLS_MD_SHA1 == md_alg ) - hash_start += 16; -#endif - /* Info from md_alg will be used instead */ hashlen = 0; From cf87c5e0a1cbb13ed8ffd1dfb3d5098263058754 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Aug 2019 10:11:21 +0100 Subject: [PATCH 08/13] Avoid forward declarations of calc_verify functions in ssl_tls.c --- library/ssl_tls.c | 276 +++++++++++++++++++++++----------------------- 1 file changed, 136 insertions(+), 140 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index f23b0953e..af330f682 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -835,23 +835,19 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_verify_ssl( const mbedtls_ssl_context *, unsigned char *, size_t * ); static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); #endif #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_verify_tls( const mbedtls_ssl_context *, unsigned char *, size_t * ); static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SHA256_C) -static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char *, size_t * ); static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); #endif #if defined(MBEDTLS_SHA512_C) -static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char *, size_t * ); static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ @@ -1359,6 +1355,142 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, return( 0 ); } +#if defined(MBEDTLS_SSL_PROTO_SSL3) +static inline void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, + unsigned char hash[36], + size_t *hlen ) +{ + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + unsigned char pad_1[48]; + unsigned char pad_2[48]; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + memset( pad_1, 0x36, 48 ); + memset( pad_2, 0x5C, 48 ); + + mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); + mbedtls_md5_update_ret( &md5, pad_1, 48 ); + mbedtls_md5_finish_ret( &md5, hash ); + + mbedtls_md5_starts_ret( &md5 ); + mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); + mbedtls_md5_update_ret( &md5, pad_2, 48 ); + mbedtls_md5_update_ret( &md5, hash, 16 ); + mbedtls_md5_finish_ret( &md5, hash ); + + mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); + mbedtls_sha1_update_ret( &sha1, pad_1, 40 ); + mbedtls_sha1_finish_ret( &sha1, hash + 16 ); + + mbedtls_sha1_starts_ret( &sha1 ); + mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); + mbedtls_sha1_update_ret( &sha1, pad_2, 40 ); + mbedtls_sha1_update_ret( &sha1, hash + 16, 20 ); + mbedtls_sha1_finish_ret( &sha1, hash + 16 ); + + *hlen = 36; + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + return; +} +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +static inline void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl, + unsigned char hash[36], + size_t *hlen ) +{ + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + mbedtls_md5_finish_ret( &md5, hash ); + mbedtls_sha1_finish_ret( &sha1, hash + 16 ); + + *hlen = 36; + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + return; +} +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +static inline void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl, + unsigned char hash[32], + size_t *hlen ) +{ + mbedtls_sha256_context sha256; + + mbedtls_sha256_init( &sha256 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); + + mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); + mbedtls_sha256_finish_ret( &sha256, hash ); + + *hlen = 32; + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_sha256_free( &sha256 ); + + return; +} +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) +static inline void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl, + unsigned char hash[48], + size_t *hlen ) +{ + mbedtls_sha512_context sha512; + + mbedtls_sha512_init( &sha512 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); + + mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); + mbedtls_sha512_finish_ret( &sha512, hash ); + + *hlen = 48; + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_sha512_free( &sha512 ); + + return; +} +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + int mbedtls_ssl_calc_verify( int minor_ver, mbedtls_md_type_t hash, mbedtls_ssl_context const *ssl, @@ -1559,142 +1691,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) return( 0 ); } -#if defined(MBEDTLS_SSL_PROTO_SSL3) -void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, - unsigned char hash[36], - size_t *hlen ) -{ - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char pad_1[48]; - unsigned char pad_2[48]; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - memset( pad_1, 0x36, 48 ); - memset( pad_2, 0x5C, 48 ); - - mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); - mbedtls_md5_update_ret( &md5, pad_1, 48 ); - mbedtls_md5_finish_ret( &md5, hash ); - - mbedtls_md5_starts_ret( &md5 ); - mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); - mbedtls_md5_update_ret( &md5, pad_2, 48 ); - mbedtls_md5_update_ret( &md5, hash, 16 ); - mbedtls_md5_finish_ret( &md5, hash ); - - mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); - mbedtls_sha1_update_ret( &sha1, pad_1, 40 ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - mbedtls_sha1_starts_ret( &sha1 ); - mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); - mbedtls_sha1_update_ret( &sha1, pad_2, 40 ); - mbedtls_sha1_update_ret( &sha1, hash + 16, 20 ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - *hlen = 36; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - return; -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl, - unsigned char hash[36], - size_t *hlen ) -{ - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - mbedtls_md5_finish_ret( &md5, hash ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - *hlen = 36; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - return; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl, - unsigned char hash[32], - size_t *hlen ) -{ - mbedtls_sha256_context sha256; - - mbedtls_sha256_init( &sha256 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); - - mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); - mbedtls_sha256_finish_ret( &sha256, hash ); - - *hlen = 32; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_sha256_free( &sha256 ); - - return; -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl, - unsigned char hash[48], - size_t *hlen ) -{ - mbedtls_sha512_context sha512; - - mbedtls_sha512_init( &sha512 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); - - mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); - mbedtls_sha512_finish_ret( &sha512, hash ); - - *hlen = 48; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_sha512_free( &sha512 ); - - return; -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) { int ret; From fc7429eef401ec3cbf0e02f252e04620cbce3e8c Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Aug 2019 10:12:21 +0100 Subject: [PATCH 09/13] Remove forward declarations of calc_finished functions in ssl_tls.c --- library/ssl_tls.c | 530 ++++++++++++++++++++++------------------------ 1 file changed, 256 insertions(+), 274 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index af330f682..a5bd45819 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -834,24 +834,6 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen, #endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SHA512_C) -static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - /* * Call the appropriate PRF function */ @@ -899,6 +881,262 @@ static inline int ssl_prf( int minor_ver, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } +#if defined(MBEDTLS_SSL_PROTO_SSL3) +static void ssl_calc_finished_ssl( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + const char *sender; + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + + unsigned char padbuf[48]; + unsigned char md5sum[16]; + unsigned char sha1sum[20]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + /* + * SSLv3: + * hash = + * MD5( master + pad2 + + * MD5( handshake + sender + master + pad1 ) ) + * + SHA1( master + pad2 + + * SHA1( handshake + sender + master + pad1 ) ) + */ + +#if !defined(MBEDTLS_MD5_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(MBEDTLS_SHA1_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" + : "SRVR"; + + memset( padbuf, 0x36, 48 ); + + mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 ); + mbedtls_md5_update_ret( &md5, session->master, 48 ); + mbedtls_md5_update_ret( &md5, padbuf, 48 ); + mbedtls_md5_finish_ret( &md5, md5sum ); + + mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 ); + mbedtls_sha1_update_ret( &sha1, session->master, 48 ); + mbedtls_sha1_update_ret( &sha1, padbuf, 40 ); + mbedtls_sha1_finish_ret( &sha1, sha1sum ); + + memset( padbuf, 0x5C, 48 ); + + mbedtls_md5_starts_ret( &md5 ); + mbedtls_md5_update_ret( &md5, session->master, 48 ); + mbedtls_md5_update_ret( &md5, padbuf, 48 ); + mbedtls_md5_update_ret( &md5, md5sum, 16 ); + mbedtls_md5_finish_ret( &md5, buf ); + + mbedtls_sha1_starts_ret( &sha1 ); + mbedtls_sha1_update_ret( &sha1, session->master, 48 ); + mbedtls_sha1_update_ret( &sha1, padbuf , 40 ); + mbedtls_sha1_update_ret( &sha1, sha1sum, 20 ); + mbedtls_sha1_finish_ret( &sha1, buf + 16 ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); + mbedtls_platform_zeroize( md5sum, sizeof( md5sum ) ); + mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_calc_finished_tls( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + unsigned char padbuf[36]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + /* + * TLSv1: + * hash = PRF( master, finished_label, + * MD5( handshake ) + SHA1( handshake ) )[0..11] + */ + +#if !defined(MBEDTLS_MD5_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(MBEDTLS_SHA1_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_md5_finish_ret( &md5, padbuf ); + mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); + + ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( session ) ) ), + session->master, 48, sender, + padbuf, 36, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +static void ssl_calc_finished_tls_sha256( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_sha256_context sha256; + unsigned char padbuf[32]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + mbedtls_sha256_init( &sha256 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); + + mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(MBEDTLS_SHA256_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) + sha256.state, sizeof( sha256.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_sha256_finish_ret( &sha256, padbuf ); + + ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( session ) ) ), + session->master, 48, sender, + padbuf, 32, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_sha256_free( &sha256 ); + + mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) +static void ssl_calc_finished_tls_sha384( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_sha512_context sha512; + unsigned char padbuf[48]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + mbedtls_sha512_init( &sha512 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); + + mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(MBEDTLS_SHA512_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) + sha512.state, sizeof( sha512.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_sha512_finish_ret( &sha512, padbuf ); + + ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), + mbedtls_ssl_suite_get_mac( + mbedtls_ssl_ciphersuite_from_id( + mbedtls_ssl_session_get_ciphersuite( session ) ) ), + session->master, 48, sender, + padbuf, 48, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_sha512_free( &sha512 ); + + mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + MBEDTLS_ALWAYS_INLINE static inline int ssl_calc_finished( int minor_ver, mbedtls_md_type_t hash, @@ -7359,262 +7597,6 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ } -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_finished_ssl( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - - unsigned char padbuf[48]; - unsigned char md5sum[16]; - unsigned char sha1sum[20]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * SSLv3: - * hash = - * MD5( master + pad2 + - * MD5( handshake + sender + master + pad1 ) ) - * + SHA1( master + pad2 + - * SHA1( handshake + sender + master + pad1 ) ) - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); -#endif - -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" - : "SRVR"; - - memset( padbuf, 0x36, 48 ); - - mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_finish_ret( &md5, md5sum ); - - mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf, 40 ); - mbedtls_sha1_finish_ret( &sha1, sha1sum ); - - memset( padbuf, 0x5C, 48 ); - - mbedtls_md5_starts_ret( &md5 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_update_ret( &md5, md5sum, 16 ); - mbedtls_md5_finish_ret( &md5, buf ); - - mbedtls_sha1_starts_ret( &sha1 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf , 40 ); - mbedtls_sha1_update_ret( &sha1, sha1sum, 20 ); - mbedtls_sha1_finish_ret( &sha1, buf + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - mbedtls_platform_zeroize( md5sum, sizeof( md5sum ) ); - mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_finished_tls( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char padbuf[36]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * TLSv1: - * hash = PRF( master, finished_label, - * MD5( handshake ) + SHA1( handshake ) )[0..11] - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); -#endif - -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_md5_finish_ret( &md5, padbuf ); - mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); - - ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( session ) ) ), - session->master, 48, sender, - padbuf, 36, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_calc_finished_tls_sha256( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_sha256_context sha256; - unsigned char padbuf[32]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - mbedtls_sha256_init( &sha256 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); - - mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA256_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) - sha256.state, sizeof( sha256.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_sha256_finish_ret( &sha256, padbuf ); - - ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( session ) ) ), - session->master, 48, sender, - padbuf, 32, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_sha256_free( &sha256 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -static void ssl_calc_finished_tls_sha384( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_sha512_context sha512; - unsigned char padbuf[48]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - mbedtls_sha512_init( &sha512 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); - - mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA512_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) - sha512.state, sizeof( sha512.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_sha512_finish_ret( &sha512, padbuf ); - - ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( session ) ) ), - session->master, 48, sender, - padbuf, 48, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_sha512_free( &sha512 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) ); From 298a47064cef8e99b2d1654a4073a5db566a69d0 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Aug 2019 10:21:32 +0100 Subject: [PATCH 10/13] Force inlining of ssl_populate_transform() if used only once Somehow, at least ARMC5 isn't able to recognize this automatically. Since some of the arguments to ssl_populate_transform() are compile- time constants in reduced configurations, inlining leads to slightly shorter code. --- library/ssl_tls.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index a5bd45819..e94bc6482 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1200,7 +1200,15 @@ static inline int ssl_calc_finished( int minor_ver, * - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg */ -static int ssl_populate_transform( mbedtls_ssl_transform *transform, +/* Force compilers to inline this function if it's used only + * from one place, because at least ARMC5 doesn't do that + * automatically. */ +#if !defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) +MBEDTLS_ALWAYS_INLINE static inline +#else +static +#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ +int ssl_populate_transform( mbedtls_ssl_transform *transform, int ciphersuite, const unsigned char master[48], #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) From 8e7f23a32644652391b710a8d451379c545af884 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Aug 2019 12:12:30 +0100 Subject: [PATCH 11/13] Force inlining of mbedtls_ssl_read/write_version() --- include/mbedtls/ssl_internal.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 536316e67..4af153712 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -58,6 +58,12 @@ #include "tinycrypt/ecc_dh.h" #endif +#if defined(__GNUC__) || defined(__arm__) +#define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline)) +#else +#define MBEDTLS_ALWAYS_INLINE +#endif + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -1177,9 +1183,8 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) */ -static inline void mbedtls_ssl_write_version( int major, int minor, - int transport, - unsigned char ver[2] ) +MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_write_version( + int major, int minor, int transport, unsigned char ver[2] ) { #if !defined(MBEDTLS_SSL_TRANSPORT__BOTH) ((void) transport); @@ -1204,9 +1209,8 @@ static inline void mbedtls_ssl_write_version( int major, int minor, #endif } -static inline void mbedtls_ssl_read_version( int *major, int *minor, - int transport, - const unsigned char ver[2] ) +MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_read_version( + int *major, int *minor, int transport, const unsigned char ver[2] ) { #if !defined(MBEDTLS_SSL_TRANSPORT__BOTH) ((void) transport); @@ -1795,12 +1799,6 @@ static inline unsigned int mbedtls_ssl_conf_get_ems_enforced( #endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ -#if defined(__GNUC__) || defined(__arm__) -#define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline)) -#else -#define MBEDTLS_ALWAYS_INLINE -#endif - /* This internal function can be used to pend a fatal alert for * later delivery. * From 2793f740a9141f2f0ddda974c66521264c15f4a6 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Aug 2019 14:28:43 +0100 Subject: [PATCH 12/13] Forbid inlining of some functions to reduce code-size on ARMC6 Usually, compilers are clever enough to pick the best inlining strategy, but in this instance, it appears that compiling on ARMC6, the compilers inlines xxx_prf_yyy() and xxx_calc_finished_yyy() even though it really shouldn't. Forbid inlining through the use of __attribute__((noinline)). --- include/mbedtls/ssl_internal.h | 2 ++ library/ssl_tls.c | 25 +++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 4af153712..df221fe8b 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -60,8 +60,10 @@ #if defined(__GNUC__) || defined(__arm__) #define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline)) +#define MBEDTLS_NO_INLINE __attribute__((noinline)) #else #define MBEDTLS_ALWAYS_INLINE +#define MBEDTLS_NO_INLINE #endif #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e94bc6482..8d08ce120 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -589,7 +589,7 @@ int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; * Key material generation */ #if defined(MBEDTLS_SSL_PROTO_SSL3) -static int ssl3_prf( const unsigned char *secret, size_t slen, +MBEDTLS_NO_INLINE static int ssl3_prf( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -650,7 +650,7 @@ exit: #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static int tls1_prf( const unsigned char *secret, size_t slen, +MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -812,7 +812,8 @@ static int tls_prf_generic( mbedtls_md_type_t md_type, } #if defined(MBEDTLS_SHA256_C) -static int tls_prf_sha256( const unsigned char *secret, size_t slen, +MBEDTLS_NO_INLINE static int tls_prf_sha256( + const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -823,7 +824,8 @@ static int tls_prf_sha256( const unsigned char *secret, size_t slen, #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) -static int tls_prf_sha384( const unsigned char *secret, size_t slen, +MBEDTLS_NO_INLINE static int tls_prf_sha384( + const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -837,8 +839,7 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen, /* * Call the appropriate PRF function */ -MBEDTLS_ALWAYS_INLINE -static inline int ssl_prf( int minor_ver, +MBEDTLS_ALWAYS_INLINE static inline int ssl_prf( int minor_ver, mbedtls_md_type_t hash, const unsigned char *secret, size_t slen, const char *label, @@ -882,7 +883,7 @@ static inline int ssl_prf( int minor_ver, } #if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_finished_ssl( +MBEDTLS_NO_INLINE static void ssl_calc_finished_ssl( mbedtls_ssl_context *ssl, unsigned char *buf, int from ) { const char *sender; @@ -967,7 +968,7 @@ static void ssl_calc_finished_ssl( #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_finished_tls( +MBEDTLS_NO_INLINE static void ssl_calc_finished_tls( mbedtls_ssl_context *ssl, unsigned char *buf, int from ) { int len = 12; @@ -1031,7 +1032,7 @@ static void ssl_calc_finished_tls( #if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SHA256_C) -static void ssl_calc_finished_tls_sha256( +MBEDTLS_NO_INLINE static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *buf, int from ) { int len = 12; @@ -1084,7 +1085,7 @@ static void ssl_calc_finished_tls_sha256( #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) -static void ssl_calc_finished_tls_sha384( +MBEDTLS_NO_INLINE static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *buf, int from ) { int len = 12; @@ -1137,8 +1138,8 @@ static void ssl_calc_finished_tls_sha384( #endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -MBEDTLS_ALWAYS_INLINE -static inline int ssl_calc_finished( int minor_ver, +MBEDTLS_ALWAYS_INLINE static inline int ssl_calc_finished( + int minor_ver, mbedtls_md_type_t hash, mbedtls_ssl_context *ssl, unsigned char *buf, From f6cc7423aa3a808e8cb4e6a15798e682f6140384 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Aug 2019 14:34:52 +0100 Subject: [PATCH 13/13] Prescribe inlining of tls_prf_generic() The NO_INLINE annotation of tls_prf_sha256() and tls_prf_sha384() from the last commit surprisingly had an influence on ARMC5 compilation in that tls_prf_generic() was no longer automatically inlined into tls_prf_sha256() if only the latter was enabled (and is the point where tls_prf_generic() is called). This commit forces inlining of tls_prf_generic() in this case. --- library/ssl_tls.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8d08ce120..200268d74 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -748,7 +748,12 @@ MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static int tls_prf_generic( mbedtls_md_type_t md_type, +#if !( defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA512_C) ) +MBEDTLS_ALWAYS_INLINE static inline +#else +static +#endif +int tls_prf_generic( mbedtls_md_type_t md_type, const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen,