Merge pull request #4891 from yuhaoth/pr/enable-key-exchange-in-client-hello

TLS1.3: Client Hello : Add  extensions and test case.
This commit is contained in:
Ronald Cron 2021-09-23 18:45:01 +02:00 committed by GitHub
commit f2cb19f921
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 704 additions and 32 deletions

View file

@ -169,6 +169,37 @@
/** Invalid value in SSL config */ /** Invalid value in SSL config */
#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 #define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80
/*
* TLS 1.3 NamedGroup values
*
* From RF 8446
* enum {
* // Elliptic Curve Groups (ECDHE)
* secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
* x25519(0x001D), x448(0x001E),
* // Finite Field Groups (DHE)
* ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
* ffdhe6144(0x0103), ffdhe8192(0x0104),
* // Reserved Code Points
* ffdhe_private_use(0x01FC..0x01FF),
* ecdhe_private_use(0xFE00..0xFEFF),
* (0xFFFF)
* } 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
/* 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
/* /*
* TLS 1.3 Key Exchange Modes * TLS 1.3 Key Exchange Modes
* *

View file

@ -32,6 +32,8 @@
#include "mbedtls/platform_util.h" #include "mbedtls/platform_util.h"
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "ecdh_misc.h"
#include <string.h> #include <string.h>
/* Parameter validation macros based on platform_util.h */ /* Parameter validation macros based on platform_util.h */
@ -726,4 +728,84 @@ int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
#endif #endif
} }
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
static int ecdh_tls13_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
size_t *olen, int point_format, unsigned char *buf, size_t blen,
int ( *f_rng )( void *, unsigned char *, size_t), void *p_rng )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ctx->grp.pbits == 0 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
f_rng, p_rng ) ) != 0 )
return( ret );
ret = mbedtls_ecp_point_write_binary( &ctx->grp, &ctx->Q, point_format,
olen, buf, blen );
if( ret != 0 )
return( ret );
return( 0 );
}
int mbedtls_ecdh_tls13_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int ( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng )
{
ECDH_VALIDATE_RET( ctx != NULL );
ECDH_VALIDATE_RET( olen != NULL );
ECDH_VALIDATE_RET( buf != NULL );
ECDH_VALIDATE_RET( f_rng != NULL );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( ctx-> restart_enabled )
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
#endif
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
return( ecdh_tls13_make_params_internal( ctx, olen, ctx->point_format,
buf, blen, f_rng, p_rng ) );
#else
switch( ctx->var )
{
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
case MBEDTLS_ECDH_VARIANT_EVEREST:
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_tls13_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
ctx->point_format, buf, blen,
f_rng, p_rng ) );
default:
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
#endif
}
/*
* Setup context without Everest
*/
int mbedtls_ecdh_setup_no_everest( mbedtls_ecdh_context *ctx,
mbedtls_ecp_group_id grp_id )
{
ECDH_VALIDATE_RET( ctx != NULL );
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
return( ecdh_setup_internal( ctx, grp_id ) );
#else
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
ctx->grp_id = grp_id;
ecdh_init_internal( &ctx->ctx.mbed_ecdh );
return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) );
#endif
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
#endif /* MBEDTLS_ECDH_C */ #endif /* MBEDTLS_ECDH_C */

51
library/ecdh_misc.h Normal file
View file

