mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-23 17:55:37 +00:00
Merge pull request #3568 from hanno-arm/tls13_experimental_key_schedule_1
TLS 1.3: Add HKDF-based key derivation functionality
This commit is contained in:
commit
2a25904f45
|
@ -38,3 +38,12 @@ together with their level of testing:
|
||||||
- The HKDF key derivation function on which the TLS 1.3 key schedule is based,
|
- The HKDF key derivation function on which the TLS 1.3 key schedule is based,
|
||||||
is already present as an independent module controlled by `MBEDTLS_HKDF_C`
|
is already present as an independent module controlled by `MBEDTLS_HKDF_C`
|
||||||
independently of the development of the TLS 1.3 prototype.
|
independently of the development of the TLS 1.3 prototype.
|
||||||
|
|
||||||
|
- The TLS 1.3-specific HKDF-based key derivation functions (see RFC 8446):
|
||||||
|
* HKDF-Expand-Label
|
||||||
|
* Derive-Secret
|
||||||
|
- Secret evolution
|
||||||
|
* The traffic {Key,IV} generation from secret
|
||||||
|
Those functions are implemented in `library/ssl_tls13_keys.c` and
|
||||||
|
tested in `test_suite_ssl` using test vectors from RFC 8448 and
|
||||||
|
https://tls13.ulfheim.net/.
|
||||||
|
|
|
@ -227,10 +227,30 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Maximum length of any IV, in Bytes. */
|
/** Maximum length of any IV, in Bytes. */
|
||||||
|
/* This should ideally be derived automatically from list of ciphers.
|
||||||
|
* This should be kept in sync with MBEDTLS_SSL_MAX_IV_LENGTH defined
|
||||||
|
* in ssl_internal.h. */
|
||||||
#define MBEDTLS_MAX_IV_LENGTH 16
|
#define MBEDTLS_MAX_IV_LENGTH 16
|
||||||
|
|
||||||
/** Maximum block size of any cipher, in Bytes. */
|
/** Maximum block size of any cipher, in Bytes. */
|
||||||
|
/* This should ideally be derived automatically from list of ciphers.
|
||||||
|
* This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined
|
||||||
|
* in ssl_internal.h. */
|
||||||
#define MBEDTLS_MAX_BLOCK_LENGTH 16
|
#define MBEDTLS_MAX_BLOCK_LENGTH 16
|
||||||
|
|
||||||
|
/** Maximum key length, in Bytes. */
|
||||||
|
/* This should ideally be derived automatically from list of ciphers.
|
||||||
|
* For now, only check whether XTS is enabled which uses 64 Byte keys,
|
||||||
|
* and use 32 Bytes as an upper bound for the maximum key length otherwise.
|
||||||
|
* This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined
|
||||||
|
* in ssl_internal.h, which however deliberately ignores the case of XTS
|
||||||
|
* since the latter isn't used in SSL/TLS. */
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
|
#define MBEDTLS_MAX_KEY_LENGTH 64
|
||||||
|
#else
|
||||||
|
#define MBEDTLS_MAX_KEY_LENGTH 32
|
||||||
|
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base cipher information (opaque struct).
|
* Base cipher information (opaque struct).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -378,6 +378,49 @@ typedef int mbedtls_ssl_tls_prf_cb( const unsigned char *secret, size_t slen,
|
||||||
const char *label,
|
const char *label,
|
||||||
const unsigned char *random, size_t rlen,
|
const unsigned char *random, size_t rlen,
|
||||||
unsigned char *dstbuf, size_t dlen );
|
unsigned char *dstbuf, size_t dlen );
|
||||||
|
|
||||||
|
/* cipher.h exports the maximum IV, key and block length from
|
||||||
|
* all ciphers enabled in the config, regardless of whether those
|
||||||
|
* ciphers are actually usable in SSL/TLS. Notably, XTS is enabled
|
||||||
|
* in the default configuration and uses 64 Byte keys, but it is
|
||||||
|
* not used for record protection in SSL/TLS.
|
||||||
|
*
|
||||||
|
* In order to prevent unnecessary inflation of key structures,
|
||||||
|
* we introduce SSL-specific variants of the max-{key,block,IV}
|
||||||
|
* macros here which are meant to only take those ciphers into
|
||||||
|
* account which can be negotiated in SSL/TLS.
|
||||||
|
*
|
||||||
|
* Since the current definitions of MBEDTLS_MAX_{KEY|BLOCK|IV}_LENGTH
|
||||||
|
* in cipher.h are rough overapproximations of the real maxima, here
|
||||||
|
* we content ourselves with replicating those overapproximations
|
||||||
|
* for the maximum block and IV length, and excluding XTS from the
|
||||||
|
* computation of the maximum key length. */
|
||||||
|
#define MBEDTLS_SSL_MAX_BLOCK_LENGTH 16
|
||||||
|
#define MBEDTLS_SSL_MAX_IV_LENGTH 16
|
||||||
|
#define MBEDTLS_SSL_MAX_KEY_LENGTH 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The data structure holding the cryptographic material (key and IV)
|
||||||
|
* used for record protection in TLS 1.3.
|
||||||
|
*/
|
||||||
|
struct mbedtls_ssl_key_set
|
||||||
|
{
|
||||||
|
/*! The key for client->server records. */
|
||||||
|
unsigned char client_write_key[ MBEDTLS_SSL_MAX_KEY_LENGTH ];
|
||||||
|
/*! The key for server->client records. */
|
||||||
|
unsigned char server_write_key[ MBEDTLS_SSL_MAX_KEY_LENGTH ];
|
||||||
|
/*! The IV for client->server records. */
|
||||||
|
unsigned char client_write_iv[ MBEDTLS_SSL_MAX_IV_LENGTH ];
|
||||||
|
/*! The IV for server->client records. */
|
||||||
|
unsigned char server_write_iv[ MBEDTLS_SSL_MAX_IV_LENGTH ];
|
||||||
|
|
||||||
|
size_t key_len; /*!< The length of client_write_key and
|
||||||
|
* server_write_key, in Bytes. */
|
||||||
|
size_t iv_len; /*!< The length of client_write_iv and
|
||||||
|
* server_write_iv, in Bytes. */
|
||||||
|
};
|
||||||
|
typedef struct mbedtls_ssl_key_set mbedtls_ssl_key_set;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure contains the parameters only needed during handshake.
|
* This structure contains the parameters only needed during handshake.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -104,6 +104,7 @@ set(src_tls
|
||||||
ssl_srv.c
|
ssl_srv.c
|
||||||
ssl_ticket.c
|
ssl_ticket.c
|
||||||
ssl_tls.c
|
ssl_tls.c
|
||||||
|
ssl_tls13_keys.c
|
||||||
)
|
)
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
|
|
@ -163,6 +163,7 @@ OBJS_TLS= \
|
||||||
ssl_srv.o \
|
ssl_srv.o \
|
||||||
ssl_ticket.o \
|
ssl_ticket.o \
|
||||||
ssl_tls.o \
|
ssl_tls.o \
|
||||||
|
ssl_tls13_keys.o \
|
||||||
# This line is intentionally left blank
|
# This line is intentionally left blank
|
||||||
|
|
||||||
.SILENT:
|
.SILENT:
|
||||||
|
|
349
library/ssl_tls13_keys.c
Normal file
349
library/ssl_tls13_keys.c
Normal file
|
@ -0,0 +1,349 @@
|
||||||
|
/*
|
||||||
|
* TLS 1.3 key schedule
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
|
||||||
|
|
||||||
|
#include "mbedtls/hkdf.h"
|
||||||
|
#include "mbedtls/ssl_internal.h"
|
||||||
|
#include "ssl_tls13_keys.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
|
||||||
|
.name = string,
|
||||||
|
|
||||||
|
struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels =
|
||||||
|
{
|
||||||
|
/* This seems to work in C, despite the string literal being one
|
||||||
|
* character too long due to the 0-termination. */
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef MBEDTLS_SSL_TLS1_3_LABEL
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function creates a HkdfLabel structure used in the TLS 1.3 key schedule.
|
||||||
|
*
|
||||||
|
* The HkdfLabel is specified in RFC 8446 as follows:
|
||||||
|
*
|
||||||
|
* struct HkdfLabel {
|
||||||
|
* uint16 length; // Length of expanded key material
|
||||||
|
* opaque label<7..255>; // Always prefixed by "tls13 "
|
||||||
|
* opaque context<0..255>; // Usually a communication transcript hash
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - desired_length: Length of expanded key material
|
||||||
|
* Even though the standard allows expansion to up to
|
||||||
|
* 2**16 Bytes, TLS 1.3 never uses expansion to more than
|
||||||
|
* 255 Bytes, so we require `desired_length` to be at most
|
||||||
|
* 255. This allows us to save a few Bytes of code by
|
||||||
|
* hardcoding the writing of the high bytes.
|
||||||
|
* - (label, llen): label + label length, without "tls13 " prefix
|
||||||
|
* The label length MUST be less than or equal to
|
||||||
|
* MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN
|
||||||
|
* It is the caller's responsibility to ensure this.
|
||||||
|
* All (label, label length) pairs used in TLS 1.3
|
||||||
|
* can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN().
|
||||||
|
* - (ctx, clen): context + context length
|
||||||
|
* The context length MUST be less than or equal to
|
||||||
|
* MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN
|
||||||
|
* It is the caller's responsibility to ensure this.
|
||||||
|
* - dst: Target buffer for HkdfLabel structure,
|
||||||
|
* This MUST be a writable buffer of size
|
||||||
|
* at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes.
|
||||||
|
* - dlen: Pointer at which to store the actual length of
|
||||||
|
* the HkdfLabel structure on success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char tls1_3_label_prefix[6] = "tls13 ";
|
||||||
|
|
||||||
|
#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( label_len, context_len ) \
|
||||||
|
( 2 /* expansion length */ \
|
||||||
|
+ 1 /* label length */ \
|
||||||
|
+ label_len \
|
||||||
|
+ 1 /* context length */ \
|
||||||
|
+ context_len )
|
||||||
|
|
||||||
|
#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \
|
||||||
|
SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \
|
||||||
|
sizeof(tls1_3_label_prefix) + \
|
||||||
|
MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \
|
||||||
|
MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN )
|
||||||
|
|
||||||
|
static void ssl_tls1_3_hkdf_encode_label(
|
||||||
|
size_t desired_length,
|
||||||
|
const unsigned char *label, size_t llen,
|
||||||
|
const unsigned char *ctx, size_t clen,
|
||||||
|
unsigned char *dst, size_t *dlen )
|
||||||
|
{
|
||||||
|
size_t total_label_len =
|
||||||
|
sizeof(tls1_3_label_prefix) + llen;
|
||||||
|
size_t total_hkdf_lbl_len =
|
||||||
|
SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( total_label_len, clen );
|
||||||
|
|
||||||
|
unsigned char *p = dst;
|
||||||
|
|
||||||
|
/* Add the size of the expanded key material.
|
||||||
|
* We're hardcoding the high byte to 0 here assuming that we never use
|
||||||
|
* TLS 1.3 HKDF key expansion to more than 255 Bytes. */
|
||||||
|
#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255
|
||||||
|
#error "The implementation of ssl_tls1_3_hkdf_encode_label() is not fit for the \
|
||||||
|
value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = (unsigned char)( ( desired_length >> 0 ) & 0xFF );
|
||||||
|
|
||||||
|
/* Add label incl. prefix */
|
||||||
|
*p++ = (unsigned char)( total_label_len & 0xFF );
|
||||||
|
memcpy( p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix) );
|
||||||
|
p += sizeof(tls1_3_label_prefix);
|
||||||
|
memcpy( p, label, llen );
|
||||||
|
p += llen;
|
||||||
|
|
||||||
|
/* Add context value */
|
||||||
|
*p++ = (unsigned char)( clen & 0xFF );
|
||||||
|
if( clen != 0 )
|
||||||
|
memcpy( p, ctx, clen );
|
||||||
|
|
||||||
|
/* Return total length to the caller. */
|
||||||
|
*dlen = total_hkdf_lbl_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ssl_tls1_3_hkdf_expand_label(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *secret, size_t slen,
|
||||||
|
const unsigned char *label, size_t llen,
|
||||||
|
const unsigned char *ctx, size_t clen,
|
||||||
|
unsigned char *buf, size_t blen )
|
||||||
|
{
|
||||||
|
const mbedtls_md_info_t *md;
|
||||||
|
unsigned char hkdf_label[ SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN ];
|
||||||
|
size_t hkdf_label_len;
|
||||||
|
|
||||||
|
if( llen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN )
|
||||||
|
{
|
||||||
|
/* Should never happen since this is an internal
|
||||||
|
* function, and we know statically which labels
|
||||||
|
* are allowed. */
|
||||||
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( clen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN )
|
||||||
|
{
|
||||||
|
/* Should not happen, as above. */
|
||||||
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( blen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN )
|
||||||
|
{
|
||||||
|
/* Should not happen, as above. */
|
||||||
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||||
|
}
|
||||||
|
|
||||||
|
md = mbedtls_md_info_from_type( hash_alg );
|
||||||
|
if( md == NULL )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
ssl_tls1_3_hkdf_encode_label( blen,
|
||||||
|
label, llen,
|
||||||
|
ctx, clen,
|
||||||
|
hkdf_label,
|
||||||
|
&hkdf_label_len );
|
||||||
|
|
||||||
|
return( mbedtls_hkdf_expand( md,
|
||||||
|
secret, slen,
|
||||||
|
hkdf_label, hkdf_label_len,
|
||||||
|
buf, blen ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The traffic keying material is generated from the following inputs:
|
||||||
|
*
|
||||||
|
* - One secret value per sender.
|
||||||
|
* - A purpose value indicating the specific value being generated
|
||||||
|
* - The desired lengths of key and IV.
|
||||||
|
*
|
||||||
|
* The expansion itself is based on HKDF:
|
||||||
|
*
|
||||||
|
* [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length )
|
||||||
|
* [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length )
|
||||||
|
*
|
||||||
|
* [sender] denotes the sending side and the Secret value is provided
|
||||||
|
* by the function caller. Note that we generate server and client side
|
||||||
|
* keys in a single function call.
|
||||||
|
*/
|
||||||
|
int mbedtls_ssl_tls1_3_make_traffic_keys(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *client_secret,
|
||||||
|
const unsigned char *server_secret,
|
||||||
|
size_t slen, size_t key_len, size_t iv_len,
|
||||||
|
mbedtls_ssl_key_set *keys )
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
|
||||||
|
client_secret, slen,
|
||||||
|
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
|
||||||
|
NULL, 0,
|
||||||
|
keys->client_write_key, key_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
|
||||||
|
server_secret, slen,
|
||||||
|
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
|
||||||
|
NULL, 0,
|
||||||
|
keys->server_write_key, key_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
|
||||||
|
client_secret, slen,
|
||||||
|
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
|
||||||
|
NULL, 0,
|
||||||
|
keys->client_write_iv, iv_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
|
||||||
|
server_secret, slen,
|
||||||
|
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
|
||||||
|
NULL, 0,
|
||||||
|
keys->server_write_iv, iv_len );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
keys->key_len = key_len;
|
||||||
|
keys->iv_len = iv_len;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ssl_tls1_3_derive_secret(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *secret, size_t slen,
|
||||||
|
const unsigned char *label, size_t llen,
|
||||||
|
const unsigned char *ctx, size_t clen,
|
||||||
|
int ctx_hashed,
|
||||||
|
unsigned char *dstbuf, size_t buflen )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char hashed_context[ MBEDTLS_MD_MAX_SIZE ];
|
||||||
|
|
||||||
|
const mbedtls_md_info_t *md;
|
||||||
|
md = mbedtls_md_info_from_type( hash_alg );
|
||||||
|
if( md == NULL )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED )
|
||||||
|
{
|
||||||
|
ret = mbedtls_md( md, ctx, clen, hashed_context );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
clen = mbedtls_md_get_size( md );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( clen > sizeof(hashed_context) )
|
||||||
|
{
|
||||||
|
/* This should never happen since this function is internal
|
||||||
|
* and the code sets `ctx_hashed` correctly.
|
||||||
|
* Let's double-check nonetheless to not run at the risk
|
||||||
|
* of getting a stack overflow. */
|
||||||
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( hashed_context, ctx, clen );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
|
||||||
|
secret, slen,
|
||||||
|
label, llen,
|
||||||
|
hashed_context, clen,
|
||||||
|
dstbuf, buflen ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ssl_tls1_3_evolve_secret(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *secret_old,
|
||||||
|
const unsigned char *input, size_t input_len,
|
||||||
|
unsigned char *secret_new )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||||
|
size_t hlen, ilen;
|
||||||
|
unsigned char tmp_secret[ MBEDTLS_MD_MAX_SIZE ] = { 0 };
|
||||||
|
unsigned char tmp_input [ MBEDTLS_MD_MAX_SIZE ] = { 0 };
|
||||||
|
|
||||||
|
const mbedtls_md_info_t *md;
|
||||||
|
md = mbedtls_md_info_from_type( hash_alg );
|
||||||
|
if( md == NULL )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
hlen = mbedtls_md_get_size( md );
|
||||||
|
|
||||||
|
/* For non-initial runs, call Derive-Secret( ., "derived", "")
|
||||||
|
* on the old secret. */
|
||||||
|
if( secret_old != NULL )
|
||||||
|
{
|
||||||
|
ret = mbedtls_ssl_tls1_3_derive_secret(
|
||||||
|
hash_alg,
|
||||||
|
secret_old, hlen,
|
||||||
|
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( derived ),
|
||||||
|
NULL, 0, /* context */
|
||||||
|
MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
|
||||||
|
tmp_secret, hlen );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( input != NULL )
|
||||||
|
{
|
||||||
|
memcpy( tmp_input, input, input_len );
|
||||||
|
ilen = input_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ilen = hlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HKDF-Extract takes a salt and input key material.
|
||||||
|
* The salt is the old secret, and the input key material
|
||||||
|
* is the input secret (PSK / ECDHE). */
|
||||||
|
ret = mbedtls_hkdf_extract( md,
|
||||||
|
tmp_secret, hlen,
|
||||||
|
tmp_input, ilen,
|
||||||
|
secret_new );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mbedtls_platform_zeroize( tmp_secret, sizeof(tmp_secret) );
|
||||||
|
mbedtls_platform_zeroize( tmp_input, sizeof(tmp_input) );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
|
274
library/ssl_tls13_keys.h
Normal file
274
library/ssl_tls13_keys.h
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
/*
|
||||||
|
* TLS 1.3 key schedule
|
||||||
|
*
|
||||||
|
* 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_SSL_TLS1_3_KEYS_H)
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_KEYS_H
|
||||||
|
|
||||||
|
/* This requires MBEDTLS_SSL_TLS1_3_LABEL( idx, name, string ) to be defined at
|
||||||
|
* the point of use. See e.g. the definition of mbedtls_ssl_tls1_3_labels_union
|
||||||
|
* below. */
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_LABEL_LIST \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( finished , "finished" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( resumption , "resumption" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( traffic_upd , "traffic upd" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( exporter , "exporter" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( key , "key" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( iv , "iv" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( c_hs_traffic, "c hs traffic" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( c_ap_traffic, "c ap traffic" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( c_e_traffic , "c e traffic" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( s_hs_traffic, "s hs traffic" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( s_ap_traffic, "s ap traffic" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( s_e_traffic , "s e traffic" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( e_exp_master, "e exp master" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( res_master , "res master" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( exp_master , "exp master" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( ext_binder , "ext binder" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( res_binder , "res binder" ) \
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL( derived , "derived" )
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
|
||||||
|
const unsigned char name [ sizeof(string) - 1 ];
|
||||||
|
|
||||||
|
union mbedtls_ssl_tls1_3_labels_union
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||||
|
};
|
||||||
|
struct mbedtls_ssl_tls1_3_labels_struct
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||||
|
};
|
||||||
|
#undef MBEDTLS_SSL_TLS1_3_LABEL
|
||||||
|
|
||||||
|
extern const struct mbedtls_ssl_tls1_3_labels_struct mbedtls_ssl_tls1_3_labels;
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( LABEL ) \
|
||||||
|
mbedtls_ssl_tls1_3_labels.LABEL, \
|
||||||
|
sizeof(mbedtls_ssl_tls1_3_labels.LABEL)
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN \
|
||||||
|
sizeof( union mbedtls_ssl_tls1_3_labels_union )
|
||||||
|
|
||||||
|
/* The maximum length of HKDF contexts used in the TLS 1.3 standard.
|
||||||
|
* Since contexts are always hashes of message transcripts, this can
|
||||||
|
* be approximated from above by the maximum hash size. */
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN \
|
||||||
|
MBEDTLS_MD_MAX_SIZE
|
||||||
|
|
||||||
|
/* Maximum desired length for expanded key material generated
|
||||||
|
* by HKDF-Expand-Label.
|
||||||
|
*
|
||||||
|
* Warning: If this ever needs to be increased, the implementation
|
||||||
|
* ssl_tls1_3_hkdf_encode_label() in ssl_tls13_keys.c needs to be
|
||||||
|
* adjusted since it currently assumes that HKDF key expansion
|
||||||
|
* is never used with more than 255 Bytes of output. */
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN 255
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The \c HKDF-Expand-Label function from
|
||||||
|
* the TLS 1.3 standard RFC 8446.
|
||||||
|
*
|
||||||
|
* <tt>
|
||||||
|
* HKDF-Expand-Label( Secret, Label, Context, Length ) =
|
||||||
|
* HKDF-Expand( Secret, HkdfLabel, Length )
|
||||||
|
* </tt>
|
||||||
|
*
|
||||||
|
* \param hash_alg The identifier for the hash algorithm to use.
|
||||||
|
* \param secret The \c Secret argument to \c HKDF-Expand-Label.
|
||||||
|
* This must be a readable buffer of length \p slen Bytes.
|
||||||
|
* \param slen The length of \p secret in Bytes.
|
||||||
|
* \param label The \c Label argument to \c HKDF-Expand-Label.
|
||||||
|
* This must be a readable buffer of length \p llen Bytes.
|
||||||
|
* \param llen The length of \p label in Bytes.
|
||||||
|
* \param ctx The \c Context argument to \c HKDF-Expand-Label.
|
||||||
|
* This must be a readable buffer of length \p clen Bytes.
|
||||||
|
* \param clen The length of \p context in Bytes.
|
||||||
|
* \param buf The destination buffer to hold the expanded secret.
|
||||||
|
* This must be a writable buffer of length \p blen Bytes.
|
||||||
|
* \param blen The desired size of the expanded secret in Bytes.
|
||||||
|
*
|
||||||
|
* \returns \c 0 on success.
|
||||||
|
* \return A negative error code on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mbedtls_ssl_tls1_3_hkdf_expand_label(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *secret, size_t slen,
|
||||||
|
const unsigned char *label, size_t llen,
|
||||||
|
const unsigned char *ctx, size_t clen,
|
||||||
|
unsigned char *buf, size_t blen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function is part of the TLS 1.3 key schedule.
|
||||||
|
* It extracts key and IV for the actual client/server traffic
|
||||||
|
* from the client/server traffic secrets.
|
||||||
|
*
|
||||||
|
* From RFC 8446:
|
||||||
|
*
|
||||||
|
* <tt>
|
||||||
|
* [sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length)
|
||||||
|
* [sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length)*
|
||||||
|
* </tt>
|
||||||
|
*
|
||||||
|
* \param hash_alg The identifier for the hash algorithm to be used
|
||||||
|
* for the HKDF-based expansion of the secret.
|
||||||
|
* \param client_secret The client traffic secret.
|
||||||
|
* This must be a readable buffer of size \p slen Bytes
|
||||||
|
* \param server_secret The server traffic secret.
|
||||||
|
* This must be a readable buffer of size \p slen Bytes
|
||||||
|
* \param slen Length of the secrets \p client_secret and
|
||||||
|
* \p server_secret in Bytes.
|
||||||
|
* \param key_len The desired length of the key to be extracted in Bytes.
|
||||||
|
* \param iv_len The desired length of the IV to be extracted in Bytes.
|
||||||
|
* \param keys The address of the structure holding the generated
|
||||||
|
* keys and IVs.
|
||||||
|
*
|
||||||
|
* \returns \c 0 on success.
|
||||||
|
* \returns A negative error code on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mbedtls_ssl_tls1_3_make_traffic_keys(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *client_secret,
|
||||||
|
const unsigned char *server_secret,
|
||||||
|
size_t slen, size_t key_len, size_t iv_len,
|
||||||
|
mbedtls_ssl_key_set *keys );
|
||||||
|
|
||||||
|
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED 0
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The \c Derive-Secret function from the TLS 1.3 standard RFC 8446.
|
||||||
|
*
|
||||||
|
* <tt>
|
||||||
|
* Derive-Secret( Secret, Label, Messages ) =
|
||||||
|
* HKDF-Expand-Label( Secret, Label,
|
||||||
|
* Hash( Messages ),
|
||||||
|
* Hash.Length ) )
|
||||||
|
* </tt>
|
||||||
|
*
|
||||||
|
* \param hash_alg The identifier for the hash function used for the
|
||||||
|
* applications of HKDF.
|
||||||
|
* \param secret The \c Secret argument to the \c Derive-Secret function.
|
||||||
|
* This must be a readable buffer of length \p slen Bytes.
|
||||||
|
* \param slen The length of \p secret in Bytes.
|
||||||
|
* \param label The \c Label argument to the \c Derive-Secret function.
|
||||||
|
* This must be a readable buffer of length \p llen Bytes.
|
||||||
|
* \param llen The length of \p label in Bytes.
|
||||||
|
* \param ctx The hash of the \c Messages argument to the
|
||||||
|
* \c Derive-Secret function, or the \c Messages argument
|
||||||
|
* itself, depending on \p context_already_hashed.
|
||||||
|
* \param clen The length of \p hash.
|
||||||
|
* \param ctx_hashed This indicates whether the \p ctx contains the hash of
|
||||||
|
* the \c Messages argument in the application of the
|
||||||
|
* \c Derive-Secret function
|
||||||
|
* (value MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED), or whether
|
||||||
|
* it is the content of \c Messages itself, in which case
|
||||||
|
* the function takes care of the hashing
|
||||||
|
* (value MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED).
|
||||||
|
* \param dstbuf The target buffer to write the output of
|
||||||
|
* \c Derive-Secret to. This must be a writable buffer of
|
||||||
|
* size \p buflen Bytes.
|
||||||
|
* \param buflen The length of \p dstbuf in Bytes.
|
||||||
|
*
|
||||||
|
* \returns \c 0 on success.
|
||||||
|
* \returns A negative error code on failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ssl_tls1_3_derive_secret(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *secret, size_t slen,
|
||||||
|
const unsigned char *label, size_t llen,
|
||||||
|
const unsigned char *ctx, size_t clen,
|
||||||
|
int ctx_hashed,
|
||||||
|
unsigned char *dstbuf, size_t buflen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Compute the next secret in the TLS 1.3 key schedule
|
||||||
|
*
|
||||||
|
* The TLS 1.3 key schedule proceeds as follows to compute
|
||||||
|
* the three main secrets during the handshake: The early
|
||||||
|
* secret for early data, the handshake secret for all
|
||||||
|
* other encrypted handshake messages, and the master
|
||||||
|
* secret for all application traffic.
|
||||||
|
*
|
||||||
|
* <tt>
|
||||||
|
* 0
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* PSK -> HKDF-Extract = Early Secret
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* Derive-Secret( ., "derived", "" )
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* (EC)DHE -> HKDF-Extract = Handshake Secret
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* Derive-Secret( ., "derived", "" )
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* 0 -> HKDF-Extract = Master Secret
|
||||||
|
* </tt>
|
||||||
|
*
|
||||||
|
* Each of the three secrets in turn is the basis for further
|
||||||
|
* key derivations, such as the derivation of traffic keys and IVs;
|
||||||
|
* see e.g. mbedtls_ssl_tls1_3_make_traffic_keys().
|
||||||
|
*
|
||||||
|
* This function implements one step in this evolution of secrets:
|
||||||
|
*
|
||||||
|
* <tt>
|
||||||
|
* old_secret
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* Derive-Secret( ., "derived", "" )
|
||||||
|
* |
|
||||||
|
* v
|
||||||
|
* input -> HKDF-Extract = new_secret
|
||||||
|
* </tt>
|
||||||
|
*
|
||||||
|
* \param hash_alg The identifier for the hash function used for the
|
||||||
|
* applications of HKDF.
|
||||||
|
* \param secret_old The address of the buffer holding the old secret
|
||||||
|
* on function entry. If not \c NULL, this must be a
|
||||||
|
* readable buffer whose size matches the output size
|
||||||
|
* of the hash function represented by \p hash_alg.
|
||||||
|
* If \c NULL, an all \c 0 array will be used instead.
|
||||||
|
* \param input The address of the buffer holding the additional
|
||||||
|
* input for the key derivation (e.g., the PSK or the
|
||||||
|
* ephemeral (EC)DH secret). If not \c NULL, this must be
|
||||||
|
* a readable buffer whose size \p input_len Bytes.
|
||||||
|
* If \c NULL, an all \c 0 array will be used instead.
|
||||||
|
* \param input_len The length of \p input in Bytes.
|
||||||
|
* \param secret_new The address of the buffer holding the new secret
|
||||||
|
* on function exit. This must be a writable buffer
|
||||||
|
* whose size matches the output size of the hash
|
||||||
|
* function represented by \p hash_alg.
|
||||||
|
* This may be the same as \p secret_old.
|
||||||
|
*
|
||||||
|
* \returns \c 0 on success.
|
||||||
|
* \returns A negative error code on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mbedtls_ssl_tls1_3_evolve_secret(
|
||||||
|
mbedtls_md_type_t hash_alg,
|
||||||
|
const unsigned char *secret_old,
|
||||||
|
const unsigned char *input, size_t input_len,
|
||||||
|
unsigned char *secret_new );
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
|
|
@ -10398,6 +10398,132 @@ Decrypt CBC !EtM, 3DES SHA384 trunc, padlen=255
|
||||||
depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:!MBEDTLS_SHA512_NO_SHA384
|
depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:!MBEDTLS_SHA512_NO_SHA384
|
||||||
ssl_decrypt_non_etm_cbc:MBEDTLS_CIPHER_DES_EDE3_CBC:MBEDTLS_MD_SHA384:1:255
|
ssl_decrypt_non_etm_cbc:MBEDTLS_CIPHER_DES_EDE3_CBC:MBEDTLS_MD_SHA384:1:255
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Secret evolution #1
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Initial secret to Early Secret
|
||||||
|
depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
|
||||||
|
ssl_tls1_3_key_evolution:MBEDTLS_MD_SHA256:"":"":"33ad0a1c607ec03b09e6cd9893680ce210adf300aa1f2660e1b22e10f170f92a"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Secret evolution #2
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Early secret to Handshake Secret
|
||||||
|
ssl_tls1_3_key_evolution:MBEDTLS_MD_SHA256:"33ad0a1c607ec03b09e6cd9893680ce210adf300aa1f2660e1b22e10f170f92a":"df4a291baa1eb7cfa6934b29b474baad2697e29f1f920dcc77c8a0a088447624":"fb9fc80689b3a5d02c33243bf69a1b1b20705588a794304a6e7120155edf149a"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Secret evolution #3
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Handshake secret to Master Secret
|
||||||
|
ssl_tls1_3_key_evolution:MBEDTLS_MD_SHA256:"fb9fc80689b3a5d02c33243bf69a1b1b20705588a794304a6e7120155edf149a":"":"7f2882bb9b9a46265941653e9c2f19067118151e21d12e57a7b6aca1f8150c8d"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #1
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Server handshake traffic secret -> Server traffic key
|
||||||
|
# HKDF-Expand-Label(server_handshake_secret, "key", "", 16)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"a2067265e7f0652a923d5d72ab0467c46132eeb968b6a32d311c805868548814":tls1_3_label_key:"":16:"844780a7acad9f980fa25c114e43402a"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #2
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Server handshake traffic secret -> Server traffic IV
|
||||||
|
# HKDF-Expand-Label(server_handshake_secret, "iv", "", 12)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"a2067265e7f0652a923d5d72ab0467c46132eeb968b6a32d311c805868548814":tls1_3_label_iv:"":12:"4c042ddc120a38d1417fc815"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #3
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Client handshake traffic secret -> Client traffic key
|
||||||
|
# HKDF-Expand-Label(client_handshake_secret, "key", "", 16)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"ff0e5b965291c608c1e8cd267eefc0afcc5e98a2786373f0db47b04786d72aea":tls1_3_label_key:"":16:"7154f314e6be7dc008df2c832baa1d39"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #4
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Client handshake traffic secret -> Client traffic IV
|
||||||
|
# HKDF-Expand-Label(client_handshake_secret, "iv", "", 12)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"ff0e5b965291c608c1e8cd267eefc0afcc5e98a2786373f0db47b04786d72aea":tls1_3_label_iv:"":12:"71abc2cae4c699d47c600268"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #5 (RFC 8448)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
# Server handshake traffic secret -> Server traffic IV
|
||||||
|
# HKDF-Expand-Label(server_handshake_secret, "iv", "", 12)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"b67b7d690cc16c4e75e54213cb2d37b4e9c912bcded9105d42befd59d391ad38":tls1_3_label_iv:"":12:"5d313eb2671276ee13000b30"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #6 (RFC 8448)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
# Server handshake traffic secret -> Server traffic Key
|
||||||
|
# HKDF-Expand-Label(server_handshake_secret, "key", "", 16)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"b67b7d690cc16c4e75e54213cb2d37b4e9c912bcded9105d42befd59d391ad38":tls1_3_label_key:"":16:"3fce516009c21727d0f2e4e86ee403bc"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #7 (RFC 8448)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
# Client handshake traffic secret -> Client traffic IV
|
||||||
|
# HKDF-Expand-Label(client_handshake_secret, "iv", "", 12)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"b3eddb126e067f35a780b3abf45e2d8f3b1a950738f52e9600746a0e27a55a21":tls1_3_label_iv:"":12:"5bd3c71b836e0b76bb73265f"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #8 (RFC 8448)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
# Client handshake traffic secret -> Client traffic Key
|
||||||
|
# HKDF-Expand-Label(client_handshake_secret, "key", "", 16)
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"b3eddb126e067f35a780b3abf45e2d8f3b1a950738f52e9600746a0e27a55a21":tls1_3_label_key:"":16:"dbfaa693d1762c5b666af5d950258d01"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #9 (RFC 8448)
|
||||||
|
# Calculation of finished_key
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"2faac08f851d35fea3604fcb4de82dc62c9b164a70974d0462e27f1ab278700f":tls1_3_label_finished:"":32:"5ace394c26980d581243f627d1150ae27e37fa52364e0a7f20ac686d09cd0e8e"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: HKDF Expand Label #10 (RFC 8448)
|
||||||
|
# Calculation of resumption key
|
||||||
|
ssl_tls1_3_hkdf_expand_label:MBEDTLS_MD_SHA256:"7df235f2031d2a051287d02b0241b0bfdaf86cc856231f2d5aba46c434ec196c":tls1_3_label_resumption:"0000":32:"4ecd0eb6ec3b4d87f5d6028f922ca4c5851a277fd41311c9e62d2c9492e1c4f3"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Traffic key generation #1
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Client/Server handshake traffic secrets -> Client/Server traffic {Key,IV}
|
||||||
|
ssl_tls1_3_traffic_key_generation:MBEDTLS_MD_SHA256:"a2067265e7f0652a923d5d72ab0467c46132eeb968b6a32d311c805868548814":"ff0e5b965291c608c1e8cd267eefc0afcc5e98a2786373f0db47b04786d72aea":12:16:"844780a7acad9f980fa25c114e43402a":"4c042ddc120a38d1417fc815":"7154f314e6be7dc008df2c832baa1d39":"71abc2cae4c699d47c600268"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Traffic key generation #2 (RFC 8448)
|
||||||
|
# Vector RFC 8448
|
||||||
|
# Client/Server handshake traffic secrets -> Client/Server traffic {Key,IV}
|
||||||
|
ssl_tls1_3_traffic_key_generation:MBEDTLS_MD_SHA256:"a2067265e7f0652a923d5d72ab0467c46132eeb968b6a32d311c805868548814":"ff0e5b965291c608c1e8cd267eefc0afcc5e98a2786373f0db47b04786d72aea":12:16:"844780a7acad9f980fa25c114e43402a":"4c042ddc120a38d1417fc815":"7154f314e6be7dc008df2c832baa1d39":"71abc2cae4c699d47c600268"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "derived", "")
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Derive-Secret( Early-Secret, "derived", "")
|
||||||
|
# Tests the case where context isn't yet hashed (empty string here,
|
||||||
|
# but still needs to be hashed)
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"33ad0a1c607ec03b09e6cd9893680ce210adf300aa1f2660e1b22e10f170f92a":tls1_3_label_derived:"":32:MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED:"6f2615a108c702c5678f54fc9dbab69716c076189c48250cebeac3576c3611ba"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "s ap traffic", hash) #1
|
||||||
|
# Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
|
||||||
|
# Derive-Secret( MasterSecret, "s ap traffic", hash)
|
||||||
|
# Tests the case where context is already hashed
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"7f2882bb9b9a46265941653e9c2f19067118151e21d12e57a7b6aca1f8150c8d":tls1_3_label_s_ap_traffic:"22844b930e5e0a59a09d5ac35fc032fc91163b193874a265236e568077378d8b":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"3fc35ea70693069a277956afa23b8f4543ce68ac595f2aace05cd7a1c92023d5"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "c e traffic", hash)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"9b2188e9b2fc6d64d71dc329900e20bb41915000f678aa839cbb797cb7d8332c":tls1_3_label_c_e_traffic:"08ad0fa05d7c7233b1775ba2ff9f4c5b8b59276b7f227f13a976245f5d960913":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"3fbbe6a60deb66c30a32795aba0eff7eaa10105586e7be5c09678d63b6caab62"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "e exp master", hash)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"9b2188e9b2fc6d64d71dc329900e20bb41915000f678aa839cbb797cb7d8332c":tls1_3_label_e_exp_master:"08ad0fa05d7c7233b1775ba2ff9f4c5b8b59276b7f227f13a976245f5d960913":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"b2026866610937d7423e5be90862ccf24c0e6091186d34f812089ff5be2ef7df"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "c hs traffic", hash)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"005cb112fd8eb4ccc623bb88a07c64b3ede1605363fc7d0df8c7ce4ff0fb4ae6":tls1_3_label_c_hs_traffic:"f736cb34fe25e701551bee6fd24c1cc7102a7daf9405cb15d97aafe16f757d03"::32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"2faac08f851d35fea3604fcb4de82dc62c9b164a70974d0462e27f1ab278700f"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "s hs traffic", hash)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"005cb112fd8eb4ccc623bb88a07c64b3ede1605363fc7d0df8c7ce4ff0fb4ae6":tls1_3_label_s_hs_traffic:"f736cb34fe25e701551bee6fd24c1cc7102a7daf9405cb15d97aafe16f757d03":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"fe927ae271312e8bf0275b581c54eef020450dc4ecffaa05a1a35d27518e7803"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "c ap traffic", hash)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"e2d32d4ed66dd37897a0e80c84107503ce58bf8aad4cb55a5002d77ecb890ece":tls1_3_label_c_ap_traffic:"b0aeffc46a2cfe33114e6fd7d51f9f04b1ca3c497dab08934a774a9d9ad7dbf3":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"2abbf2b8e381d23dbebe1dd2a7d16a8bf484cb4950d23fb7fb7fa8547062d9a1"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "s ap traffic", hash) #2
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"e2d32d4ed66dd37897a0e80c84107503ce58bf8aad4cb55a5002d77ecb890ece":tls1_3_label_s_ap_traffic:"b0aeffc46a2cfe33114e6fd7d51f9f04b1ca3c497dab08934a774a9d9ad7dbf3":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"cc21f1bf8feb7dd5fa505bd9c4b468a9984d554a993dc49e6d285598fb672691"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "exp master", hash)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"e2d32d4ed66dd37897a0e80c84107503ce58bf8aad4cb55a5002d77ecb890ece":tls1_3_label_exp_master:"b0aeffc46a2cfe33114e6fd7d51f9f04b1ca3c497dab08934a774a9d9ad7dbf3":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"3fd93d4ffddc98e64b14dd107aedf8ee4add23f4510f58a4592d0b201bee56b4"
|
||||||
|
|
||||||
|
SSL TLS 1.3 Key schedule: Derive-Secret( ., "res master", hash)
|
||||||
|
# Vector from RFC 8448
|
||||||
|
ssl_tls1_3_derive_secret:MBEDTLS_MD_SHA256:"e2d32d4ed66dd37897a0e80c84107503ce58bf8aad4cb55a5002d77ecb890ece":tls1_3_label_res_master:"c3c122e0bd907a4a3ff6112d8fd53dbf89c773d9552e8b6b9d56d361b3a97bf6":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"5e95bdf1f89005ea2e9aa0ba85e728e3c19c5fe0c699e3f5bee59faebd0b5406"
|
||||||
|
|
||||||
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_NONE
|
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_NONE
|
||||||
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_NONE:"":"":"test tls_prf label":"":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
|
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_NONE:"":"":"test tls_prf label":"":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
|
||||||
|
|
|
@ -6,11 +6,20 @@
|
||||||
#include <mbedtls/certs.h>
|
#include <mbedtls/certs.h>
|
||||||
#include <mbedtls/timing.h>
|
#include <mbedtls/timing.h>
|
||||||
#include <mbedtls/debug.h>
|
#include <mbedtls/debug.h>
|
||||||
|
#include <ssl_tls13_keys.h>
|
||||||
|
|
||||||
#include <ssl_invasive.h>
|
#include <ssl_invasive.h>
|
||||||
|
|
||||||
#include <test/constant_flow.h>
|
#include <test/constant_flow.h>
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
|
||||||
|
tls1_3_label_ ## name,
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||||
|
#undef MBEDTLS_SSL_TLS1_3_LABEL
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct log_pattern
|
typedef struct log_pattern
|
||||||
{
|
{
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
|
@ -3669,6 +3678,150 @@ exit:
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
|
||||||
|
void ssl_tls1_3_hkdf_expand_label( int hash_alg,
|
||||||
|
data_t *secret,
|
||||||
|
int label_idx,
|
||||||
|
data_t *ctx,
|
||||||
|
int desired_length,
|
||||||
|
data_t *expected )
|
||||||
|
{
|
||||||
|
unsigned char dst[ 100 ];
|
||||||
|
|
||||||
|
unsigned char const *lbl = NULL;
|
||||||
|
size_t lbl_len;
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
|
||||||
|
if( label_idx == (int) tls1_3_label_ ## name ) \
|
||||||
|
{ \
|
||||||
|
lbl = mbedtls_ssl_tls1_3_labels.name; \
|
||||||
|
lbl_len = sizeof( mbedtls_ssl_tls1_3_labels.name ); \
|
||||||
|
}
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||||
|
#undef MBEDTLS_SSL_TLS1_3_LABEL
|
||||||
|
TEST_ASSERT( lbl != NULL );
|
||||||
|
|
||||||
|
/* Check sanity of test parameters. */
|
||||||
|
TEST_ASSERT( (size_t) desired_length <= sizeof(dst) );
|
||||||
|
TEST_ASSERT( (size_t) desired_length == expected->len );
|
||||||
|
|
||||||
|
TEST_ASSERT( mbedtls_ssl_tls1_3_hkdf_expand_label(
|
||||||
|
(mbedtls_md_type_t) hash_alg,
|
||||||
|
secret->x, secret->len,
|
||||||
|
lbl, lbl_len,
|
||||||
|
ctx->x, ctx->len,
|
||||||
|
dst, desired_length ) == 0 );
|
||||||
|
|
||||||
|
ASSERT_COMPARE( dst, (size_t) desired_length,
|
||||||
|
expected->x, (size_t) expected->len );
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
|
||||||
|
void ssl_tls1_3_traffic_key_generation( int hash_alg,
|
||||||
|
data_t *server_secret,
|
||||||
|
data_t *client_secret,
|
||||||
|
int desired_iv_len,
|
||||||
|
int desired_key_len,
|
||||||
|
data_t *expected_server_write_key,
|
||||||
|
data_t *expected_server_write_iv,
|
||||||
|
data_t *expected_client_write_key,
|
||||||
|
data_t *expected_client_write_iv )
|
||||||
|
{
|
||||||
|
mbedtls_ssl_key_set keys;
|
||||||
|
|
||||||
|
/* Check sanity of test parameters. */
|
||||||
|
TEST_ASSERT( client_secret->len == server_secret->len );
|
||||||
|
TEST_ASSERT( expected_client_write_iv->len == expected_server_write_iv->len &&
|
||||||
|
expected_client_write_iv->len == (size_t) desired_iv_len );
|
||||||
|
TEST_ASSERT( expected_client_write_key->len == expected_server_write_key->len &&
|
||||||
|
expected_client_write_key->len == (size_t) desired_key_len );
|
||||||
|
|
||||||
|
TEST_ASSERT( mbedtls_ssl_tls1_3_make_traffic_keys(
|
||||||
|
(mbedtls_md_type_t) hash_alg,
|
||||||
|
client_secret->x,
|
||||||
|
server_secret->x,
|
||||||
|
client_secret->len /* == server_secret->len */,
|
||||||
|
desired_key_len, desired_iv_len,
|
||||||
|
&keys ) == 0 );
|
||||||
|
|
||||||
|
ASSERT_COMPARE( keys.client_write_key,
|
||||||
|
keys.key_len,
|
||||||
|
expected_client_write_key->x,
|
||||||
|
(size_t) desired_key_len );
|
||||||
|
ASSERT_COMPARE( keys.server_write_key,
|
||||||
|
keys.key_len,
|
||||||
|
expected_server_write_key->x,
|
||||||
|
(size_t) desired_key_len );
|
||||||
|
ASSERT_COMPARE( keys.client_write_iv,
|
||||||
|
keys.iv_len,
|
||||||
|
expected_client_write_iv->x,
|
||||||
|
(size_t) desired_iv_len );
|
||||||
|
ASSERT_COMPARE( keys.server_write_iv,
|
||||||
|
keys.iv_len,
|
||||||
|
expected_server_write_iv->x,
|
||||||
|
(size_t) desired_iv_len );
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
|
||||||
|
void ssl_tls1_3_derive_secret( int hash_alg,
|
||||||
|
data_t *secret,
|
||||||
|
int label_idx,
|
||||||
|
data_t *ctx,
|
||||||
|
int desired_length,
|
||||||
|
int already_hashed,
|
||||||
|
data_t *expected )
|
||||||
|
{
|
||||||
|
unsigned char dst[ 100 ];
|
||||||
|
|
||||||
|
unsigned char const *lbl = NULL;
|
||||||
|
size_t lbl_len;
|
||||||
|
#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
|
||||||
|
if( label_idx == (int) tls1_3_label_ ## name ) \
|
||||||
|
{ \
|
||||||
|
lbl = mbedtls_ssl_tls1_3_labels.name; \
|
||||||
|
lbl_len = sizeof( mbedtls_ssl_tls1_3_labels.name ); \
|
||||||
|
}
|
||||||
|
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||||
|
#undef MBEDTLS_SSL_TLS1_3_LABEL
|
||||||
|
TEST_ASSERT( lbl != NULL );
|
||||||
|
|
||||||
|
/* Check sanity of test parameters. */
|
||||||
|
TEST_ASSERT( (size_t) desired_length <= sizeof(dst) );
|
||||||
|
TEST_ASSERT( (size_t) desired_length == expected->len );
|
||||||
|
|
||||||
|
TEST_ASSERT( mbedtls_ssl_tls1_3_derive_secret(
|
||||||
|
(mbedtls_md_type_t) hash_alg,
|
||||||
|
secret->x, secret->len,
|
||||||
|
lbl, lbl_len,
|
||||||
|
ctx->x, ctx->len,
|
||||||
|
already_hashed,
|
||||||
|
dst, desired_length ) == 0 );
|
||||||
|
|
||||||
|
ASSERT_COMPARE( dst, desired_length,
|
||||||
|
expected->x, desired_length );
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
|
||||||
|
void ssl_tls1_3_key_evolution( int hash_alg,
|
||||||
|
data_t *secret,
|
||||||
|
data_t *input,
|
||||||
|
data_t *expected )
|
||||||
|
{
|
||||||
|
unsigned char secret_new[ MBEDTLS_MD_MAX_SIZE ];
|
||||||
|
|
||||||
|
TEST_ASSERT( mbedtls_ssl_tls1_3_evolve_secret(
|
||||||
|
(mbedtls_md_type_t) hash_alg,
|
||||||
|
secret->len ? secret->x : NULL,
|
||||||
|
input->len ? input->x : NULL, input->len,
|
||||||
|
secret_new ) == 0 );
|
||||||
|
|
||||||
|
ASSERT_COMPARE( secret_new, (size_t) expected->len,
|
||||||
|
expected->x, (size_t) expected->len );
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
/* BEGIN_CASE */
|
/* BEGIN_CASE */
|
||||||
void ssl_tls_prf( int type, data_t * secret, data_t * random,
|
void ssl_tls_prf( int type, data_t * secret, data_t * random,
|
||||||
char *label, data_t *result_hex_str, int exp_ret )
|
char *label, data_t *result_hex_str, int exp_ret )
|
||||||
|
|
|
@ -252,6 +252,7 @@
|
||||||
<ClInclude Include="..\..\library\psa_crypto_slot_management.h" />
|
<ClInclude Include="..\..\library\psa_crypto_slot_management.h" />
|
||||||
<ClInclude Include="..\..\library\psa_crypto_storage.h" />
|
<ClInclude Include="..\..\library\psa_crypto_storage.h" />
|
||||||
<ClInclude Include="..\..\library\ssl_invasive.h" />
|
<ClInclude Include="..\..\library\ssl_invasive.h" />
|
||||||
|
<ClInclude Include="..\..\library\ssl_tls13_keys.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\everest\include\everest\everest.h" />
|
<ClInclude Include="..\..\3rdparty\everest\include\everest\everest.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\everest\include\everest\Hacl_Curve25519.h" />
|
<ClInclude Include="..\..\3rdparty\everest\include\everest\Hacl_Curve25519.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\everest\include\everest\kremlib.h" />
|
<ClInclude Include="..\..\3rdparty\everest\include\everest\kremlib.h" />
|
||||||
|
@ -331,6 +332,7 @@
|
||||||
<ClCompile Include="..\..\library\ssl_srv.c" />
|
<ClCompile Include="..\..\library\ssl_srv.c" />
|
||||||
<ClCompile Include="..\..\library\ssl_ticket.c" />
|
<ClCompile Include="..\..\library\ssl_ticket.c" />
|
||||||
<ClCompile Include="..\..\library\ssl_tls.c" />
|
<ClCompile Include="..\..\library\ssl_tls.c" />
|
||||||
|
<ClCompile Include="..\..\library\ssl_tls13_keys.c" />
|
||||||
<ClCompile Include="..\..\library\threading.c" />
|
<ClCompile Include="..\..\library\threading.c" />
|
||||||
<ClCompile Include="..\..\library\timing.c" />
|
<ClCompile Include="..\..\library\timing.c" />
|
||||||
<ClCompile Include="..\..\library\version.c" />
|
<ClCompile Include="..\..\library\version.c" />
|
||||||
|
|
Loading…
Reference in a new issue