From c1096e7514ae92c9e936977fac63ff61bca11bbf Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 19 Jun 2019 12:30:41 +0100 Subject: [PATCH] Allow hardcoding single supported elliptic curve This commit introduces the option MBEDTLS_SSL_CONF_SINGLE_EC which can be used to register a single supported elliptic curve at compile time. It replaces the runtime configuration API mbedtls_ssl_conf_curves() which allows to register a _list_ of supported elliptic curves. In contrast to other options used to hardcode configuration options, MBEDTLS_SSL_CONF_SINGLE_EC isn't a numeric option, but instead it's only relevant if it's defined or not. To actually set the single elliptic curve that should be supported, numeric options MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID must both be defined and provide the TLS ID and the Mbed TLS internal ID and the chosen curve, respectively. --- configs/baremetal.h | 4 ++++ include/mbedtls/check_config.h | 6 ++++++ include/mbedtls/config.h | 27 +++++++++++++++++++++++++++ include/mbedtls/ssl.h | 8 ++++++++ include/mbedtls/ssl_internal.h | 22 ++++++++++++++++++++++ library/ssl_tls.c | 8 +++++++- programs/ssl/query_config.c | 24 ++++++++++++++++++++++++ programs/ssl/ssl_client2.c | 14 +++++++++----- programs/ssl/ssl_server2.c | 14 +++++++++----- 9 files changed, 116 insertions(+), 11 deletions(-) diff --git a/configs/baremetal.h b/configs/baremetal.h index 2e92e76ac..89f3771c6 100644 --- a/configs/baremetal.h +++ b/configs/baremetal.h @@ -57,6 +57,10 @@ #define MBEDTLS_ECP_MAX_BITS 256 #define MBEDTLS_MPI_MAX_SIZE 32 // 256 bits is 32 bytes +#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 + /* Key exchanges */ #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED #define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 735a1e419..509cfa4f3 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -87,6 +87,12 @@ #error "MBEDTLS_CMAC_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_CONF_SINGLE_EC) && \ + ( !defined(MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID) || \ + !defined(MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID) ) +#error "MBEDTLS_SSL_CONF_SINGLE_EC 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 8290c516d..9443c92a7 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -3652,6 +3652,33 @@ */ //#define MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 +/* Enable support a single elliptic curve fixed + * 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 + * a single elliptic curve to use for all elliptic + * curve operations during the handshake. + * + * If this is set, you must also define the following: + * - MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID + * This must resolve to the Mbed TLS group ID for the elliptic + * curve to use (e.g. MBEDTLS_ECP_DP_SECP256R1_ENABLED); see + * ::mbedtls_ecp_group_id in mbedtls/ecp.h for a complete list + * of curve identifiers. + * - MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID + * This must resolve to the identifier for the elliptic curve + * to use according to the IANA NamedCurve registry: + * https://tools.ietf.org/html/rfc4492#section-5.1 + * + * If defined, this option overwrites the effect of the + * runtime configuration API mbedtls_ssl_conf_curves(). + */ +//#define MBEDTLS_SSL_CONF_SINGLE_EC +//#define MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID +//#define MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID + /* \} SECTION: Compile-time SSL configuration */ /* Target and application specific configurations diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 169e054c0..9937b3052 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1070,7 +1070,9 @@ struct mbedtls_ssl_config #endif #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ +#endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ #endif #if defined(MBEDTLS_DHM_C) @@ -2785,6 +2787,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) /** * \brief Set the allowed curves in order of preference. * (Default: all defined curves.) @@ -2808,12 +2811,17 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, * \note This list should be ordered by decreasing preference * (preferred curve first). * + * \note On highly constrained systems, the support for a single + * fixed elliptic curve can be configured at compile time + * through the option MBEDTLS_SSL_CONF_SINGLE_EC. + * * \param conf SSL configuration * \param curves Ordered list of allowed curves, * terminated by MBEDTLS_ECP_DP_NONE. */ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, const mbedtls_ecp_group_id *curves ); +#endif /* !MBEDTLS_SSL_CONF_SINGLE_EC */ #endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index f7ae62584..9259955ca 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1484,6 +1484,8 @@ static inline unsigned int mbedtls_ssl_conf_get_ems_enforced( #endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) + #define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_TLS_ID( TLS_ID_VAR ) \ { \ mbedtls_ecp_group_id const *__gid; \ @@ -1513,4 +1515,24 @@ static inline unsigned int mbedtls_ssl_conf_get_ems_enforced( } \ } +#else /* !MBEDTLS_SSL_CONF_SINGLE_EC */ + +#define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_TLS_ID( TLS_ID_VAR ) \ + { \ + uint16_t TLS_ID_VAR = MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID; \ + ((void) ssl); + +#define MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_TLS_ID \ + } + +#define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_GRP_ID( EC_ID_VAR ) \ + { \ + mbedtls_ecp_group_id EC_ID_VAR = MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID; \ + ((void) ssl); + +#define MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_GRP_ID \ + } + +#endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ + #endif /* ssl_internal.h */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d669fe77a..5b67d6271 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8616,6 +8616,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) /* * Set the allowed elliptic curves */ @@ -8624,6 +8625,7 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, { conf->curve_list = curve_list; } +#endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ #endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -10840,7 +10842,7 @@ static int ssl_preset_suiteb_hashes[] = { }; #endif -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) MBEDTLS_ECP_DP_SECP256R1, @@ -10983,7 +10985,9 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) conf->curve_list = ssl_preset_suiteb_curves; +#endif #endif break; @@ -11024,8 +11028,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) conf->curve_list = mbedtls_ecp_grp_id_list(); #endif +#endif #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) conf->dhm_min_bitlen = 1024; diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index 574d4d7a5..b9271eac8 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -2778,6 +2778,30 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ +#if defined(MBEDTLS_SSL_CONF_SINGLE_EC) + if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_EC", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_EC ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ + +#if defined(MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID) + if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID */ + +#if defined(MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID) + if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_SINGLE_EC_GRP_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 205f27aae..897c82842 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -215,7 +215,7 @@ int main( void ) #define USAGE_ALPN "" #endif /* MBEDTLS_SSL_ALPN */ -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) #define USAGE_CURVES \ " curves=a,b,c,d default: \"default\" (library default)\n" \ " example: \"secp521r1,brainpoolP512r1\"\n" \ @@ -764,7 +764,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_SSL_ALPN) const char *alpn_list[ALPN_LIST_SIZE]; #endif -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) mbedtls_ecp_group_id curve_list[CURVE_LIST_SIZE]; const mbedtls_ecp_curve_info *curve_cur; #endif @@ -1102,8 +1102,10 @@ int main( int argc, char *argv[] ) default: goto usage; } } +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) else if( strcmp( p, "curves" ) == 0 ) opt.curves = q; +#endif /* !MBEDTLS_SSL_CONF_SINGLE_EC */ else if( strcmp( p, "etm" ) == 0 ) { switch( atoi( q ) ) @@ -1404,7 +1406,7 @@ int main( int argc, char *argv[] ) } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) if( opt.curves != NULL ) { p = (char *) opt.curves; @@ -1458,7 +1460,7 @@ int main( int argc, char *argv[] ) curve_list[i] = MBEDTLS_ECP_DP_NONE; } } -#endif /* MBEDTLS_ECP_C */ +#endif /* MBEDTLS_ECP_C && !MBEDTLS_SSL_CONF_SINGLE_EC */ #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) @@ -1829,12 +1831,14 @@ int main( int argc, char *argv[] ) #endif #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) if( opt.curves != NULL && strcmp( opt.curves, "default" ) != 0 ) { mbedtls_ssl_conf_curves( &conf, curve_list ); } -#endif +#endif /* !MBEDTLS_SSL_CONF_SINGLE_EC */ +#endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len, diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 160997ad7..cfb3d6a3a 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -381,7 +381,7 @@ int main( void ) #define USAGE_ECJPAKE "" #endif -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) #define USAGE_CURVES \ " curves=a,b,c,d default: \"default\" (library default)\n" \ " example: \"secp521r1,brainpoolP512r1\"\n" \ @@ -1412,7 +1412,7 @@ int main( int argc, char *argv[] ) #if defined(SNI_OPTION) sni_entry *sni_info = NULL; #endif -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) mbedtls_ecp_group_id curve_list[CURVE_LIST_SIZE]; const mbedtls_ecp_curve_info * curve_cur; #endif @@ -1694,8 +1694,10 @@ int main( int argc, char *argv[] ) } opt.force_ciphersuite[1] = 0; } +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) else if( strcmp( p, "curves" ) == 0 ) opt.curves = q; +#endif /* !MBEDTLS_SSL_CONF_SINGLE_EC */ else if( strcmp( p, "version_suites" ) == 0 ) opt.version_suites = q; else if( strcmp( p, "renegotiation" ) == 0 ) @@ -2152,7 +2154,7 @@ int main( int argc, char *argv[] ) } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) if( opt.curves != NULL ) { p = (char *) opt.curves; @@ -2206,7 +2208,7 @@ int main( int argc, char *argv[] ) curve_list[i] = MBEDTLS_ECP_DP_NONE; } } -#endif /* MBEDTLS_ECP_C */ +#endif /* MBEDTLS_ECP_C && !MBEDTLS_SSL_CONF_SINGLE_EC */ #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) @@ -2824,12 +2826,14 @@ int main( int argc, char *argv[] ) #endif #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) if( opt.curves != NULL && strcmp( opt.curves, "default" ) != 0 ) { mbedtls_ssl_conf_curves( &conf, curve_list ); } -#endif +#endif /* !MBEDTLS_SSL_CONF_SINGLE_EC */ +#endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) if( strlen( opt.psk ) != 0 && strlen( opt.psk_identity ) != 0 )