@ -0,0 +1,51 @@
/**
* \file ecdh_misc.h
*
* \brief Internal functions shared by the ECDH module
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 ( the "License" ); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(MBEDTLS_ECDH_MISC_H)
#define MBEDTLS_ECDH_MISC_H
#include "mbedtls/ecdh.h"
#include "mbedtls/ecp.h"
#if defined(MBEDTLS_ECDH_C)
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
/*
* Setup context without Everest
*/
int mbedtls_ecdh_setup_no_everest( mbedtls_ecdh_context *ctx,
mbedtls_ecp_group_id grp_id );
/*
* TLS 1.3 version of mbedtls_ecdh_make_params in ecdh.h
*/
int mbedtls_ecdh_tls13_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int ( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
#endif /* MBEDTLS_ECDH_C */
#endif /* !MBEDTLS_ECDH_MISC_H */

View file

@ -649,6 +649,16 @@ struct mbedtls_ssl_handshake_params
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
mbedtls_ssl_tls_prf_cb *tls_prf; mbedtls_ssl_tls_prf_cb *tls_prf;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
uint16_t offered_group_id; /* The NamedGroup value for the group
* that is being used for ephemeral
* key exchange.
*
* On the client: Defaults to the first
* entry in the client's group list,
* but can be overwritten by the HRR. */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
mbedtls_ssl_ciphersuite_t const *ciphersuite_info; mbedtls_ssl_ciphersuite_t const *ciphersuite_info;
size_t pmslen; /*!< premaster length */ size_t pmslen; /*!< premaster length */
@ -1348,6 +1358,49 @@ void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl );
void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight ); void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight );
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
/*
* Helper functions around key exchange modes.
*/
static inline unsigned mbedtls_ssl_conf_tls13_check_kex_modes( mbedtls_ssl_context *ssl,
int kex_mode_mask )
{
return( ( ssl->conf->tls13_kex_modes & kex_mode_mask ) != 0 );
}
static inline int mbedtls_ssl_conf_tls13_psk_enabled( mbedtls_ssl_context *ssl )
{
return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK ) );
}
static inline int mbedtls_ssl_conf_tls13_psk_ephemeral_enabled( mbedtls_ssl_context *ssl )
{
return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ) );
}
static inline int mbedtls_ssl_conf_tls13_ephemeral_enabled( mbedtls_ssl_context *ssl )
{
return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL ) );
}
static inline int mbedtls_ssl_conf_tls13_some_ephemeral_enabled( mbedtls_ssl_context *ssl )
{
return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL ) );
}
static inline int mbedtls_ssl_conf_tls13_some_psk_enabled( mbedtls_ssl_context *ssl )
{
return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL ) );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
/** /**
* ssl utils functions for checking configuration. * ssl utils functions for checking configuration.
*/ */
@ -1396,6 +1449,24 @@ static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_conf
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
/*
* Helper functions for NamedGroup.
*/
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 );
}
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 );
}
static inline void mbedtls_ssl_handshake_set_state( mbedtls_ssl_context *ssl, static inline void mbedtls_ssl_handshake_set_state( mbedtls_ssl_context *ssl,
mbedtls_ssl_states state ) mbedtls_ssl_states state )
{ {
@ -1430,6 +1501,7 @@ int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
unsigned char *end, unsigned char *end,
size_t *olen); size_t *olen);
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */

View file

