diff --git a/configs/baremetal.h b/configs/baremetal.h index a88f8ac31..aadbd09d5 100644 --- a/configs/baremetal.h +++ b/configs/baremetal.h @@ -60,6 +60,9 @@ #define MBEDTLS_SSL_CONF_SINGLE_EC #define MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID MBEDTLS_ECP_DP_SECP256R1 #define MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID 23 +#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH +#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID MBEDTLS_MD_SHA256 +#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID MBEDTLS_SSL_HASH_SHA256 /* Key exchanges */ #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 93831b76a..576349fbb 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -93,6 +93,12 @@ #error "MBEDTLS_SSL_CONF_SINGLE_EC defined, but not all prerequesites" #endif +#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) && \ + ( !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID) || \ + !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID) ) +#error "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH defined, but not all prerequesites" +#endif + #if defined(MBEDTLS_USE_TINYCRYPT) && defined(MBEDTLS_NO_64BIT_MULTIPLICATION) #error "MBEDTLS_USE_TINYCRYPT defined, but it cannot be defined with MBEDTLS_NO_64BIT_MULTIPLICATION" #endif diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 5b172387e..fb0f26ea9 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -3685,6 +3685,34 @@ //#define MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID //#define MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID +/* Enable support a single signature hash algorithm + * at compile-time, at the benefit of code-size. + * + * On highly constrained systems with large control + * over the configuration of the connection endpoints, + * this option can be used to hardcode the choice of + * hash algorithm to be used for signatures in the + * ServerKeyExchange and CertificateVerify messages. + * + * If this is set, you must also define the following: + * - MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID + * This must resolve to the Mbed TLS hash ID for the hash + * algorithm to use (e.g. MBEDTLS_MD_SHA256). See + * ::mbedtls_md_type_t in mbedtls/md.h for a complete + * list of supported hash algorithm identifiers. + * - MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID + * This must resolve to the TLS identifier for the hash + * algorithm to use. See + * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + * for a list of the supported identifiers. + * + * If defined, this option overwrites the effect of the + * runtime configuration API mbedtls_ssl_conf_sig_hashes(). + */ +//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH +//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID +//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID + /* \} SECTION: Compile-time SSL configuration */ /* Target and application specific configurations diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 0f9ab0ecf..a41182cf4 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1078,7 +1078,9 @@ struct mbedtls_ssl_config #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) const int *sig_hashes; /*!< allowed signature hashes */ +#endif /* !MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ #endif #if defined(MBEDTLS_ECP_C) @@ -2863,6 +2865,10 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, * \note This list should be ordered by decreasing preference * (preferred hash first). * + * \note On highly constrained systems, the support for a single + * fixed signature hash algorithm can be configured at compile + * time through the option MBEDTLS_SSL_CONF_SINGLE_SIG_HASH. + * * \param conf SSL configuration * \param hashes Ordered list of allowed signature hashes, * terminated by \c MBEDTLS_MD_NONE. diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 40391d581..b8875abd4 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1676,4 +1676,52 @@ static inline unsigned int mbedtls_ssl_conf_get_ems_enforced( #endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ +#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) + +#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( MD_VAR ) \ + { \ + int const *__md; \ + for( __md = ssl->conf->sig_hashes; \ + *__md != MBEDTLS_MD_NONE; __md++ ) \ + { \ + mbedtls_md_type_t MD_VAR = (mbedtls_md_type_t) *__md; \ + + #define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH \ + } \ + } + +#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( HASH_VAR ) \ + { \ + int const *__md; \ + for( __md = ssl->conf->sig_hashes; \ + *__md != MBEDTLS_MD_NONE; __md++ ) \ + { \ + unsigned char HASH_VAR; \ + HASH_VAR = mbedtls_ssl_hash_from_md_alg( *__md ); + +#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS \ + } \ + } + +#else /* !MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ + +#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( MD_VAR ) \ + { \ + mbedtls_md_type_t MD_VAR = MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID; \ + ((void) ssl); + +#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH \ + } + +#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( HASH_VAR ) \ + { \ + unsigned char HASH_VAR = MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID; \ + ((void) ssl); + + +#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS \ + } + +#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ + #endif /* ssl_internal.h */ diff --git a/library/ssl_cli.c b/library/ssl_cli.c index e1f3df4cb..3d421556a 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -173,7 +173,6 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t sig_alg_len = 0; - const int *md; #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) unsigned char *sig_alg_list = buf + 6; #endif @@ -188,15 +187,15 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); - for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) - { + MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash ) + ((void) hash); #if defined(MBEDTLS_ECDSA_C) - sig_alg_len += 2; + sig_alg_len += 2; #endif #if defined(MBEDTLS_RSA_C) - sig_alg_len += 2; + sig_alg_len += 2; #endif - } + MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) { @@ -209,17 +208,16 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, */ sig_alg_len = 0; - for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) - { + MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash ) #if defined(MBEDTLS_ECDSA_C) - sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; + sig_alg_list[sig_alg_len++] = hash; + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; #endif #if defined(MBEDTLS_RSA_C) - sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; + sig_alg_list[sig_alg_len++] = hash; + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; #endif - } + MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS /* * enum { diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 8f460ed63..cb88be60d 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -3074,18 +3074,19 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) */ if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) { - const int *cur; - /* * Supported signature algorithms */ - for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) + MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash ) + if( 0 +#if defined(MBEDTLS_SHA512_C) + || hash == MBEDTLS_SSL_HASH_SHA384 +#endif +#if defined(MBEDTLS_SHA256_C) + || hash == MBEDTLS_SSL_HASH_SHA256 +#endif + ) { - unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur ); - - if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) ) - continue; - #if defined(MBEDTLS_RSA_C) p[2 + sa_len++] = hash; p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; @@ -3095,6 +3096,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; #endif } + MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS p[0] = (unsigned char)( sa_len >> 8 ); p[1] = (unsigned char)( sa_len ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d106ca6e7..fc7ece79d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8628,7 +8628,12 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, const int *hashes ) { +#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) conf->sig_hashes = hashes; +#else + ((void) conf); + ((void) hashes); +#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ } #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ @@ -10837,6 +10842,7 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) } #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) static int ssl_preset_default_hashes[] = { #if defined(MBEDTLS_SHA512_C) MBEDTLS_MD_SHA512, @@ -10852,6 +10858,7 @@ static int ssl_preset_default_hashes[] = { MBEDTLS_MD_NONE }; #endif +#endif #if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) static int ssl_preset_suiteb_ciphersuites[] = { @@ -10862,12 +10869,14 @@ static int ssl_preset_suiteb_ciphersuites[] = { #endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) static int ssl_preset_suiteb_hashes[] = { MBEDTLS_MD_SHA256, MBEDTLS_MD_SHA384, MBEDTLS_MD_NONE }; #endif +#endif #if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { @@ -11016,8 +11025,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) conf->sig_hashes = ssl_preset_suiteb_hashes; #endif +#endif #if defined(MBEDTLS_ECP_C) #if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) @@ -11066,8 +11077,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) conf->sig_hashes = ssl_preset_default_hashes; #endif +#endif #if defined(MBEDTLS_ECP_C) #if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) @@ -11306,14 +11319,10 @@ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_i int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, mbedtls_md_type_t md ) { - const int *cur; - - if( ssl->conf->sig_hashes == NULL ) - return( -1 ); - - for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) - if( *cur == (int) md ) - return( 0 ); + MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( md_alg ) + if( md_alg == md ) + return( 0 ); + MBEDTLS_SSL_END_FOR_EACH_SIG_HASH return( -1 ); } @@ -11410,25 +11419,11 @@ 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 ) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_3 ) - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; - switch( md ) { -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_SSL_HASH_MD5: - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_SSL_HASH_SHA1: - ssl->handshake->calc_verify = ssl_calc_verify_tls; - break; -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ #if defined(MBEDTLS_SHA512_C) case MBEDTLS_SSL_HASH_SHA384: ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; @@ -11439,18 +11434,14 @@ int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; break; #endif + default: - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; + return( MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH ); } - return 0; -#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */ - (void) ssl; - (void) md; - - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + 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) diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index ff3078826..6766314a8 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -2834,6 +2834,30 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID */ +#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) + if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_SIG_HASH ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ + +#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID) + if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID */ + +#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID) + if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID */ + /* If the symbol is not found, return an error */ return( 1 ); } diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 87454b2fb..bb84207d8 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -569,6 +569,7 @@ static int my_verify( void *data, mbedtls_x509_crt *crt, return( 0 ); } +#if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) static int ssl_sig_hashes_for_test[] = { #if defined(MBEDTLS_SHA512_C) MBEDTLS_MD_SHA512, @@ -584,6 +585,7 @@ static int ssl_sig_hashes_for_test[] = { #endif MBEDTLS_MD_NONE }; +#endif /* !MBEDTLS_SSL_CONF_SINGLE_HASH */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ /* @@ -1693,7 +1695,9 @@ int main( int argc, char *argv[] ) { crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ); mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test ); +#if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test ); +#endif } mbedtls_ssl_conf_verify( &conf, my_verify, NULL ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 9cca9c4d7..42b9773d5 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1000,7 +1000,8 @@ void term_handler( int sig ) } #endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ + !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) static int ssl_sig_hashes_for_test[] = { #if defined(MBEDTLS_SHA512_C) MBEDTLS_MD_SHA512, @@ -1016,7 +1017,7 @@ static int ssl_sig_hashes_for_test[] = { #endif MBEDTLS_MD_NONE }; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ +#endif /* MBEDTLS_X509_CRT_PARSE_C && !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) */ /** Return true if \p ret is a status code indicating that there is an * operation in progress on an SSL connection, and false if it indicates @@ -2516,7 +2517,9 @@ int main( int argc, char *argv[] ) { crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ); mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test ); +#if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test ); +#endif } #endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index acbf4143e..56db0545b 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -3557,7 +3557,6 @@ run_test "Authentication: client SHA256, server required" \ key_file=data_files/server6.key \ force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" \ 0 \ - -c "Supported Signature Algorithm found: 4," \ -c "Supported Signature Algorithm found: 5," run_test "Authentication: client SHA384, server required" \ @@ -3566,7 +3565,6 @@ run_test "Authentication: client SHA384, server required" \ key_file=data_files/server6.key \ force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \ 0 \ - -c "Supported Signature Algorithm found: 4," \ -c "Supported Signature Algorithm found: 5," requires_config_enabled MBEDTLS_SSL_PROTO_SSL3