diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index fa2429d07..323ffa90b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -21,6 +21,7 @@ */ #ifndef MBEDTLS_SSL_H #define MBEDTLS_SSL_H +#include "mbedtls/platform_util.h" #include "mbedtls/private_access.h" #include "mbedtls/build_info.h" @@ -187,18 +188,28 @@ * } NamedGroup; * */ + /* Elliptic Curve Groups (ECDHE) */ -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP256R1 0x0017 -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP384R1 0x0018 -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP521R1 0x0019 -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_X25519 0x001D -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_X448 0x001E +#define MBEDTLS_SSL_IANA_TLS_GROUP_NONE 0 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP192K1 0x0012 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP192R1 0x0013 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP224K1 0x0014 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP224R1 0x0015 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP256K1 0x0016 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 0x0017 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 0x0018 +#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1 0x0019 +#define MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1 0x001A +#define MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1 0x001B +#define MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1 0x001C +#define MBEDTLS_SSL_IANA_TLS_GROUP_X25519 0x001D +#define MBEDTLS_SSL_IANA_TLS_GROUP_X448 0x001E /* Finite Field Groups (DHE) */ -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE2048 0x0100 -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE3072 0x0101 -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE4096 0x0102 -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE6144 0x0103 -#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE8192 0x0104 +#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048 0x0100 +#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE3072 0x0101 +#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE4096 0x0102 +#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE6144 0x0103 +#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192 0x0104 /* * TLS 1.3 Key Exchange Modes @@ -1282,10 +1293,12 @@ struct mbedtls_ssl_config #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) const mbedtls_ecp_group_id *MBEDTLS_PRIVATE(curve_list); /*!< allowed curves */ #endif + const uint16_t *MBEDTLS_PRIVATE(group_list); /*!< allowed IANA NamedGroups */ + #if defined(MBEDTLS_DHM_C) mbedtls_mpi MBEDTLS_PRIVATE(dhm_P); /*!< prime modulus for DHM */ mbedtls_mpi MBEDTLS_PRIVATE(dhm_G); /*!< generator for DHM */ @@ -3142,6 +3155,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_DEPRECATED_REMOVED) /** * \brief Set the allowed curves in order of preference. * @@ -3155,6 +3169,8 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, * Both sides: limits the set of curves accepted for use in * ECDHE and in the peer's end-entity certificate. * + * \deprecated Superseeded by mbedtls_ssl_conf_groups(). + * * \note This has no influence on which curves are allowed inside the * certificate chains, see \c mbedtls_ssl_conf_cert_profile() * for that. For the end-entity certificate however, the key @@ -3181,10 +3197,51 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, * \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 ); +void MBEDTLS_DEPRECATED mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, + const mbedtls_ecp_group_id *curves ); +#endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_ECP_C */ +/** + * \brief Set the allowed groups in order of preference. + * + * On server: This only affects the choice of key agreement mechanism + * + * On client: this affects the list of groups offered for any + * use. The server can override our preference order. + * + * Both sides: limits the set of groups accepted for use in + * key sharing. + * + * \note This function replaces the deprecated mbedtls_ssl_conf_curves(), + * which only allows ECP curves to be configured. + * + * \note The most recent invocation of either mbedtls_ssl_conf_curves() + * or mbedtls_ssl_conf_groups() nullifies all previous invocations + * of both. + * + * \note This list should be ordered by decreasing preference + * (preferred group first). + * + * \note When this function is not called, a default list is used, + * consisting of all supported curves at 255 bits and above, + * and all supported finite fields at 2048 bits and above. + * The order favors groups with the lowest resource usage. + * + * \note New minor versions of Mbed TLS will not remove items + * from the default list unless serious security concerns require it. + * New minor versions of Mbed TLS may change the order in + * keeping with the general principle of favoring the lowest + * resource usage. + * + * \param conf SSL configuration + * \param groups List of allowed groups ordered by preference, terminated by 0. + * Must contain valid IANA NamedGroup IDs (provided via either an integer + * or using MBEDTLS_TLS13_NAMED_GROUP_XXX macros). + */ +void mbedtls_ssl_conf_groups( mbedtls_ssl_config *conf, + const uint16_t *groups ); + #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) /** * \brief Set the allowed hashes for signatures during the handshake. diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 9041c51d2..56a5718a6 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -520,6 +520,11 @@ struct mbedtls_ssl_handshake_params int tls1_3_kex_modes; /*!< key exchange modes for TLS 1.3 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + const uint16_t *group_list; + unsigned char group_list_heap_allocated; +#endif + #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */ @@ -1565,17 +1570,17 @@ static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_conf */ static inline int mbedtls_ssl_tls13_named_group_is_ecdhe( uint16_t named_group ) { - return( named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP256R1 || - named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP384R1 || - named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP521R1 || - named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_X25519 || - named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_X448 ); + return( named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 || + named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 || + named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1 || + named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X25519 || + named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X448 ); } static inline int mbedtls_ssl_tls13_named_group_is_dhe( uint16_t named_group ) { - return( named_group >= MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE2048 && - named_group <= MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE8192 ); + return( named_group >= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048 && + named_group <= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192 ); } static inline void mbedtls_ssl_handshake_set_state( mbedtls_ssl_context *ssl, @@ -1638,4 +1643,27 @@ int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl, size_t dst_len, size_t *olen ); +/* + * Return supported groups. + * + * In future, invocations can be changed to ssl->conf->group_list + * when mbedtls_ssl_conf_curves() is deleted. + * + * ssl->handshake->group_list is either a translation of curve_list to IANA TLS group + * identifiers when mbedtls_ssl_conf_curves() has been used, or a pointer to + * ssl->conf->group_list when mbedtls_ssl_conf_groups() has been more recently invoked. + * + */ +static inline const void *mbedtls_ssl_get_groups( const mbedtls_ssl_context *ssl ) +{ + #if defined(MBEDTLS_DEPRECATED_REMOVED) || !defined(MBEDTLS_ECP_C) + return( ssl->conf->group_list ); + #else + if( ( ssl->handshake != NULL ) && ( ssl->handshake->group_list != NULL ) ) + return( ssl->handshake->group_list ); + else + return( ssl->conf->group_list ); + #endif +} + #endif /* ssl_misc.h */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index c5079508e..d604f38ce 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3073,6 +3073,52 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl ) } #endif +/* + * curve_list is translated to IANA TLS group identifiers here because + * mbedtls_ssl_conf_curves returns void and so can't return + * any error codes. + */ +#if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + /* Heap allocate and translate curve_list from internal to IANA group ids */ + if ( ssl->conf->curve_list != NULL ) + { + size_t length; + const mbedtls_ecp_group_id *curve_list = ssl->conf->curve_list; + + for( length = 0; ( curve_list[length] != MBEDTLS_ECP_DP_NONE ) && + ( length < MBEDTLS_ECP_DP_MAX ); length++ ) {} + + /* Leave room for zero termination */ + uint16_t *group_list = mbedtls_calloc( length + 1, sizeof(uint16_t) ); + if ( group_list == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + for( size_t i = 0; i < length; i++ ) + { + const mbedtls_ecp_curve_info *info = + mbedtls_ecp_curve_info_from_grp_id( curve_list[i] ); + if ( info == NULL ) + { + mbedtls_free( group_list ); + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); + } + group_list[i] = info->tls_id; + } + + group_list[length] = 0; + + ssl->handshake->group_list = group_list; + ssl->handshake->group_list_heap_allocated = 1; + } + else + { + ssl->handshake->group_list = ssl->conf->group_list; + ssl->handshake->group_list_heap_allocated = 0; + } +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_ECP_C */ + return( 0 ); } @@ -3928,16 +3974,36 @@ void mbedtls_ssl_conf_sig_algs( mbedtls_ssl_config *conf, #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_DEPRECATED_REMOVED) /* * Set the allowed elliptic curves + * + * mbedtls_ssl_setup() takes the provided list + * and translates it to a list of IANA TLS group identifiers, + * stored in ssl->handshake->group_list. + * */ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, const mbedtls_ecp_group_id *curve_list ) { conf->curve_list = curve_list; + conf->group_list = NULL; } +#endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_ECP_C */ +/* + * Set the allowed groups + */ +void mbedtls_ssl_conf_groups( mbedtls_ssl_config *conf, + const uint16_t *group_list ) +{ +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) + conf->curve_list = NULL; +#endif + conf->group_list = group_list; +} + #if defined(MBEDTLS_X509_CRT_PARSE_C) int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) { @@ -5379,6 +5445,14 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) if( handshake == NULL ) return; +#if defined(MBEDTLS_ECP_C) +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + if ( ssl->handshake->group_list_heap_allocated ) + mbedtls_free( (void*) handshake->group_list ); + handshake->group_list = NULL; +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_ECP_C */ + #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 ) { @@ -6233,41 +6307,39 @@ static int ssl_preset_default_hashes[] = { }; #endif -#if defined(MBEDTLS_ECP_C) /* The selection should be the same as mbedtls_x509_crt_profile_default in * x509_crt.c, plus Montgomery curves for ECDHE. Here, the order matters: * curves with a lower resource usage come first. * See the documentation of mbedtls_ssl_conf_curves() for what we promise * about this list. */ -static mbedtls_ecp_group_id ssl_preset_default_curves[] = { +static uint16_t ssl_preset_default_groups[] = { #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - MBEDTLS_ECP_DP_CURVE25519, + MBEDTLS_SSL_IANA_TLS_GROUP_X25519, #endif #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1, #endif #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - MBEDTLS_ECP_DP_SECP384R1, + MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, #endif #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - MBEDTLS_ECP_DP_CURVE448, + MBEDTLS_SSL_IANA_TLS_GROUP_X448, #endif #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - MBEDTLS_ECP_DP_SECP521R1, + MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1, #endif #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - MBEDTLS_ECP_DP_BP256R1, + MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1, #endif #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - MBEDTLS_ECP_DP_BP384R1, + MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1, #endif #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - MBEDTLS_ECP_DP_BP512R1, + MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1, #endif - MBEDTLS_ECP_DP_NONE + MBEDTLS_SSL_IANA_TLS_GROUP_NONE }; -#endif static int ssl_preset_suiteb_ciphersuites[] = { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, @@ -6314,17 +6386,15 @@ static uint16_t ssl_preset_suiteb_sig_algs[] = { #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif -#if defined(MBEDTLS_ECP_C) -static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { +static uint16_t ssl_preset_suiteb_groups[] = { #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1, #endif #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - MBEDTLS_ECP_DP_SECP384R1, + MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, #endif - MBEDTLS_ECP_DP_NONE + MBEDTLS_SSL_IANA_TLS_GROUP_NONE }; -#endif /* * Load default in mbedtls_ssl_config @@ -6438,9 +6508,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif -#if defined(MBEDTLS_ECP_C) - conf->curve_list = ssl_preset_suiteb_curves; +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) + conf->curve_list = NULL; #endif + conf->group_list = ssl_preset_suiteb_groups; break; /* @@ -6475,9 +6546,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ -#if defined(MBEDTLS_ECP_C) - conf->curve_list = ssl_preset_default_curves; +#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) + conf->curve_list = NULL; #endif + conf->group_list = ssl_preset_default_groups; #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) conf->dhm_min_bitlen = 1024; @@ -6701,14 +6773,17 @@ unsigned char mbedtls_ssl_hash_from_md_alg( int md ) */ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) { - const mbedtls_ecp_group_id *gid; + const uint16_t *group_list = mbedtls_ssl_get_groups( ssl ); - if( ssl->conf->curve_list == NULL ) + if( group_list == NULL ) return( -1 ); + uint16_t tls_id = mbedtls_ecp_curve_info_from_grp_id(grp_id)->tls_id; - for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) - if( *gid == grp_id ) + for( ; *group_list != 0; group_list++ ) + { + if( *group_list == tls_id ) return( 0 ); + } return( -1 ); }