@ -27,8 +27,11 @@
#include <string.h> #include <string.h>
#include "mbedtls/debug.h"
#include "mbedtls/error.h"
#include "ssl_misc.h" #include "ssl_misc.h"
#include <mbedtls/debug.h> #include "ecdh_misc.h"
#define CLIENT_HELLO_RANDOM_LEN 32 #define CLIENT_HELLO_RANDOM_LEN 32
@ -52,13 +55,11 @@ static int ssl_tls13_write_supported_versions_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported versions extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported versions extension" ) );
/* /* Check if we have space to write the extension:
* Check space for extension header. * - extension_type (2 bytes)
* * - extension_data_length (2 bytes)
* extension_type 2 * - versions_length (1 byte )
* extension_data_length 2 * - versions (2 bytes)
* version_length 1
* versions 2
*/ */
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 7 ); MBEDTLS_SSL_CHK_BUF_PTR( p, end, 7 );
@ -93,35 +94,366 @@ static int ssl_tls13_write_supported_versions_ext( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Functions for writing supported_groups extension.
*
* Stucture of supported_groups:
* enum {
* secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
* x25519(0x001D), x448(0x001E),
* ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
* ffdhe6144(0x0103), ffdhe8192(0x0104),
* ffdhe_private_use(0x01FC..0x01FF),
* ecdhe_private_use(0xFE00..0xFEFF),
* (0xFFFF)
* } NamedGroup;
* struct {
* NamedGroup named_group_list<2..2^16-1>;
* } NamedGroupList;
*/
#if defined(MBEDTLS_ECDH_C)
/*
* In versions of TLS prior to TLS 1.3, this extension was named
* 'elliptic_curves' and only contained elliptic curve groups.
*/
static int ssl_tls13_write_named_group_list_ecdhe( mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *olen )
{
unsigned char *p = buf;
*olen = 0;
if( ssl->conf->curve_list == NULL )
return( MBEDTLS_ERR_SSL_BAD_CONFIG );
for ( const mbedtls_ecp_group_id *grp_id = ssl->conf->curve_list;
*grp_id != MBEDTLS_ECP_DP_NONE;
grp_id++ )
{
const mbedtls_ecp_curve_info *info;
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
if( info == NULL )
continue;
if( !mbedtls_ssl_tls13_named_group_is_ecdhe( info->tls_id ) )
continue;
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2);
MBEDTLS_PUT_UINT16_BE( info->tls_id, p, 0 );
p += 2;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "NamedGroup: %s ( %x )",
mbedtls_ecp_curve_info_from_tls_id( info->tls_id )->name,
info->tls_id ) );
}
*olen = p - buf;
return( 0 );
}
#else
static int ssl_tls13_write_named_group_list_ecdhe( mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *olen )
{
((void) ssl);
((void) buf);
((void) end);
*olen = 0;
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
#endif /* MBEDTLS_ECDH_C */
static int ssl_tls13_write_named_group_list_dhe( mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *olen )
{
((void) ssl);
((void) buf);
((void) end);
*olen = 0;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "write_named_group_dhe is not implemented" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
static int ssl_tls13_write_supported_groups_ext( mbedtls_ssl_context *ssl, static int ssl_tls13_write_supported_groups_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
unsigned char *end, unsigned char *end,
size_t *olen ) size_t *olen )
{ {
((void) ssl); unsigned char *p = buf ;
((void) buf); unsigned char *named_group_list_ptr; /* Start of named_group_list */
((void) end); size_t named_group_list_len; /* Length of named_group_list */
((void) olen); size_t output_len = 0;
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); int ret_ecdhe, ret_dhe;
*olen = 0;
if( !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
return( 0 );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_groups extension" ) );
/* Check if we have space for header and length fields:
* - extension_type (2 bytes)
* - extension_data_length (2 bytes)
* - named_group_list_length (2 bytes)
*/
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
p += 6;
named_group_list_ptr = p;
ret_ecdhe = ssl_tls13_write_named_group_list_ecdhe( ssl, p, end, &output_len );
if( ret_ecdhe != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_named_group_list_ecdhe", ret_ecdhe );
}
p += output_len;
ret_dhe = ssl_tls13_write_named_group_list_dhe( ssl, p, end, &output_len );
if( ret_dhe != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_named_group_list_dhe", ret_dhe );
}
p += output_len;
/* Both ECDHE and DHE failed. */
if( ret_ecdhe != 0 && ret_dhe != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Both ECDHE and DHE groups are fail. " ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
/* Length of named_group_list*/
named_group_list_len = p - named_group_list_ptr;
if( named_group_list_len == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "No group available." ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
/* Write extension_type */
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_GROUPS, buf, 0 );
/* Write extension_data_length */
MBEDTLS_PUT_UINT16_BE( named_group_list_len + 2, buf, 2 );
/* Write length of named_group_list */
MBEDTLS_PUT_UINT16_BE( named_group_list_len, buf, 4 );
MBEDTLS_SSL_DEBUG_BUF( 3, "Supported groups extension", buf + 4, named_group_list_len + 2 );
*olen = p - buf;
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
return( 0 );
} }
static int ssl_tls13_write_key_shares_ext( mbedtls_ssl_context *ssl, /*
unsigned char *buf, * Functions for writing key_share extension.
unsigned char *end, */
size_t *olen ) #if defined(MBEDTLS_ECDH_C)
static int ssl_tls13_generate_and_write_ecdh_key_exchange(
mbedtls_ssl_context *ssl,
uint16_t named_group,
unsigned char *buf,
unsigned char *end,
size_t *olen )
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_tls_id( named_group );
if( curve_info == NULL )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "offer curve %s", curve_info->name ) );
if( ( ret = mbedtls_ecdh_setup_no_everest( &ssl->handshake->ecdh_ctx,
curve_info->grp_id ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_setup_no_everest", ret );
return( ret );
}
ret = mbedtls_ecdh_tls13_make_params( &ssl->handshake->ecdh_ctx, olen,
buf, end - buf,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_tls13_make_params", ret );
return( ret );
}
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
return( 0 );
}
#endif /* MBEDTLS_ECDH_C */
static int ssl_tls13_get_default_group_id( mbedtls_ssl_context *ssl,
uint16_t *group_id )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
#if defined(MBEDTLS_ECDH_C)
/* Pick first available ECDHE group compatible with TLS 1.3 */
if( ssl->conf->curve_list == NULL )
return( MBEDTLS_ERR_SSL_BAD_CONFIG );
for ( const mbedtls_ecp_group_id *grp_id = ssl->conf->curve_list;
*grp_id != MBEDTLS_ECP_DP_NONE;
grp_id++ )
{
const mbedtls_ecp_curve_info *info;
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
if( info != NULL &&
mbedtls_ssl_tls13_named_group_is_ecdhe( info->tls_id ) )
{
*group_id = info->tls_id;
return( 0 );
}
}
#else
((void) ssl); ((void) ssl);
((void) buf); ((void) group_id);
((void) end); #endif /* MBEDTLS_ECDH_C */
((void) olen);
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); /*
* Add DHE named groups here.
* Pick first available DHE group compatible with TLS 1.3
*/
return( ret );
}
/*
* ssl_tls13_write_key_share_ext
*
* Structure of key_share extension in ClientHello:
*
* struct {
* NamedGroup group;
* opaque key_exchange<1..2^16-1>;
* } KeyShareEntry;
* struct {
* KeyShareEntry client_shares<0..2^16-1>;
* } KeyShareClientHello;
*/
static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *olen )
{
unsigned char *p = buf;
unsigned char *client_shares_ptr; /* Start of client_shares */
size_t client_shares_len; /* Length of client_shares */
uint16_t group_id;
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
*olen = 0;
if( !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
return( 0 );
/* Check if we have space for header and length fields:
* - extension_type (2 bytes)
* - extension_data_length (2 bytes)
* - client_shares_length (2 bytes)
*/
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
p += 6;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello: adding key share extension" ) );
/* HRR could already have requested something else. */
group_id = ssl->handshake->offered_group_id;
if( !mbedtls_ssl_tls13_named_group_is_ecdhe( group_id ) &&
!mbedtls_ssl_tls13_named_group_is_dhe( group_id ) )
{
MBEDTLS_SSL_PROC_CHK( ssl_tls13_get_default_group_id( ssl,
&group_id ) );
}
/*
* Dispatch to type-specific key generation function.
*
* So far, we're only supporting ECDHE. With the introduction
* of PQC KEMs, we'll want to have multiple branches, one per
* type of KEM, and dispatch to the corresponding crypto. And
* only one key share entry is allowed.
*/
client_shares_ptr = p;
#if defined(MBEDTLS_ECDH_C)
if( mbedtls_ssl_tls13_named_group_is_ecdhe( group_id ) )
{
/* Pointer to group */
unsigned char *group_ptr = p;
/* Length of key_exchange */
size_t key_exchange_len;
/* Check there is space for header of KeyShareEntry
* - group (2 bytes)
* - key_exchange_length (2 bytes)
*/
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
p += 4;
ret = ssl_tls13_generate_and_write_ecdh_key_exchange( ssl, group_id,
p, end,
&key_exchange_len );
p += key_exchange_len;
if( ret != 0 )
return( ret );
/* Write group */
MBEDTLS_PUT_UINT16_BE( group_id, group_ptr, 0 );
/* Write key_exchange_length */
MBEDTLS_PUT_UINT16_BE( key_exchange_len, group_ptr, 2 );
}
else
#endif /* MBEDTLS_ECDH_C */
if( 0 /* other KEMs? */ )
{
/* Do something */
}
else
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
/* Length of client_shares */
client_shares_len = p - client_shares_ptr;
if( client_shares_len == 0)
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "No key share defined." ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
/* Write extension_type */
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_KEY_SHARE, buf, 0 );
/* Write extension_data_length */
MBEDTLS_PUT_UINT16_BE( client_shares_len + 2, buf, 2 );
/* Write client_shares_length */
MBEDTLS_PUT_UINT16_BE( client_shares_len, buf, 4 );
/* Update offered_group_id field */
ssl->handshake->offered_group_id = group_id;
/* Output the total length of key_share extension. */
*olen = p - buf;
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, key_share extension", buf, *olen );
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
cleanup:
return( ret );
} }
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/*
* Functions for writing ClientHello message.
*/
/* Write cipher_suites /* Write cipher_suites
* CipherSuite cipher_suites<2..2^16-2>; * CipherSuite cipher_suites<2..2^16-2>;
*/ */
@ -311,7 +643,7 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl,
* 3) Or, in case all ciphers are supported ( which includes #1 and #2 * 3) Or, in case all ciphers are supported ( which includes #1 and #2
* from above ) * from above )
*/ */
ret = ssl_tls13_write_key_shares_ext( ssl, p, end, &output_len ); ret = ssl_tls13_write_key_share_ext( ssl, p, end, &output_len );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
p += output_len; p += output_len;
@ -340,7 +672,7 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl,
return( 0 ); return( 0 );
} }
static int ssl_tls13_finalize_client_hello( mbedtls_ssl_context* ssl ) static int ssl_tls13_finalize_client_hello( mbedtls_ssl_context *ssl )
{ {
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_HELLO ); mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_HELLO );
return( 0 ); return( 0 );

