From 56595f4f7b6ba3d0ec4933dd11cb518b8988d893 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 19 Jun 2019 16:31:38 +0100 Subject: [PATCH] Allow hardcoding single signature hash at compile-time This commit introduces the option MBEDTLS_SSL_CONF_SINGLE_HASH which can be used to register a single supported signature hash algorithm at compile time. It replaces the runtime configuration API mbedtls_ssl_conf_sig_hashes() which allows to register a _list_ of supported signature hash algorithms. In contrast to other options used to hardcode configuration options, MBEDTLS_SSL_CONF_SINGLE_HASH isn't a numeric option, but instead it's only relevant if it's defined or not. To actually set the single supported hash algorithm that should be supported, numeric options MBEDTLS_SSL_CONF_SINGLE_HASH_TLS_ID MBEDTLS_SSL_CONF_SINGLE_HASH_MD_ID must both be defined and provide the TLS ID and the Mbed TLS internal ID and the chosen hash algorithm, respectively. --- configs/baremetal.h | 3 +++ include/mbedtls/check_config.h | 6 ++++++ include/mbedtls/config.h | 28 ++++++++++++++++++++++++++++ include/mbedtls/ssl.h | 6 ++++++ include/mbedtls/ssl_internal.h | 23 +++++++++++++++++++++++ library/ssl_tls.c | 16 +++++++++++++--- programs/ssl/ssl_client2.c | 4 ++++ programs/ssl/ssl_server2.c | 7 +++++-- 8 files changed, 88 insertions(+), 5 deletions(-) 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..65819cac7 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 which 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 29729d495..b8875abd4 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1676,6 +1676,8 @@ 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; \ @@ -1701,4 +1703,25 @@ static inline unsigned int mbedtls_ssl_conf_get_ems_enforced( } \ } +#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_tls.c b/library/ssl_tls.c index 9359be6d9..78a15fe0a 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8630,7 +8630,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 */ @@ -10839,6 +10844,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, @@ -10854,6 +10860,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[] = { @@ -10864,12 +10871,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[] = { @@ -11018,8 +11027,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) @@ -11068,8 +11079,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) @@ -11308,9 +11321,6 @@ 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 ) { - if( ssl->conf->sig_hashes == NULL ) - return( -1 ); - MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( md_alg ) if( md_alg == md ) return( 0 ); 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 */