Add mbedtls_ssl_conf_groups to API

mbedtls_ssl_conf_groups allows supported groups for key
sharing to be configured via their IANA NamedGroup ID.

This is added in anticipation of PQC and Hybrid key
sharing algorithms being integrated into Mbed TLS.

mbedtls_ssl_conf_curves is deprecated in favor of
mbedtls_ssl_conf_groups. handshake_init has been
modified to translate and copy curves configured
via conf_curves into a heap allocatied array of
NamedGroup IDs. This allows the refactoring of code
interacting with conf_curve related variables (such
as curve_list) to use NamedGroup IDs while retaining
the deprecated API.

Signed-off-by: Brett Warren <brett.warren@arm.com>
This commit is contained in:
Brett Warren 2021-08-17 09:53:13 +01:00
parent 36b70b2a4e
commit e0edc8407b
3 changed files with 206 additions and 46 deletions

View file

@ -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.

View file

@ -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 */

View file

@ -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 );
}