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:
commit
f2cb19f921
8 changed files with 704 additions and 32 deletions
|
@ -169,6 +169,37 @@
|
|||
/** Invalid value in SSL config */
|
||||
#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
|
||||
*
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include "ecdh_misc.h"
|
||||
|
||||
#include <string.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
|
||||
}
|
||||
|
||||
#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 */
|
||||
|
|
51
library/ecdh_misc.h
Normal file
51
library/ecdh_misc.h
Normal 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 */
|
|
@ -649,6 +649,16 @@ struct mbedtls_ssl_handshake_params
|
|||
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
|
||||
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;
|
||||
|
||||
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 );
|
||||
#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.
|
||||
*/
|
||||
|
@ -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)
|
||||
|
||||
/*
|
||||
* 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,
|
||||
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 *end,
|
||||
size_t *olen);
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
|
||||
|
|
|
@ -27,8 +27,11 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include "ssl_misc.h"
|
||||
#include <mbedtls/debug.h>
|
||||
#include "ecdh_misc.h"
|
||||
|
||||
#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" ) );
|
||||
|
||||
/*
|
||||
* Check space for extension header.
|
||||
*
|
||||
* extension_type 2
|
||||
* extension_data_length 2
|
||||
* version_length 1
|
||||
* versions 2
|
||||
/* Check if we have space to write the extension:
|
||||
* - extension_type (2 bytes)
|
||||
* - extension_data_length (2 bytes)
|
||||
* - versions_length (1 byte )
|
||||
* - versions (2 bytes)
|
||||
*/
|
||||
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)
|
||||
|
||||
/*
|
||||
* 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,
|
||||
unsigned char *buf,
|
||||
unsigned char *end,
|
||||
size_t *olen )
|
||||
{
|
||||
((void) ssl);
|
||||
((void) buf);
|
||||
((void) end);
|
||||
((void) olen);
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
unsigned char *p = buf ;
|
||||
unsigned char *named_group_list_ptr; /* Start of named_group_list */
|
||||
size_t named_group_list_len; /* Length of named_group_list */
|
||||
size_t output_len = 0;
|
||||
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,
|
||||
unsigned char *end,
|
||||
size_t *olen )
|
||||
/*
|
||||
* Functions for writing key_share extension.
|
||||
*/
|
||||
#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) buf);
|
||||
((void) end);
|
||||
((void) olen);
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
((void) group_id);
|
||||
#endif /* MBEDTLS_ECDH_C */
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
/*
|
||||
* Functions for writing ClientHello message.
|
||||
*/
|
||||
/* Write cipher_suites
|
||||
* 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
|
||||
* 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 )
|
||||
return( ret );
|
||||
p += output_len;
|
||||
|
@ -340,7 +672,7 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl,
|
|||
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 );
|
||||
return( 0 );
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
|
||||
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/debug.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.
|
||||
*/
|
||||
|
||||
int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
unsigned char *end,
|
||||
size_t *olen )
|
||||
{
|
||||
((void) ssl);
|
||||
((void) buf);
|
||||
((void) end);
|
||||
((void) olen);
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
unsigned char *p = buf;
|
||||
unsigned char *supported_sig_alg_ptr; /* Start of supported_signature_algorithms */
|
||||
size_t supported_sig_alg_len = 0; /* Length of supported_signature_algorithms */
|
||||
|
||||
*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 */
|
||||
|
|
|
@ -2565,6 +2565,8 @@ component_test_tls13_experimental () {
|
|||
make
|
||||
msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, without padding"
|
||||
make test
|
||||
msg "ssl-opt.sh (TLS 1.3 experimental)"
|
||||
if_build_succeeded tests/ssl-opt.sh
|
||||
}
|
||||
|
||||
component_test_tls13_experimental_with_padding () {
|
||||
|
@ -2579,6 +2581,31 @@ component_test_tls13_experimental_with_padding () {
|
|||
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 () {
|
||||
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
|
||||
|
|
|
@ -1322,6 +1322,11 @@ if [ -n "${OPENSSL_LEGACY:-}" ]; then
|
|||
O_LEGACY_CLI="$O_LEGACY_CLI -connect localhost:+SRV_PORT"
|
||||
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
|
||||
G_NEXT_SRV="$G_NEXT_SRV -p $SRV_PORT"
|
||||
fi
|
||||
|
@ -8661,6 +8666,24 @@ run_test "TLS1.3: handshake dispatch test: tls1_3 only" \
|
|||
-s "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
|
||||
requires_config_enabled MBEDTLS_MEMORY_DEBUG
|
||||
requires_config_enabled MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
|
|
Loading…
Reference in a new issue