View file

@ -24,6 +24,7 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include "ssl_misc.h" #include "ssl_misc.h"
@ -99,17 +100,70 @@ void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
* *
* Only if we handle at least one key exchange that needs signatures. * Only if we handle at least one key exchange that needs signatures.
*/ */
int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl, int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
unsigned char *end, unsigned char *end,
size_t *olen ) size_t *olen )
{ {
((void) ssl); unsigned char *p = buf;
((void) buf); unsigned char *supported_sig_alg_ptr; /* Start of supported_signature_algorithms */
((void) end); size_t supported_sig_alg_len = 0; /* Length of supported_signature_algorithms */
((void) olen);
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); *olen = 0;
/* Skip the extension on the client if all allowed key exchanges
* are PSK-based. */
#if defined(MBEDTLS_SSL_CLI_C)
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
!mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
{
return( 0 );
}
#endif /* MBEDTLS_SSL_CLI_C */
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding signature_algorithms extension" ) );
/* Check if we have space for header and length field:
* - extension_type (2 bytes)
* - extension_data_length (2 bytes)
* - supported_signature_algorithms_length (2 bytes)
*/
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
p += 6;
/*
* Write supported_signature_algorithms
*/
supported_sig_alg_ptr = p;
for( const uint16_t *sig_alg = ssl->conf->tls13_sig_algs;
*sig_alg != MBEDTLS_TLS13_SIG_NONE; sig_alg++ )
{
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
MBEDTLS_PUT_UINT16_BE( *sig_alg, p, 0 );
p += 2;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "signature scheme [%x]", *sig_alg ) );
}
/* Length of supported_signature_algorithms */
supported_sig_alg_len = p - supported_sig_alg_ptr;
if( supported_sig_alg_len == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "No signature algorithms defined." ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
/* Write extension_type */
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, buf, 0 );
/* Write extension_data_length */
MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len + 2, buf, 2 );
/* Write length of supported_signature_algorithms */
MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len, buf, 4 );
/* Output the total length of signature algorithms extension. */
*olen = p - buf;
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
return( 0 );
} }
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */

View file

@ -2565,6 +2565,8 @@ component_test_tls13_experimental () {
make make
msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, without padding" msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, without padding"
make test make test
msg "ssl-opt.sh (TLS 1.3 experimental)"
if_build_succeeded tests/ssl-opt.sh
} }
component_test_tls13_experimental_with_padding () { component_test_tls13_experimental_with_padding () {
@ -2579,6 +2581,31 @@ component_test_tls13_experimental_with_padding () {
if_build_succeeded tests/ssl-opt.sh if_build_succeeded tests/ssl-opt.sh
} }
component_test_tls13_experimental_with_ecp_restartable () {
msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with ecp_restartable"
scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
scripts/config.py set MBEDTLS_ECP_RESTARTABLE
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with ecp_restartable"
make test
msg "ssl-opt.sh (TLS 1.3 experimental)"
if_build_succeeded tests/ssl-opt.sh
}
component_test_tls13_experimental_with_everest () {
msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with Everest"
scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with Everest"
make test
msg "ssl-opt.sh (TLS 1.3 experimental)"
if_build_succeeded tests/ssl-opt.sh
}
component_build_mingw () { component_build_mingw () {
msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs

View file

@ -1322,6 +1322,11 @@ if [ -n "${OPENSSL_LEGACY:-}" ]; then
O_LEGACY_CLI="$O_LEGACY_CLI -connect localhost:+SRV_PORT" O_LEGACY_CLI="$O_LEGACY_CLI -connect localhost:+SRV_PORT"
fi fi
if [ -n "${OPENSSL_NEXT:-}" ]; then
O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
O_NEXT_CLI="$O_NEXT_CLI -connect localhost:+SRV_PORT"
fi
if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
G_NEXT_SRV="$G_NEXT_SRV -p $SRV_PORT" G_NEXT_SRV="$G_NEXT_SRV -p $SRV_PORT"
fi fi
@ -8661,6 +8666,24 @@ run_test "TLS1.3: handshake dispatch test: tls1_3 only" \
-s "SSL - The requested feature is not available" \ -s "SSL - The requested feature is not available" \
-c "SSL - The requested feature is not available" -c "SSL - The requested feature is not available"
requires_openssl_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
run_test "TLS1.3: Test client hello msg work - openssl" \
"$O_NEXT_SRV -tls1_3 -msg" \
"$P_CLI min_version=tls1_3 max_version=tls1_3" \
1 \
-c "SSL - The requested feature is not available" \
-s "ServerHello"
requires_gnutls_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
run_test "TLS1.3: Test client hello msg work - gnutls" \
"$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --debug=4" \
"$P_CLI min_version=tls1_3 max_version=tls1_3" \
1 \
-c "SSL - The requested feature is not available" \
-s "SERVER HELLO was queued"
# Test heap memory usage after handshake # Test heap memory usage after handshake
requires_config_enabled MBEDTLS_MEMORY_DEBUG requires_config_enabled MBEDTLS_MEMORY_DEBUG
requires_config_enabled MBEDTLS_MEMORY_BUFFER_ALLOC_C requires_config_enabled MBEDTLS_MEMORY_BUFFER_ALLOC_C