Merge pull request #4927 from yuhaoth/pr/add-tls13-serverhello-utils

TLS 1.3: ServerHello: add  utils functions used by ServerHello
Regarding the merge job, there was only one of the failure we currently encounter on almost all PR (Session resume using tickets, DTLS: openssl client test case see #5012) thus we can consider that this PR passed CI.
This commit is contained in:
Ronald Cron 2021-10-11 11:01:11 +02:00 committed by GitHub
commit e23bba04ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 263 additions and 46 deletions

View File

@ -593,6 +593,9 @@ union mbedtls_ssl_premaster_secret
#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret )
/* Length in number of bytes of the TLS sequence number */
#define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8
#ifdef __cplusplus
extern "C" {
#endif
@ -1566,7 +1569,7 @@ struct mbedtls_ssl_context
size_t MBEDTLS_PRIVATE(out_buf_len); /*!< length of output buffer */
#endif
unsigned char MBEDTLS_PRIVATE(cur_out_ctr)[8]; /*!< Outgoing record sequence number. */
unsigned char MBEDTLS_PRIVATE(cur_out_ctr)[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!< Outgoing record sequence number. */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
uint16_t MBEDTLS_PRIVATE(mtu); /*!< path mtu, used to fragment outgoing messages */

View File

@ -307,6 +307,10 @@
+ ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) )
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
#define MBEDTLS_TLS1_3_MD_MAX_SIZE MBEDTLS_MD_MAX_SIZE
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/**
* \brief Return the maximum fragment length (payload, in bytes) for
@ -573,8 +577,8 @@ struct mbedtls_ssl_handshake_params
flight being received */
mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for
resending messages */
unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
for resending messages */
unsigned char alt_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!< Alternative record epoch/counter
for resending messages */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
/* The state of CID configuration in this handshake. */
@ -675,6 +679,13 @@ struct mbedtls_ssl_handshake_params
int extensions_present; /*!< extension presence; Each bitfield
represents an extension and defined
as \c MBEDTLS_SSL_EXT_XXX */
union
{
unsigned char early [MBEDTLS_TLS1_3_MD_MAX_SIZE];
unsigned char handshake[MBEDTLS_TLS1_3_MD_MAX_SIZE];
unsigned char app [MBEDTLS_TLS1_3_MD_MAX_SIZE];
} tls1_3_master_secrets;
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -866,14 +877,14 @@ static inline int mbedtls_ssl_transform_uses_aead(
typedef struct
{
uint8_t ctr[8]; /* In TLS: The implicit record sequence number.
* In DTLS: The 2-byte epoch followed by
* the 6-byte sequence number.
* This is stored as a raw big endian byte array
* as opposed to a uint64_t because we rarely
* need to perform arithmetic on this, but do
* need it as a Byte array for the purpose of
* MAC computations. */
uint8_t ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /* In TLS: The implicit record sequence number.
* In DTLS: The 2-byte epoch followed by
* the 6-byte sequence number.
* This is stored as a raw big endian byte array
* as opposed to a uint64_t because we rarely
* need to perform arithmetic on this, but do
* need it as a Byte array for the purpose of
* MAC computations. */
uint8_t type; /* The record content type. */
uint8_t ver[2]; /* SSL/TLS version as present on the wire.
* Convert to internal presentation of versions
@ -956,6 +967,14 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
*/
void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
/* set inbound transform of ssl context */
void mbedtls_ssl_set_inbound_transform( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform );
/* set outbound transform of ssl context */
void mbedtls_ssl_set_outbound_transform( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform );
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
@ -1510,13 +1529,19 @@ int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
int mbedtls_ssl_tls13_finish_handshake_msg( mbedtls_ssl_context *ssl,
size_t buf_len,
size_t msg_len );
/*
* Update checksum with handshake header
*/
void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
unsigned hs_type,
size_t total_hs_len );
/*
* Update checksum of handshake messages.
*/
void mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( mbedtls_ssl_context *ssl,
unsigned hs_type,
unsigned char const *msg,
size_t msg_len );
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Write TLS 1.3 Signature Algorithm extension
@ -1530,4 +1555,11 @@ int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
/* Get handshake transcript */
int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
const mbedtls_md_type_t md,
unsigned char *dst,
size_t dst_len,
size_t *olen );
#endif /* ssl_misc.h */

View File

@ -2101,7 +2101,7 @@ void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight )
static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_transform *tmp_transform;
unsigned char tmp_out_ctr[8];
unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];
if( ssl->transform_out == ssl->handshake->alt_transform_out )
{
@ -2117,9 +2117,11 @@ static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
ssl->handshake->alt_transform_out = tmp_transform;
/* Swap epoch + sequence_number */
memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
memcpy( tmp_out_ctr, ssl->cur_out_ctr, sizeof( tmp_out_ctr ) );
memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr,
sizeof( ssl->cur_out_ctr ) );
memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr,
sizeof( ssl->handshake->alt_out_ctr ) );
/* Adjust to the newly activated transform */
mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
@ -2562,7 +2564,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
ssl->conf->transport, ssl->out_hdr + 1 );
memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
memcpy( ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
if( ssl->transform_out != NULL )
@ -2574,7 +2576,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
rec.data_len = ssl->out_msglen;
rec.data_offset = ssl->out_msg - rec.buf;
memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
memcpy( &rec.ctr[0], ssl->out_ctr, sizeof( rec.ctr ) );
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
ssl->conf->transport, rec.ver );
rec.type = ssl->out_msgtype;
@ -3649,9 +3651,12 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
#endif
{
unsigned i;
for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
for( i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
i > mbedtls_ssl_ep_len( ssl ); i-- )
{
if( ++ssl->in_ctr[i - 1] != 0 )
break;
}
/* The loop goes to its end iff the counter is wrapping */
if( i == mbedtls_ssl_ep_len( ssl ) )
@ -4791,7 +4796,7 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
}
else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
memset( ssl->in_ctr, 0, 8 );
memset( ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
mbedtls_ssl_update_in_pointers( ssl );
@ -4827,12 +4832,12 @@ void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl,
{
ssl->out_ctr = ssl->out_hdr + 3;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
ssl->out_cid = ssl->out_ctr + 8;
ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
ssl->out_len = ssl->out_cid;
if( transform != NULL )
ssl->out_len += transform->out_cid_len;
#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
ssl->out_len = ssl->out_ctr + 8;
ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
ssl->out_iv = ssl->out_len + 2;
}
@ -4881,17 +4886,17 @@ void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl )
* ssl_parse_record_header(). */
ssl->in_ctr = ssl->in_hdr + 3;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
ssl->in_cid = ssl->in_ctr + 8;
ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
ssl->in_len = ssl->in_cid; /* Default: no CID */
#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
ssl->in_len = ssl->in_ctr + 8;
ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
ssl->in_iv = ssl->in_len + 2;
}
else
#endif
{
ssl->in_ctr = ssl->in_hdr - 8;
ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
ssl->in_len = ssl->in_hdr + 3;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
ssl->in_cid = ssl->in_len;
@ -5065,9 +5070,11 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
}
in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len );
out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len );
&ssl->conf->renego_period[ep_len],
MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len );
out_ctr_cmp = memcmp( &ssl->cur_out_ctr[ep_len],
&ssl->conf->renego_period[ep_len],
sizeof( ssl->cur_out_ctr ) - ep_len );
if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
{
@ -5551,6 +5558,20 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
}
void mbedtls_ssl_set_inbound_transform( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform )
{
ssl->transform_in = transform;
memset( ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
}
void mbedtls_ssl_set_outbound_transform( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform )
{
ssl->transform_out = transform;
memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl )

View File

@ -1220,7 +1220,8 @@ read_record_header:
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
memcpy( &ssl->cur_out_ctr[2], ssl->in_ctr + 2,
sizeof( ssl->cur_out_ctr ) - 2 );
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )

