diff --git a/docs/architecture/tls13-experimental.md b/docs/architecture/tls13-experimental.md new file mode 100644 index 000000000..bcf3e34f9 --- /dev/null +++ b/docs/architecture/tls13-experimental.md @@ -0,0 +1,40 @@ +TLS 1.3 Experimental Developments +================================= + +Overview +-------- + +Mbed TLS doesn't support the TLS 1.3 protocol yet, but a prototype is in development. +Stable parts of this prototype that can be independently tested are being successively +upstreamed under the guard of the following macro: + +``` +MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +``` + +This macro will likely be renamed to `MBEDTLS_SSL_PROTO_TLS1_3` once a minimal viable +implementation of the TLS 1.3 protocol is available. + +See the [documentation of `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL`](../../include/mbedtls/config.h) +for more information. + +Status +------ + +The following lists which parts of the TLS 1.3 prototype have already been upstreamed +together with their level of testing: + +* TLS 1.3 record protection mechanisms + + The record protection routines `mbedtls_ssl_{encrypt|decrypt}_buf()` have been extended + to support the modified TLS 1.3 record protection mechanism, including modified computation + of AAD, IV, and the introduction of a flexible padding. + + Those record protection routines have unit tests in `test_suite_ssl` alongside the + tests for the other record protection routines. + + TODO: Add some test vectors from RFC 8448. + +- 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` + independently of the development of the TLS 1.3 prototype. diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index fa3caa7c4..e2e45ac98 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -619,6 +619,11 @@ #error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && ( !defined(MBEDTLS_HKDF_C) && \ + !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL defined, but not all prerequisites" +#endif + #if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index de7c664e1..60a3aee55 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1706,6 +1706,25 @@ */ #define MBEDTLS_SSL_PROTO_TLS1_2 +/** + * \def MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + * + * This macro is used to selectively enable experimental parts + * of the code that contribute to the ongoing development of + * the prototype TLS 1.3 and DTLS 1.3 implementation, and provide + * no other purpose. + * + * \warning TLS 1.3 and DTLS 1.3 aren't yet supported in Mbed TLS, + * and no feature exposed through this macro is part of the + * public API. In particular, features under the control + * of this macro are experimental and don't come with any + * stability guarantees. + * + * Uncomment this macro to enable experimental and partial + * functionality specific to TLS 1.3. + */ +//#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + /** * \def MBEDTLS_SSL_PROTO_DTLS * @@ -3555,6 +3574,22 @@ */ //#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 +/** \def MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY + * + * This option controls the use of record plaintext padding + * in TLS 1.3. + * + * The padding will always be chosen so that the length of the + * padded plaintext is a multiple of the value of this option. + * + * Note: A value of \c 1 means that no padding will be used + * for outgoing records. + * + * Note: On systems lacking division instructions, + * a power of two should be preferred. + */ +//#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1 + /** \def MBEDTLS_SSL_OUT_CONTENT_LEN * * Maximum length (in bytes) of outgoing plaintext fragments. diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 7fec65e1d..65424d6d0 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -138,6 +138,7 @@ #define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */ #define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ #define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ +#define MBEDTLS_SSL_MINOR_VERSION_4 4 /*!< TLS v1.3 (experimental) */ #define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ #define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ @@ -276,6 +277,10 @@ #define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 #endif +#if !defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY) +#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1 +#endif + /* \} name SECTION: Module settings */ /* diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index e92381c33..cd881eb02 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -554,6 +554,10 @@ typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer; * time with the 8-byte record sequence number, without prepending the * latter to the encrypted record. * + * Additionally, DTLS 1.2 + CID as well as TLS 1.3 use an inner plaintext + * which allows to add flexible length padding and to hide a record's true + * content type. + * * In addition to type and version, the following parameters are relevant: * - The symmetric cipher algorithm to be used. * - The (static) encryption/decryption keys for the cipher. diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 976fc7b00..ae8d07653 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -341,15 +341,25 @@ static void ssl_read_memory( unsigned char *p, size_t len ) * Encryption/decryption functions */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -/* This functions transforms a DTLS plaintext fragment and a record content - * type into an instance of the DTLSInnerPlaintext structure: +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + +static size_t ssl_compute_padding_length( size_t len, + size_t granularity ) +{ + return( ( granularity - ( len + 1 ) % granularity ) % granularity ); +} + +/* This functions transforms a (D)TLS plaintext fragment and a record content + * type into an instance of the (D)TLSInnerPlaintext structure. This is used + * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect + * a record's content type. * * struct { * opaque content[DTLSPlaintext.length]; * ContentType real_type; * uint8 zeros[length_of_padding]; - * } DTLSInnerPlaintext; + * } (D)TLSInnerPlaintext; * * Input: * - `content`: The beginning of the buffer holding the @@ -360,23 +370,21 @@ static void ssl_read_memory( unsigned char *p, size_t len ) * - `rec_type`: The desired record content type. * * Output: - * - `content`: The beginning of the resulting DTLSInnerPlaintext structure. - * - `*content_size`: The length of the resulting DTLSInnerPlaintext structure. + * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure. + * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure. * * Returns: * - `0` on success. * - A negative error code if `max_len` didn't offer enough space * for the expansion. */ -static int ssl_cid_build_inner_plaintext( unsigned char *content, - size_t *content_size, - size_t remaining, - uint8_t rec_type ) +static int ssl_build_inner_plaintext( unsigned char *content, + size_t *content_size, + size_t remaining, + uint8_t rec_type, + size_t pad ) { size_t len = *content_size; - size_t pad = ( MBEDTLS_SSL_CID_PADDING_GRANULARITY - - ( len + 1 ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY ) % - MBEDTLS_SSL_CID_PADDING_GRANULARITY; /* Write real content type */ if( remaining == 0 ) @@ -395,9 +403,9 @@ static int ssl_cid_build_inner_plaintext( unsigned char *content, return( 0 ); } -/* This function parses a DTLSInnerPlaintext structure. - * See ssl_cid_build_inner_plaintext() for details. */ -static int ssl_cid_parse_inner_plaintext( unsigned char const *content, +/* This function parses a (D)TLSInnerPlaintext structure. + * See ssl_build_inner_plaintext() for details. */ +static int ssl_parse_inner_plaintext( unsigned char const *content, size_t *content_size, uint8_t *rec_type ) { @@ -416,13 +424,15 @@ static int ssl_cid_parse_inner_plaintext( unsigned char const *content, return( 0 ); } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || + MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ /* `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. */ static void ssl_extract_add_data_from_record( unsigned char* add_data, size_t *add_data_len, - mbedtls_record *rec ) + mbedtls_record *rec, + unsigned minor_ver ) { /* Quoting RFC 5246 (TLS 1.2): * @@ -438,28 +448,50 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data, * 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. */ - memcpy( add_data, rec->ctr, sizeof( rec->ctr ) ); - add_data[8] = rec->type; - memcpy( add_data + 9, rec->ver, sizeof( rec->ver ) ); + unsigned char *cur = add_data; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ) +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + { + ((void) minor_ver); + memcpy( cur, rec->ctr, sizeof( rec->ctr ) ); + cur += sizeof( rec->ctr ); + } + + *cur = rec->type; + cur++; + + memcpy( cur, rec->ver, sizeof( rec->ver ) ); + cur += sizeof( rec->ver ); #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) if( rec->cid_len != 0 ) { - memcpy( add_data + 11, rec->cid, rec->cid_len ); - add_data[11 + rec->cid_len + 0] = rec->cid_len; - add_data[11 + rec->cid_len + 1] = ( rec->data_len >> 8 ) & 0xFF; - add_data[11 + rec->cid_len + 2] = ( rec->data_len >> 0 ) & 0xFF; - *add_data_len = 13 + 1 + rec->cid_len; + memcpy( cur, rec->cid, rec->cid_len ); + cur += rec->cid_len; + + *cur = rec->cid_len; + cur++; + + cur[0] = ( rec->data_len >> 8 ) & 0xFF; + cur[1] = ( rec->data_len >> 0 ) & 0xFF; + cur += 2; } else #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ { - add_data[11 + 0] = ( rec->data_len >> 8 ) & 0xFF; - add_data[11 + 1] = ( rec->data_len >> 0 ) & 0xFF; - *add_data_len = 13; + cur[0] = ( rec->data_len >> 8 ) & 0xFF; + cur[1] = ( rec->data_len >> 0 ) & 0xFF; + cur += 2; } + + *add_data_len = cur - add_data; } #if defined(MBEDTLS_SSL_PROTO_SSL3) @@ -509,6 +541,57 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, } #endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_GCM_C) || \ + defined(MBEDTLS_CCM_C) || \ + defined(MBEDTLS_CHACHAPOLY_C) +static int ssl_transform_aead_dynamic_iv_is_explicit( + mbedtls_ssl_transform const *transform ) +{ + return( transform->ivlen != transform->fixed_ivlen ); +} + +/* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV ) + * + * Concretely, this occurs in two variants: + * + * a) Fixed and dynamic IV lengths add up to total IV length, giving + * IV = fixed_iv || dynamic_iv + * + * This variant is used in TLS 1.2 when used with GCM or CCM. + * + * b) Fixed IV lengths matches total IV length, giving + * IV = fixed_iv XOR ( 0 || dynamic_iv ) + * + * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly. + * + * See also the documentation of mbedtls_ssl_transform. + * + * This function has the precondition that + * + * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len ) + * + * which has to be ensured by the caller. If this precondition + * violated, the behavior of this function is undefined. + */ +static void ssl_build_record_nonce( unsigned char *dst_iv, + size_t dst_iv_len, + unsigned char const *fixed_iv, + size_t fixed_iv_len, + unsigned char const *dynamic_iv, + size_t dynamic_iv_len ) +{ + size_t i; + + /* Start with Fixed IV || 0 */ + memset( dst_iv, 0, dst_iv_len ); + memcpy( dst_iv, fixed_iv, fixed_iv_len ); + + dst_iv += dst_iv_len - dynamic_iv_len; + for( i = 0; i < dynamic_iv_len; i++ ) + dst_iv[i] ^= dynamic_iv[i]; +} +#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ + int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, mbedtls_ssl_transform *transform, mbedtls_record *rec, @@ -574,6 +657,37 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } + /* The following two code paths implement the (D)TLSInnerPlaintext + * structure present in TLS 1.3 and DTLS 1.2 + CID. + * + * See ssl_build_inner_plaintext() for more information. + * + * Note that this changes `rec->data_len`, and hence + * `post_avail` needs to be recalculated afterwards. + * + * Note also that the two code paths cannot occur simultaneously + * since they apply to different versions of the protocol. There + * is hence no risk of double-addition of the inner plaintext. + */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { + size_t padding = + ssl_compute_padding_length( rec->data_len, + MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY ); + if( ssl_build_inner_plaintext( data, + &rec->data_len, + post_avail, + rec->type, + padding ) != 0 ) + { + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) /* * Add CID information @@ -584,17 +698,21 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, if( rec->cid_len != 0 ) { + size_t padding = + ssl_compute_padding_length( rec->data_len, + MBEDTLS_SSL_CID_PADDING_GRANULARITY ); /* * Wrap plaintext into DTLSInnerPlaintext structure. - * See ssl_cid_build_inner_plaintext() for more information. + * See ssl_build_inner_plaintext() for more information. * * Note that this changes `rec->data_len`, and hence * `post_avail` needs to be recalculated afterwards. */ - if( ssl_cid_build_inner_plaintext( data, + if( ssl_build_inner_plaintext( data, &rec->data_len, post_avail, - rec->type ) != 0 ) + rec->type, + padding ) != 0 ) { return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } @@ -638,7 +756,8 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, { unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec, + transform->minor_ver ); mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, add_data_len ); @@ -704,52 +823,51 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char iv[12]; - size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; + unsigned char *dynamic_iv; + size_t dynamic_iv_len; + int dynamic_iv_is_explicit = + ssl_transform_aead_dynamic_iv_is_explicit( transform ); - /* Check that there's space for both the authentication tag - * and the explicit IV before and after the record content. */ - if( post_avail < transform->taglen || - rec->data_offset < explicit_iv_len ) + /* Check that there's space for the authentication tag. */ + if( post_avail < transform->taglen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } /* - * Generate IV + * Build nonce for AEAD encryption. + * + * Note: In the case of CCM and GCM in TLS 1.2, the dynamic + * part of the IV is prepended to the ciphertext and + * can be chosen freely - in particular, it need not + * agree with the record sequence number. + * However, since ChaChaPoly as well as all AEAD modes + * in TLS 1.3 use the record sequence number as the + * dynamic part of the nonce, we uniformly use the + * record sequence number here in all cases. */ - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit (=seqnum) */ - memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); - memcpy( iv + transform->fixed_ivlen, rec->ctr, - explicit_iv_len ); - /* Prefix record content with explicit IV. */ - memcpy( data - explicit_iv_len, rec->ctr, explicit_iv_len ); - } - else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - unsigned char i; + dynamic_iv = rec->ctr; + dynamic_iv_len = sizeof( rec->ctr ); - memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); + ssl_build_record_nonce( iv, sizeof( iv ), + transform->iv_enc, + transform->fixed_ivlen, + dynamic_iv, + dynamic_iv_len ); - for( i = 0; i < 8; i++ ) - iv[i+4] ^= rec->ctr[i]; - } - else - { - /* Reminder if we ever add an AEAD mode with a different size */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + /* + * Build additional data for AEAD encryption. + * This depends on the TLS version. + */ + ssl_extract_add_data_from_record( add_data, &add_data_len, rec, + transform->minor_ver ); MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", - iv, transform->ivlen ); + iv, transform->ivlen ); MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", - data - explicit_iv_len, explicit_iv_len ); + dynamic_iv, + dynamic_iv_is_explicit ? dynamic_iv_len : 0 ); MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", add_data, add_data_len ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " @@ -770,17 +888,32 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); return( ret ); } - MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", data + rec->data_len, transform->taglen ); - - rec->data_len += transform->taglen + explicit_iv_len; - rec->data_offset -= explicit_iv_len; + /* Account for authentication tag. */ + rec->data_len += transform->taglen; post_avail -= transform->taglen; + + /* + * Prefix record content with dynamic IV in case it is explicit. + */ + if( dynamic_iv_is_explicit != 0 ) + { + if( rec->data_offset < dynamic_iv_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + memcpy( data - dynamic_iv_len, dynamic_iv, dynamic_iv_len ); + rec->data_offset -= dynamic_iv_len; + rec->data_len += dynamic_iv_len; + } + auth_done++; } else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ #if defined(MBEDTLS_CIPHER_MODE_CBC) && \ ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) if( mode == MBEDTLS_MODE_CBC ) @@ -898,7 +1031,8 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, + rec, transform->minor_ver ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, @@ -1012,61 +1146,61 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, mode == MBEDTLS_MODE_CHACHAPOLY ) { unsigned char iv[12]; - size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; + unsigned char *dynamic_iv; + size_t dynamic_iv_len; /* - * Prepare IV from explicit and implicit data. + * Extract dynamic part of nonce for AEAD decryption. + * + * Note: In the case of CCM and GCM in TLS 1.2, the dynamic + * part of the IV is prepended to the ciphertext and + * can be chosen freely - in particular, it need not + * agree with the record sequence number. */ - - /* Check that there's enough space for the explicit IV - * (at the beginning of the record) and the MAC (at the - * end of the record). */ - if( rec->data_len < explicit_iv_len + transform->taglen ) + dynamic_iv_len = sizeof( rec->ctr ); + if( ssl_transform_aead_dynamic_iv_is_explicit( transform ) == 1 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " - "+ taglen (%d)", rec->data_len, - explicit_iv_len, transform->taglen ) ); + if( rec->data_len < dynamic_iv_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) ", + rec->data_len, + dynamic_iv_len ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + dynamic_iv = data; + + data += dynamic_iv_len; + rec->data_offset += dynamic_iv_len; + rec->data_len -= dynamic_iv_len; + } + else + { + dynamic_iv = rec->ctr; + } + + /* Check that there's space for the authentication tag. */ + if( rec->data_len < transform->taglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < taglen (%d) " ) ); return( MBEDTLS_ERR_SSL_INVALID_MAC ); } + rec->data_len -= transform->taglen; -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit */ + /* + * Prepare nonce from dynamic and static parts. + */ + ssl_build_record_nonce( iv, sizeof( iv ), + transform->iv_dec, + transform->fixed_ivlen, + dynamic_iv, + dynamic_iv_len ); - /* Fixed */ - memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - /* Explicit */ - memcpy( iv + transform->fixed_ivlen, data, 8 ); - } - else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - unsigned char i; - - memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - - for( i = 0; i < 8; i++ ) - iv[i+4] ^= rec->ctr[i]; - } - else -#endif /* MBEDTLS_CHACHAPOLY_C */ - { - /* Reminder if we ever add an AEAD mode with a different size */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* Group changes to data, data_len, and add_data, because - * add_data depends on data_len. */ - data += explicit_iv_len; - rec->data_offset += explicit_iv_len; - rec->data_len -= explicit_iv_len + transform->taglen; - - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + /* + * Build additional data for AEAD encryption. + * This depends on the TLS version. + */ + ssl_extract_add_data_from_record( add_data, &add_data_len, rec, + transform->minor_ver ); MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", add_data, add_data_len ); @@ -1178,7 +1312,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, * * Further, we still know that data_len > minlen */ rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec, + transform->minor_ver ); /* Calculate expected MAC. */ MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, @@ -1397,7 +1532,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, * hence data_len >= maclen in any case. */ rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec, + transform->minor_ver ); #if defined(MBEDTLS_SSL_PROTO_SSL3) if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) @@ -1549,11 +1685,23 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { + /* Remove inner padding and infer true content type. */ + ret = ssl_parse_inner_plaintext( data, &rec->data_len, + &rec->type ); + + if( ret != 0 ) + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) if( rec->cid_len != 0 ) { - ret = ssl_cid_parse_inner_plaintext( data, &rec->data_len, - &rec->type ); + ret = ssl_parse_inner_plaintext( data, &rec->data_len, + &rec->type ); if( ret != 0 ) return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } @@ -4866,6 +5014,15 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) * and the caller has to make sure there's space for this. */ +static size_t ssl_transform_get_explicit_iv_len( + mbedtls_ssl_transform const *transform ) +{ + if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) + return( 0 ); + + return( transform->ivlen - transform->fixed_ivlen ); +} + void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl, mbedtls_ssl_transform *transform ) { @@ -4894,14 +5051,10 @@ void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl, ssl->out_iv = ssl->out_hdr + 5; } + ssl->out_msg = ssl->out_iv; /* Adjust out_msg to make space for explicit IV, if used. */ - if( transform != NULL && - ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen; - } - else - ssl->out_msg = ssl->out_iv; + if( transform != NULL ) + ssl->out_msg += ssl_transform_get_explicit_iv_len( transform ); } /* Once ssl->in_hdr as the address of the beginning of the diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fd0c8a7ab..30c917bb1 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -973,15 +973,28 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, transform->taglen = ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - /* All modes haves 96-bit IVs; - * GCM and CCM has 4 implicit and 8 explicit bytes - * ChachaPoly has all 12 bytes implicit + /* All modes haves 96-bit IVs, but the length of the static parts vary + * with mode and version: + * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes + * (to be concatenated with a dynamically chosen IV of 8 Bytes) + * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's + * a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record + * sequence number). */ transform->ivlen = 12; - if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { transform->fixed_ivlen = 12; + } else - transform->fixed_ivlen = 4; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + { + if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) + transform->fixed_ivlen = 12; + else + transform->fixed_ivlen = 4; + } /* Minimum length of encrypted record */ explicit_ivlen = transform->ivlen - transform->fixed_ivlen; diff --git a/library/version_features.c b/library/version_features.c index 7ecde2148..adc61a1fe 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -519,6 +519,9 @@ static const char * const features[] = { #if defined(MBEDTLS_SSL_PROTO_TLS1_2) "MBEDTLS_SSL_PROTO_TLS1_2", #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL", +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #if defined(MBEDTLS_SSL_PROTO_DTLS) "MBEDTLS_SSL_PROTO_DTLS", #endif /* MBEDTLS_SSL_PROTO_DTLS */ diff --git a/programs/test/query_config.c b/programs/test/query_config.c index 27c5d0db0..062dce6c1 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -1426,6 +1426,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( strcmp( "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + #if defined(MBEDTLS_SSL_PROTO_DTLS) if( strcmp( "MBEDTLS_SSL_PROTO_DTLS", config ) == 0 ) { @@ -2610,6 +2618,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_CID_PADDING_GRANULARITY */ +#if defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY) + if( strcmp( "MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY */ + #if defined(MBEDTLS_SSL_OUT_CONTENT_LEN) if( strcmp( "MBEDTLS_SSL_OUT_CONTENT_LEN", config ) == 0 ) { diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index bd41f4b17..a2279769d 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1731,6 +1731,15 @@ component_test_allow_sha1 () { if_build_succeeded tests/ssl-opt.sh -f SHA-1 } +component_test_tls13_experimental () { + msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled" + scripts/config.pl set MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled" + make test +} + 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 diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 9af6a5ca0..aa314dd32 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -4154,6 +4154,10 @@ Record crypt, AES-128-GCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_128_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, AES-128-GCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_GCM_C +ssl_crypt_record:MBEDTLS_CIPHER_AES_128_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, AES-128-GCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_128_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -4178,6 +4182,10 @@ Record crypt, AES-192-GCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_192_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, AES-192-GCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_GCM_C +ssl_crypt_record:MBEDTLS_CIPHER_AES_192_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, AES-192-GCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_192_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -4202,6 +4210,10 @@ Record crypt, AES-256-GCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_256_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, AES-256-GCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_GCM_C +ssl_crypt_record:MBEDTLS_CIPHER_AES_256_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, AES-256-GCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_256_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -4298,6 +4310,10 @@ Record crypt, AES-128-CCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_128_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, AES-128-CCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_CCM_C +ssl_crypt_record:MBEDTLS_CIPHER_AES_128_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, AES-128-CCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_128_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -4322,6 +4338,10 @@ Record crypt, AES-192-CCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_192_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, AES-192-CCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_CCM_C +ssl_crypt_record:MBEDTLS_CIPHER_AES_192_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, AES-192-CCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_192_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -4346,6 +4366,10 @@ Record crypt, AES-256-CCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_256_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, AES-256-CCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_CCM_C +ssl_crypt_record:MBEDTLS_CIPHER_AES_256_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, AES-256-CCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record:MBEDTLS_CIPHER_AES_256_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -5018,10 +5042,18 @@ Record crypt, ChachaPoly depends_on:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SSL_PROTO_TLS1_2 ssl_crypt_record:MBEDTLS_CIPHER_CHACHA20_POLY1305:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, ChachaPoly, 1.3 +depends_on:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +ssl_crypt_record:MBEDTLS_CIPHER_CHACHA20_POLY1305:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, ChachaPoly depends_on:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SSL_PROTO_TLS1_2 ssl_crypt_record_small:MBEDTLS_CIPHER_CHACHA20_POLY1305:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, little space, ChachaPoly, 1.3 +depends_on:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +ssl_crypt_record_small:MBEDTLS_CIPHER_CHACHA20_POLY1305:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, ChachaPoly, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SSL_PROTO_TLS1_2 ssl_crypt_record_small:MBEDTLS_CIPHER_CHACHA20_POLY1305:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -8554,6 +8586,10 @@ Record crypt, little space, AES-128-GCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_128_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, little space, AES-128-GCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_GCM_C +ssl_crypt_record_small:MBEDTLS_CIPHER_AES_128_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, AES-128-GCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_128_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -8578,6 +8614,10 @@ Record crypt, little space, AES-192-GCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_192_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, little space, AES-192-GCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_GCM_C +ssl_crypt_record_small:MBEDTLS_CIPHER_AES_192_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, AES-192-GCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_192_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -8602,6 +8642,10 @@ Record crypt, little space, AES-256-GCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_256_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, little space, AES-256-GCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_GCM_C +ssl_crypt_record_small:MBEDTLS_CIPHER_AES_256_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, AES-256-GCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_GCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_256_GCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -8698,6 +8742,10 @@ Record crypt, little space, AES-128-CCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_128_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, little space, AES-128-CCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_CCM_C +ssl_crypt_record_small:MBEDTLS_CIPHER_AES_128_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, AES-128-CCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_128_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -8722,6 +8770,10 @@ Record crypt, little space, AES-192-CCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_192_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, little space, AES-192-CCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_CCM_C +ssl_crypt_record_small:MBEDTLS_CIPHER_AES_192_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, AES-192-CCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_192_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 @@ -8746,6 +8798,10 @@ Record crypt, little space, AES-256-CCM, 1.2 depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_256_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:0:0 +Record crypt, little space, AES-256-CCM, 1.3 +depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL:MBEDTLS_CCM_C +ssl_crypt_record_small:MBEDTLS_CIPHER_AES_256_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_4:0:0 + Record crypt, little space, AES-256-CCM, 1.2, CID 4+4 depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C ssl_crypt_record_small:MBEDTLS_CIPHER_AES_256_CCM:MBEDTLS_MD_MD5:0:0:MBEDTLS_SSL_MINOR_VERSION_3:4:4 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 230d16a0c..6b32ca344 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1308,8 +1308,18 @@ static int build_transforms( mbedtls_ssl_transform *t_in, { case MBEDTLS_MODE_GCM: case MBEDTLS_MODE_CCM: - t_out->fixed_ivlen = 4; - t_in->fixed_ivlen = 4; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { + t_out->fixed_ivlen = 12; + t_in->fixed_ivlen = 12; + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + { + t_out->fixed_ivlen = 4; + t_in->fixed_ivlen = 4; + } t_out->maclen = 0; t_in->maclen = 0; switch( tag_mode ) @@ -3182,6 +3192,26 @@ void ssl_crypt_record( int cipher_type, int hash_id, continue; } +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + if( rec.cid_len != 0 ) + { + /* DTLS 1.2 + CID hides the real content type and + * uses a special CID content type in the protected + * record. Double-check this. */ + TEST_ASSERT( rec.type == MBEDTLS_SSL_MSG_CID ); + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( t_enc->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { + /* TLS 1.3 hides the real content type and + * always uses Application Data as the content type + * for protected records. Double-check this. */ + TEST_ASSERT( rec.type == MBEDTLS_SSL_MSG_APPLICATION_DATA ); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /* Decrypt record with t_dec */ ret = mbedtls_ssl_decrypt_buf( &ssl, t_dec, &rec ); TEST_ASSERT( ret == 0 ); @@ -3325,6 +3355,26 @@ void ssl_crypt_record_small( int cipher_type, int hash_id, if( ret != 0 ) continue; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + if( rec.cid_len != 0 ) + { + /* DTLS 1.2 + CID hides the real content type and + * uses a special CID content type in the protected + * record. Double-check this. */ + TEST_ASSERT( rec.type == MBEDTLS_SSL_MSG_CID ); + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( t_enc->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { + /* TLS 1.3 hides the real content type and + * always uses Application Data as the content type + * for protected records. Double-check this. */ + TEST_ASSERT( rec.type == MBEDTLS_SSL_MSG_APPLICATION_DATA ); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /* Decrypt record with t_dec */ TEST_ASSERT( mbedtls_ssl_decrypt_buf( &ssl, t_dec, &rec ) == 0 );