Merge pull request #6264 from hannestschofenig/rfc9146_2

CID update to RFC 9146
This commit is contained in:
Manuel Pégourié-Gonnard 2022-11-29 09:25:14 +01:00 committed by GitHub
commit ffc330fafa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 259 additions and 79 deletions

View file

@ -903,6 +903,19 @@
#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && \
!defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0
#if defined(MBEDTLS_DEPRECATED_REMOVED)
#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS"
#elif defined(MBEDTLS_DEPRECATED_WARNING)
#warning "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS"
#endif
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0 */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites"

View file

@ -1325,21 +1325,16 @@
/**
* \def MBEDTLS_SSL_DTLS_CONNECTION_ID
*
* Enable support for the DTLS Connection ID extension
* (version draft-ietf-tls-dtls-connection-id-05,
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05)
* Enable support for the DTLS Connection ID (CID) extension,
* which allows to identify DTLS connections across changes
* in the underlying transport.
* in the underlying transport. The CID functionality is described
* in RFC 9146.
*
* Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`,
* mbedtls_ssl_get_own_cid()`, `mbedtls_ssl_get_peer_cid()` and
* `mbedtls_ssl_conf_cid()`. See the corresponding documentation for
* more information.
*
* \warning The Connection ID extension is still in draft state.
* We make no stability promises for the availability
* or the shape of the API controlled by this option.
*
* The maximum lengths of outgoing and incoming CIDs can be configured
* through the options
* - MBEDTLS_SSL_CID_OUT_LEN_MAX
@ -1349,7 +1344,30 @@
*
* Uncomment to enable the Connection ID extension.
*/
//#define MBEDTLS_SSL_DTLS_CONNECTION_ID
#define MBEDTLS_SSL_DTLS_CONNECTION_ID
/**
* \def MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
*
* Defines whether RFC 9146 (default) or the legacy version
* (version draft-ietf-tls-dtls-connection-id-05,
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05)
* is used.
*
* Set the value to 0 for the standard version, and
* 1 for the legacy draft version.
*
* \deprecated Support for the legacy version of the DTLS
* Connection ID feature is deprecated. Please
* switch to the standardized version defined
* in RFC 9146 enabled by utilizing
* MBEDTLS_SSL_DTLS_CONNECTION_ID without use
* of MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT.
*
* Requires: MBEDTLS_SSL_DTLS_CONNECTION_ID
*/
#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0
/**
* \def MBEDTLS_SSL_ASYNC_PRIVATE
@ -3697,17 +3715,6 @@
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
/** \def MBEDTLS_TLS_EXT_CID
*
* At the time of writing, the CID extension has not been assigned its
* final value. Set this configuration option to make Mbed TLS use a
* different value.
*
* A future minor revision of Mbed TLS may change the default value of
* this option to match evolving standards and usage.
*/
//#define MBEDTLS_TLS_EXT_CID 254
/**
* Complete list of ciphersuites to use, in order of preference.
*

View file

@ -408,6 +408,14 @@
/** \} name SECTION: Module settings */
/*
* Default to standard CID mode
*/
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
!defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT)
#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0
#endif
/*
* Length of the verify data for secure renegotiation
*/
@ -576,15 +584,10 @@
#define MBEDTLS_TLS_EXT_SIG_ALG_CERT 50 /* RFC 8446 TLS 1.3 */
#define MBEDTLS_TLS_EXT_KEY_SHARE 51 /* RFC 8446 TLS 1.3 */
/* The value of the CID extension is still TBD as of
* draft-ietf-tls-dtls-connection-id-05
* (https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05).
*
* A future minor revision of Mbed TLS may change the default value of
* this option to match evolving standards and usage.
*/
#if !defined(MBEDTLS_TLS_EXT_CID)
#define MBEDTLS_TLS_EXT_CID 254 /* TBD */
#if MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
#define MBEDTLS_TLS_EXT_CID 54 /* RFC 9146 DTLS 1.2 CID */
#else
#define MBEDTLS_TLS_EXT_CID 254 /* Pre-RFC 9146 DTLS 1.2 CID */
#endif
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */
@ -2074,8 +2077,9 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
* \brief Configure the use of the Connection ID (CID)
* extension in the next handshake.
*
* Reference: draft-ietf-tls-dtls-connection-id-05
* Reference: RFC 9146 (or draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
* for legacy version)
*
* The DTLS CID extension allows the reliable association of
* DTLS records to DTLS connections across changes in the

View file

@ -382,30 +382,80 @@ static int ssl_parse_inner_plaintext( unsigned char const *content,
}
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || MBEDTLS_SSL_PROTO_TLS1_3 */
/* `add_data` must have size 13 Bytes if the CID extension is disabled,
* and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
/* The size of the `add_data` structure depends on various
* factors, namely
*
* 1) CID functionality disabled
*
* additional_data =
* 8: seq_num +
* 1: type +
* 2: version +
* 2: length of inner plaintext +
*
* size = 13 bytes
*
* 2) CID functionality based on RFC 9146 enabled
*
* size = 8 + 1 + 1 + 1 + 2 + 2 + 6 + 2 + CID-length
* = 23 + CID-length
*
* 3) CID functionality based on legacy CID version
according to draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* size = 13 + 1 + CID-length
*
* More information about the CID usage:
*
* Per Section 5.3 of draft-ietf-tls-dtls-connection-id-05 the
* size of the additional data structure is calculated as:
*
* additional_data =
* 8: seq_num +
* 1: tls12_cid +
* 2: DTLSCipherText.version +
* n: cid +
* 1: cid_length +
* 2: length_of_DTLSInnerPlaintext
*
* Per RFC 9146 the size of the add_data structure is calculated as:
*
* additional_data =
* 8: seq_num_placeholder +
* 1: tls12_cid +
* 1: cid_length +
* 1: tls12_cid +
* 2: DTLSCiphertext.version +
* 2: epoch +
* 6: sequence_number +
* n: cid +
* 2: length_of_DTLSInnerPlaintext
*
*/
static void ssl_extract_add_data_from_record( unsigned char* add_data,
size_t *add_data_len,
mbedtls_record *rec,
mbedtls_ssl_protocol_version
tls_version,
tls_version,
size_t taglen )
{
/* Quoting RFC 5246 (TLS 1.2):
/* Several types of ciphers have been defined for use with TLS and DTLS,
* and the MAC calculations for those ciphers differ slightly. Further
* variants were added when the CID functionality was added with RFC 9146.
* This implementations also considers the use of a legacy version of the
* CID specification published in draft-ietf-tls-dtls-connection-id-05,
* which is used in deployments.
*
* We will distinguish between the non-CID and the CID cases below.
*
* --- Non-CID cases ---
*
* Quoting RFC 5246 (TLS 1.2):
*
* additional_data = seq_num + TLSCompressed.type +
* TLSCompressed.version + TLSCompressed.length;
*
* For the CID extension, this is extended as follows
* (quoting draft-ietf-tls-dtls-connection-id-05,
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
*
* additional_data = seq_num + DTLSPlaintext.type +
* DTLSPlaintext.version +
* cid +
* cid_length +
* length_of_DTLSInnerPlaintext;
*
* For TLS 1.3, the record sequence number is dropped from the AAD
* and encoded within the nonce of the AEAD operation instead.
* Moreover, the additional data involves the length of the TLS
@ -421,11 +471,72 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data,
*
* TLSCiphertext.length = TLSInnerPlaintext.length + taglen.
*
*/
* --- CID cases ---
*
* RFC 9146 uses a common pattern when constructing the data
* passed into a MAC / AEAD cipher.
*
* Data concatenation for MACs used with block ciphers with
* Encrypt-then-MAC Processing (with CID):
*
* data = seq_num_placeholder +
* tls12_cid +
* cid_length +
* tls12_cid +
* DTLSCiphertext.version +
* epoch +
* sequence_number +
* cid +
* DTLSCiphertext.length +
* IV +
* ENC(content + padding + padding_length)
*
* Data concatenation for MACs used with block ciphers (with CID):
*
* data = seq_num_placeholder +
* tls12_cid +
* cid_length +
* tls12_cid +
* DTLSCiphertext.version +
* epoch +
* sequence_number +
* cid +
* length_of_DTLSInnerPlaintext +
* DTLSInnerPlaintext.content +
* DTLSInnerPlaintext.real_type +
* DTLSInnerPlaintext.zeros
*
* AEAD ciphers use the following additional data calculation (with CIDs):
*
* additional_data = seq_num_placeholder +
* tls12_cid +
* cid_length +
* tls12_cid +
* DTLSCiphertext.version +
* epoch +
* sequence_number +
* cid +
* length_of_DTLSInnerPlaintext
*
* Section 5.3 of draft-ietf-tls-dtls-connection-id-05 (for legacy CID use)
* defines the additional data calculation as follows:
*
* additional_data = seq_num +
* tls12_cid +
* DTLSCipherText.version +
* cid +
* cid_length +
* length_of_DTLSInnerPlaintext
*/
unsigned char *cur = add_data;
size_t ad_len_field = rec->data_len;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
const unsigned char seq_num_placeholder[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if( tls_version == MBEDTLS_SSL_VERSION_TLS1_3 )
{
@ -439,25 +550,72 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data,
{
((void) tls_version);
((void) taglen);
memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
cur += sizeof( rec->ctr );
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
if( rec->cid_len != 0 )
{
// seq_num_placeholder
memcpy( cur, seq_num_placeholder, sizeof(seq_num_placeholder) );
cur += sizeof( seq_num_placeholder );
// tls12_cid type
*cur = rec->type;
cur++;
// cid_length
*cur = rec->cid_len;
cur++;
}
else
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
{
// epoch + sequence number
memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
cur += sizeof( rec->ctr );
}
}
// type
*cur = rec->type;
cur++;
// version
memcpy( cur, rec->ver, sizeof( rec->ver ) );
cur += sizeof( rec->ver );
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
if( rec->cid_len != 0 )
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 1
if (rec->cid_len != 0)
{
memcpy( cur, rec->cid, rec->cid_len );
// CID
memcpy(cur, rec->cid, rec->cid_len);
cur += rec->cid_len;
// cid_length
*cur = rec->cid_len;
cur++;
// length of inner plaintext
MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
cur += 2;
}
else
#elif defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
if( rec->cid_len != 0 )
{
// epoch + sequence number
memcpy(cur, rec->ctr, sizeof(rec->ctr));
cur += sizeof(rec->ctr);
// CID
memcpy( cur, rec->cid, rec->cid_len );
cur += rec->cid_len;
// length of inner plaintext
MBEDTLS_PUT_UINT16_BE( ad_len_field, cur, 0 );
cur += 2;
}
@ -532,7 +690,14 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
mbedtls_ssl_mode_t ssl_mode;
int auth_done = 0;
unsigned char * data;
unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
/* For an explanation of the additional data length see
* the descrpition of ssl_extract_add_data_from_record().
*/
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
unsigned char add_data[23 + MBEDTLS_SSL_CID_OUT_LEN_MAX];
#else
unsigned char add_data[13];
#endif
size_t add_data_len;
size_t post_avail;
@ -1015,13 +1180,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
size_t sign_mac_length = 0;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/*
* MAC(MAC_write_key, seq_num +
* TLSCipherText.type +
* TLSCipherText.version +
* length_of( (IV +) ENC(...) ) +
* IV +
* ENC(content + padding + padding_length));
/* MAC(MAC_write_key, add_data, IV, ENC(content + padding + padding_length))
*/
if( post_avail < transform->maclen)
@ -1129,7 +1288,14 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
size_t padlen = 0, correct = 1;
#endif
unsigned char* data;
unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ];
/* For an explanation of the additional data length see
* the descrpition of ssl_extract_add_data_from_record().
*/
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
unsigned char add_data[23 + MBEDTLS_SSL_CID_IN_LEN_MAX];
#else
unsigned char add_data[13];
#endif
size_t add_data_len;
#if !defined(MBEDTLS_DEBUG_C)
@ -3481,7 +3647,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
{
/* Shift pointers to account for record header including CID
* struct {
* ContentType special_type = tls12_cid;
* ContentType outer_type = tls12_cid;
* ProtocolVersion version;
* uint16 epoch;
* uint48 sequence_number;

View file

@ -226,9 +226,6 @@ static int ssl_write_cid_ext( mbedtls_ssl_context *ssl,
size_t ext_len;
/*
* Quoting draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* struct {
* opaque cid<0..2^8-1>;
* } ConnectionId;

View file

@ -376,9 +376,6 @@ static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
}
/*
* Quoting draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* struct {
* opaque cid<0..2^8-1>;
* } ConnectionId;
@ -1775,9 +1772,6 @@ static void ssl_write_cid_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding CID extension" ) );
/*
* Quoting draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* struct {
* opaque cid<0..2^8-1>;
* } ConnectionId;

View file

@ -34,6 +34,8 @@
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY
#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
/* Enable some invasive tests */
#define MBEDTLS_TEST_HOOKS

View file

@ -1246,6 +1246,7 @@ component_test_full_no_cipher () {
scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
scripts/config.py unset MBEDTLS_SSL_DTLS_ANTI_REPLAY
scripts/config.py unset MBEDTLS_SSL_DTLS_CONNECTION_ID
scripts/config.py unset MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py unset MBEDTLS_SSL_SRV_C
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
@ -2765,21 +2766,20 @@ component_test_variable_ssl_in_out_buffer_len () {
tests/compat.sh
}
component_test_variable_ssl_in_out_buffer_len_CID () {
msg "build: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled (ASan build)"
scripts/config.py set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
scripts/config.py set MBEDTLS_SSL_DTLS_CONNECTION_ID
component_test_dtls_cid_legacy () {
msg "build: MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled (ASan build)"
scripts/config.py set MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 1
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID"
msg "test: MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy)"
make test
msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled"
msg "test: ssl-opt.sh, MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled"
tests/ssl-opt.sh
msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled"
msg "test: compat.sh, MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled"
tests/compat.sh
}

View file

@ -2614,7 +2614,6 @@ run_test "Context serialization, client serializes, with CID" \
-c "Deserializing connection..." \
-S "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, server serializes, CCM" \
"$P_SRV dtls=1 serialize=1 exchanges=2" \
@ -2688,7 +2687,6 @@ run_test "Context serialization, both serialize, with CID" \
-c "Deserializing connection..." \
-s "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, re-init, client serializes, CCM" \
"$P_SRV dtls=1 serialize=0 exchanges=2" \
@ -2725,7 +2723,6 @@ run_test "Context serialization, re-init, client serializes, with CID" \
-c "Deserializing connection..." \
-S "Deserializing connection..."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
run_test "Context serialization, re-init, server serializes, CCM" \
"$P_SRV dtls=1 serialize=2 exchanges=2" \