View File

@ -2820,10 +2820,12 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
/* Remember current epoch settings for resending */
ssl->handshake->alt_transform_out = ssl->transform_out;
memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr,
sizeof( ssl->handshake->alt_out_ctr ) );
/* Set sequence_number to zero */
memset( ssl->cur_out_ctr + 2, 0, 6 );
memset( &ssl->cur_out_ctr[2], 0, sizeof( ssl->cur_out_ctr ) - 2 );
/* Increment epoch */
for( i = 2; i > 0; i-- )
@ -2839,7 +2841,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
}
else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
memset( ssl->cur_out_ctr, 0, 8 );
memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
ssl->transform_out = ssl->transform_negotiate;
ssl->session_out = ssl->session_negotiate;
@ -5792,11 +5794,11 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
used += 8;
used += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
if( used <= buf_len )
{
memcpy( p, ssl->cur_out_ctr, 8 );
p += 8;
memcpy( p, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
p += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
@ -6052,11 +6054,10 @@ static int ssl_context_load( mbedtls_ssl_context *ssl,
ssl->disable_datagram_packing = *p++;
#endif /* MBEDTLS_SSL_PROTO_DTLS */
if( (size_t)( end - p ) < 8 )
if( (size_t)( end - p ) < sizeof( ssl->cur_out_ctr ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
memcpy( ssl->cur_out_ctr, p, 8 );
p += 8;
memcpy( ssl->cur_out_ctr, p, sizeof( ssl->cur_out_ctr ) );
p += sizeof( ssl->cur_out_ctr );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( (size_t)( end - p ) < 2 )
@ -6995,4 +6996,106 @@ exit:
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
const mbedtls_md_type_t md,
unsigned char *dst,
size_t dst_len,
size_t *olen )
{
((void) ssl);
((void) md);
((void) dst);
((void) dst_len);
*olen = 0;
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE);
}
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SHA384_C)
static int ssl_get_handshake_transcript_sha384( mbedtls_ssl_context *ssl,
unsigned char *dst,
size_t dst_len,
size_t *olen )
{
int ret;
mbedtls_sha512_context sha512;
if( dst_len < 48 )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
mbedtls_sha512_init( &sha512 );
mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
if( ( ret = mbedtls_sha512_finish( &sha512, dst ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha512_finish", ret );
goto exit;
}
*olen = 48;
exit:
mbedtls_sha512_free( &sha512 );
return( ret );
}
#endif /* MBEDTLS_SHA384_C */
#if defined(MBEDTLS_SHA256_C)
static int ssl_get_handshake_transcript_sha256( mbedtls_ssl_context *ssl,
unsigned char *dst,
size_t dst_len,
size_t *olen )
{
int ret;
mbedtls_sha256_context sha256;
if( dst_len < 32 )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
mbedtls_sha256_init( &sha256 );
mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
if( ( ret = mbedtls_sha256_finish( &sha256, dst ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha256_finish", ret );
goto exit;
}
*olen = 32;
exit:
mbedtls_sha256_free( &sha256 );
return( ret );
}
#endif /* MBEDTLS_SHA256_C */
int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
const mbedtls_md_type_t md,
unsigned char *dst,
size_t dst_len,
size_t *olen )
{
switch( md )
{
#if defined(MBEDTLS_SHA384_C)
case MBEDTLS_MD_SHA384:
return( ssl_get_handshake_transcript_sha384( ssl, dst, dst_len, olen ) );
#endif /* MBEDTLS_SHA384_C */
#if defined(MBEDTLS_SHA256_C)
case MBEDTLS_MD_SHA256:
return( ssl_get_handshake_transcript_sha256( ssl, dst, dst_len, olen ) );
#endif /* MBEDTLS_SHA256_C */
default:
break;
}
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_TLS_C */

View File

@ -104,6 +104,15 @@ cleanup:
return( ret );
}
void mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( mbedtls_ssl_context *ssl,
unsigned hs_type,
unsigned char const *msg,
size_t msg_len )
{
mbedtls_ssl_tls13_add_hs_hdr_to_checksum( ssl, hs_type, msg_len );
ssl->handshake->update_checksum( ssl, msg, msg_len );
}
void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
unsigned hs_type,
size_t total_hs_len )

View File

@ -21,14 +21,16 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
#include "mbedtls/hkdf.h"
#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
#include "mbedtls/debug.h"
#include <stdint.h>
#include <string.h>
#include "mbedtls/hkdf.h"
#include "mbedtls/debug.h"
#include "mbedtls/error.h"
#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
.name = string,
@ -820,4 +822,28 @@ int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform,
return( 0 );
}
int mbedtls_ssl_tls1_3_key_schedule_stage_early( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_type;
if( ssl->handshake->ciphersuite_info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher suite info not found" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
md_type = ssl->handshake->ciphersuite_info->mac;
ret = mbedtls_ssl_tls1_3_evolve_secret( md_type, NULL, NULL, 0,
ssl->handshake->tls1_3_master_secrets.early );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret );
return( ret );
}
return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */

View File

@ -531,4 +531,26 @@ int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform,
mbedtls_ssl_key_set const *traffic_keys,
mbedtls_ssl_context *ssl );
/*
* TLS 1.3 key schedule evolutions
*
* Early -> Handshake -> Application
*
* Small wrappers around mbedtls_ssl_tls1_3_evolve_secret().
*/
/**
* \brief Begin TLS 1.3 key schedule by calculating early secret.
*
* The TLS 1.3 key schedule can be viewed as a simple state machine
* with states Initial -> Early -> Handshake -> Application, and
* this function represents the Initial -> Early transition.
*
* \param ssl The SSL context to operate on.
*
* \returns \c 0 on success.
* \returns A negative error code on failure.
*/
int mbedtls_ssl_tls1_3_key_schedule_stage_early( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */