diff --git a/library/ssl_misc.h b/library/ssl_misc.h index c8e2f4c88..64b0abb73 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -740,7 +740,8 @@ struct mbedtls_ssl_transform #if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) /* We need the Hello random bytes in order to re-derive keys from the - * Master Secret and other session info, see ssl_populate_transform() */ + * Master Secret and other session info, + * see ssl_tls12_populate_transform() */ unsigned char randbytes[64]; /*!< ServerHello.random+ClientHello.random */ #endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ }; diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 76cc2b17d..cf2eab56b 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -384,7 +384,8 @@ static int ssl_parse_inner_plaintext( unsigned char const *content, static void ssl_extract_add_data_from_record( unsigned char* add_data, size_t *add_data_len, mbedtls_record *rec, - unsigned minor_ver ) + unsigned minor_ver, + size_t taglen ) { /* Quoting RFC 5246 (TLS 1.2): * @@ -403,15 +404,37 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data, * * 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 + * ciphertext, not the TLS plaintext as in earlier versions. + * Quoting RFC 8446 (TLS 1.3): + * + * additional_data = TLSCiphertext.opaque_type || + * TLSCiphertext.legacy_record_version || + * TLSCiphertext.length + * + * We pass the tag length to this function in order to compute the + * ciphertext length from the inner plaintext length rec->data_len via + * + * TLSCiphertext.length = TLSInnerPlaintext.length + taglen. + * */ unsigned char *cur = add_data; + size_t ad_len_field = rec->data_len; #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) - if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { + /* In TLS 1.3, the AAD contains the length of the TLSCiphertext, + * which differs from the length of the TLSInnerPlaintext + * by the length of the authentication tag. */ + ad_len_field += taglen; + } + else #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ { ((void) minor_ver); + ((void) taglen); memcpy( cur, rec->ctr, sizeof( rec->ctr ) ); cur += sizeof( rec->ctr ); } @@ -431,15 +454,15 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data, *cur = rec->cid_len; cur++; - cur[0] = ( rec->data_len >> 8 ) & 0xFF; - cur[1] = ( rec->data_len >> 0 ) & 0xFF; + cur[0] = ( ad_len_field >> 8 ) & 0xFF; + cur[1] = ( ad_len_field >> 0 ) & 0xFF; cur += 2; } else #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ { - cur[0] = ( rec->data_len >> 8 ) & 0xFF; - cur[1] = ( rec->data_len >> 0 ) & 0xFF; + cur[0] = ( ad_len_field >> 8 ) & 0xFF; + cur[1] = ( ad_len_field >> 0 ) & 0xFF; cur += 2; } @@ -646,7 +669,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, - transform->minor_ver ); + transform->minor_ver, + transform->taglen ); mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, add_data_len ); @@ -743,7 +767,8 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, * This depends on the TLS version. */ ssl_extract_add_data_from_record( add_data, &add_data_len, rec, - transform->minor_ver ); + transform->minor_ver, + transform->taglen ); MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", iv, transform->ivlen ); @@ -897,7 +922,8 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, } ssl_extract_add_data_from_record( add_data, &add_data_len, - rec, transform->minor_ver ); + rec, transform->minor_ver, + transform->taglen ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, @@ -1304,7 +1330,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, * This depends on the TLS version. */ ssl_extract_add_data_from_record( add_data, &add_data_len, rec, - transform->minor_ver ); + transform->minor_ver, + transform->taglen ); MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", add_data, add_data_len ); @@ -1414,7 +1441,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, - transform->minor_ver ); + transform->minor_ver, + transform->taglen ); /* Calculate expected MAC. */ MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, @@ -1606,7 +1634,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, */ rec->data_len -= transform->maclen; ssl_extract_add_data_from_record( add_data, &add_data_len, rec, - transform->minor_ver ); + transform->minor_ver, + transform->taglen ); #if defined(MBEDTLS_SSL_PROTO_TLS1_2) /* diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 923c671a7..2306c712c 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -664,14 +664,14 @@ typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *, * - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg */ -static int ssl_populate_transform( mbedtls_ssl_transform *transform, +static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform, int ciphersuite, const unsigned char master[48], -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \ + defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) int encrypt_then_mac, -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC && + MBEDTLS_SSL_SOME_SUITES_USE_MAC */ ssl_tls_prf_t tls_prf, const unsigned char randbytes[64], int minor_ver, @@ -713,6 +713,15 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, memcpy( transform->randbytes, randbytes, sizeof( transform->randbytes ) ); #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) + { + /* At the moment, we keep TLS <= 1.2 and TLS 1.3 transform + * generation separate. This should never happen. */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /* * Get various info structures */ @@ -805,19 +814,10 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, * sequence number). */ transform->ivlen = 12; -#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) - { + if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) transform->fixed_ivlen = 12; - } else -#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ - { - if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) - transform->fixed_ivlen = 12; - else - transform->fixed_ivlen = 4; - } + transform->fixed_ivlen = 4; /* Minimum length of encrypted record */ explicit_ivlen = transform->ivlen - transform->fixed_ivlen; @@ -1327,22 +1327,22 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) } /* Populate transform structure */ - ret = ssl_populate_transform( ssl->transform_negotiate, - ssl->session_negotiate->ciphersuite, - ssl->session_negotiate->master, -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - ssl->session_negotiate->encrypt_then_mac, -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - ssl->handshake->tls_prf, - ssl->handshake->randbytes, - ssl->minor_ver, - ssl->conf->endpoint, - ssl ); + ret = ssl_tls12_populate_transform( ssl->transform_negotiate, + ssl->session_negotiate->ciphersuite, + ssl->session_negotiate->master, +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \ + defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + ssl->session_negotiate->encrypt_then_mac, +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC && + MBEDTLS_SSL_SOME_SUITES_USE_MAC */ + ssl->handshake->tls_prf, + ssl->handshake->randbytes, + ssl->minor_ver, + ssl->conf->endpoint, + ssl ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls12_populate_transform", ret ); return( ret ); } @@ -5923,14 +5923,14 @@ static int ssl_context_load( mbedtls_ssl_context *ssl, if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - ret = ssl_populate_transform( ssl->transform, + ret = ssl_tls12_populate_transform( ssl->transform, ssl->session->ciphersuite, ssl->session->master, -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \ + defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) ssl->session->encrypt_then_mac, -#endif -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC && + MBEDTLS_SSL_SOME_SUITES_USE_MAC */ ssl_tls12prf_from_cs( ssl->session->ciphersuite ), p, /* currently pointing to randbytes */ MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */ diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index f1c8a12d8..902f99ea8 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -699,4 +699,125 @@ exit: return( ret ); } +int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform, + int endpoint, + int ciphersuite, + mbedtls_ssl_key_set const *traffic_keys, + mbedtls_ssl_context *ssl /* DEBUG ONLY */ ) +{ + int ret; + mbedtls_cipher_info_t const *cipher_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + unsigned char const *key_enc; + unsigned char const *iv_enc; + unsigned char const *key_dec; + unsigned char const *iv_dec; + +#if !defined(MBEDTLS_DEBUG_C) + ssl = NULL; /* make sure we don't use it except for those cases */ + (void) ssl; +#endif + + ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite ); + if( ciphersuite_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found", + ciphersuite ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher ); + if( cipher_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %u not found", + ciphersuite_info->cipher ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + /* + * Setup cipher contexts in target transform + */ + + if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, + cipher_info ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); + return( ret ); + } + + if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec, + cipher_info ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); + return( ret ); + } + +#if defined(MBEDTLS_SSL_SRV_C) + if( endpoint == MBEDTLS_SSL_IS_SERVER ) + { + key_enc = traffic_keys->server_write_key; + key_dec = traffic_keys->client_write_key; + iv_enc = traffic_keys->server_write_iv; + iv_dec = traffic_keys->client_write_iv; + } + else +#endif /* MBEDTLS_SSL_SRV_C */ +#if defined(MBEDTLS_SSL_CLI_C) + if( endpoint == MBEDTLS_SSL_IS_CLIENT ) + { + key_enc = traffic_keys->client_write_key; + key_dec = traffic_keys->server_write_key; + iv_enc = traffic_keys->client_write_iv; + iv_dec = traffic_keys->server_write_iv; + } + else +#endif /* MBEDTLS_SSL_CLI_C */ + { + /* should not happen */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( transform->iv_enc, iv_enc, traffic_keys->iv_len ); + memcpy( transform->iv_dec, iv_dec, traffic_keys->iv_len ); + + if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, + key_enc, cipher_info->key_bitlen, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); + return( ret ); + } + + if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, + key_dec, cipher_info->key_bitlen, + MBEDTLS_DECRYPT ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); + return( ret ); + } + + /* + * Setup other fields in SSL transform + */ + + if( ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ) != 0 ) + transform->taglen = 8; + else + transform->taglen = 16; + + transform->ivlen = traffic_keys->iv_len; + transform->maclen = 0; + transform->fixed_ivlen = transform->ivlen; + transform->minor_ver = MBEDTLS_SSL_MINOR_VERSION_4; + + /* We add the true record content type (1 Byte) to the plaintext and + * then pad to the configured granularity. The mimimum length of the + * type-extended and padded plaintext is therefore the padding + * granularity. */ + transform->minlen = + transform->taglen + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY; + + return( 0 ); +} + #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index 3b96998ae..ca892b166 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -498,4 +498,37 @@ int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl, unsigned char const *transcript, unsigned char *result ); +/** + * \bref Setup an SSL transform structure representing the + * record protection mechanism used by TLS 1.3 + * + * \param transform The SSL transform structure to be created. This must have + * been initialized through mbedtls_ssl_transform_init() and + * not used in any other way prior to calling this function. + * In particular, this function does not clean up the + * transform structure prior to installing the new keys. + * \param endpoint Indicates whether the transform is for the client + * (value #MBEDTLS_SSL_IS_CLIENT) or the server + * (value #MBEDTLS_SSL_IS_SERVER). + * \param ciphersuite The numerical identifier for the ciphersuite to use. + * This must be one of the identifiers listed in + * ssl_ciphersuites.h. + * \param traffic_keys The key material to use. No reference is stored in + * the SSL transform being generated, and the caller + * should destroy the key material afterwards. + * \param ssl (Debug-only) The SSL context to use for debug output + * in case of failure. This parameter is only needed if + * #MBEDTLS_DEBUG_C is set, and is ignored otherwise. + * + * \return \c 0 on success. In this case, \p transform is ready to + * be used with mbedtls_ssl_transform_decrypt() and + * mbedtls_ssl_transform_encrypt(). + * \return A negative error code on failure. + */ +int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform, + int endpoint, + int ciphersuite, + mbedtls_ssl_key_set const *traffic_keys, + mbedtls_ssl_context *ssl ); + #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index f8e43c871..5d2710cad 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2437,11 +2437,22 @@ component_build_armcc () { } component_test_tls13_experimental () { - msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled" + msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, without padding" scripts/config.pl set MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + scripts/config.pl set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1 CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . make - msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled" + msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, without padding" + make test +} + +component_test_tls13_experimental_with_padding () { + msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with padding" + scripts/config.pl set MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + scripts/config.pl set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with padding" make test } diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 5d92469ad..25eefb3ab 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -6021,6 +6021,62 @@ SSL TLS 1.3 Key schedule: Handshake secrets derivation helper # Vector from RFC 8448 ssl_tls1_3_derive_handshake_secrets:MBEDTLS_MD_SHA256:"005cb112fd8eb4ccc623bb88a07c64b3ede1605363fc7d0df8c7ce4ff0fb4ae6":"f736cb34fe25e701551bee6fd24c1cc7102a7daf9405cb15d97aafe16f757d03":"2faac08f851d35fea3604fcb4de82dc62c9b164a70974d0462e27f1ab278700f":"fe927ae271312e8bf0275b581c54eef020450dc4ecffaa05a1a35d27518e7803" +SSL TLS 1.3 Record Encryption, tls13.ulfheim.net Example #1 +# - Server App Key: 0b6d22c8ff68097ea871c672073773bf +# - Server App IV: 1b13dd9f8d8f17091d34b349 +# - Client App Key: 49134b95328f279f0183860589ac6707 +# - Client App IV: bc4dd5f7b98acff85466261d +# - App data payload: 70696e67 +# - Complete record: 1703030015c74061535eb12f5f25a781957874742ab7fb305dd5 +# - Padding used: No (== granularity 1) +ssl_tls1_3_record_protection:MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_CLIENT:0:1:"0b6d22c8ff68097ea871c672073773bf":"1b13dd9f8d8f17091d34b349":"49134b95328f279f0183860589ac6707":"bc4dd5f7b98acff85466261d":"70696e67":"c74061535eb12f5f25a781957874742ab7fb305dd5" + +SSL TLS 1.3 Record Encryption, tls13.ulfheim.net Example #2 +# - Server App Key: 0b6d22c8ff68097ea871c672073773bf +# - Server App IV: 1b13dd9f8d8f17091d34b349 +# - Client App Key: 49134b95328f279f0183860589ac6707 +# - Client App IV: bc4dd5f7b98acff85466261d +# - App data payload: 706f6e67 +# - Complete record: 1703030015370e5f168afa7fb16b663ecdfca3dbb81931a90ca7 +# - Padding used: No (== granularity 1) +ssl_tls1_3_record_protection:MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_SERVER:1:1:"0b6d22c8ff68097ea871c672073773bf":"1b13dd9f8d8f17091d34b349":"49134b95328f279f0183860589ac6707":"bc4dd5f7b98acff85466261d":"706f6e67":"370e5f168afa7fb16b663ecdfca3dbb81931a90ca7" + +SSL TLS 1.3 Record Encryption RFC 8448 Example #1 +# Application Data record sent by Client in 1-RTT example of RFC 8448, Section 3 +# - Server App Key: 9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac 92 e3 56 +# - Server App IV: cf 78 2b 88 dd 83 54 9a ad f1 e9 84 +# - Client App Key: 17 42 2d da 59 6e d5 d9 ac d8 90 e3 c6 3f 50 51 +# - Client App IV: 5b 78 92 3d ee 08 57 90 33 e5 23 d9 +# - App data payload: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +# 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +# 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +# 30 31 +# - Complete record: 17 03 03 00 43 a2 3f 70 54 b6 2c 94 d0 af fa fe +# 82 28 ba 55 cb ef ac ea 42 f9 14 aa 66 bc ab 3f +# 2b 98 19 a8 a5 b4 6b 39 5b d5 4a 9a 20 44 1e 2b +# 62 97 4e 1f 5a 62 92 a2 97 70 14 bd 1e 3d ea e6 +# 3a ee bb 21 69 49 15 e4 +# - Padding used: No (== granularity 1) +ssl_tls1_3_record_protection:MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_CLIENT:0:1:"9f02283b6c9c07efc26bb9f2ac92e356":"cf782b88dd83549aadf1e984":"17422dda596ed5d9acd890e3c63f5051":"5b78923dee08579033e523d9":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031":"a23f7054b62c94d0affafe8228ba55cbefacea42f914aa66bcab3f2b9819a8a5b46b395bd54a9a20441e2b62974e1f5a6292a2977014bd1e3deae63aeebb21694915e4" + +SSL TLS 1.3 Record Encryption RFC 8448 Example #2 +# Application Data record sent by Server in 1-RTT example of RFC 8448, Section 3 +# - Server App Key: 9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac 92 e3 56 +# - Server App IV: cf 78 2b 88 dd 83 54 9a ad f1 e9 84 +# - Client App Key: 17 42 2d da 59 6e d5 d9 ac d8 90 e3 c6 3f 50 51 +# - Client App IV: 5b 78 92 3d ee 08 57 90 33 e5 23 d9 +# - App data payload: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +# 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +# 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +# 30 31 +# - Complete record: 17 03 03 00 43 2e 93 7e 11 ef 4a c7 40 e5 38 ad +# 36 00 5f c4 a4 69 32 fc 32 25 d0 5f 82 aa 1b 36 +# e3 0e fa f9 7d 90 e6 df fc 60 2d cb 50 1a 59 a8 +# fc c4 9c 4b f2 e5 f0 a2 1c 00 47 c2 ab f3 32 54 +# 0d d0 32 e1 67 c2 95 5d +# - Padding used: No (== granularity 1) +ssl_tls1_3_record_protection:MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_SERVER:1:1:"9f02283b6c9c07efc26bb9f2ac92e356":"cf782b88dd83549aadf1e984":"17422dda596ed5d9acd890e3c63f5051":"5b78923dee08579033e523d9":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031":"2e937e11ef4ac740e538ad36005fc4a46932fc3225d05f82aa1b36e30efaf97d90e6dffc602dcb501a59a8fcc49c4bf2e5f0a21c0047c2abf332540dd032e167c2955d" + SSL TLS 1.3 Key schedule: Application secrets derivation helper # Vector from RFC 8448 ssl_tls1_3_derive_application_secrets:MBEDTLS_MD_SHA256:"e2d32d4ed66dd37897a0e80c84107503ce58bf8aad4cb55a5002d77ecb890ece":"b0aeffc46a2cfe33114e6fd7d51f9f04b1ca3c497dab08934a774a9d9ad7dbf3":"2abbf2b8e381d23dbebe1dd2a7d16a8bf484cb4950d23fb7fb7fa8547062d9a1":"cc21f1bf8feb7dd5fa505bd9c4b468a9984d554a993dc49e6d285598fb672691":"3fd93d4ffddc98e64b14dd107aedf8ee4add23f4510f58a4592d0b201bee56b4" diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 72b0cdb8a..69d2e0066 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3944,6 +3944,104 @@ void ssl_tls1_3_create_psk_binder( int hash_alg, } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ +void ssl_tls1_3_record_protection( int ciphersuite, + int endpoint, + int ctr, + int padding_used, + data_t *server_write_key, + data_t *server_write_iv, + data_t *client_write_key, + data_t *client_write_iv, + data_t *plaintext, + data_t *ciphertext ) +{ + mbedtls_ssl_key_set keys; + mbedtls_ssl_transform transform_send; + mbedtls_ssl_transform transform_recv; + mbedtls_record rec; + unsigned char *buf = NULL; + size_t buf_len; + int other_endpoint; + + TEST_ASSERT( endpoint == MBEDTLS_SSL_IS_CLIENT || + endpoint == MBEDTLS_SSL_IS_SERVER ); + + if( endpoint == MBEDTLS_SSL_IS_SERVER ) + other_endpoint = MBEDTLS_SSL_IS_CLIENT; + if( endpoint == MBEDTLS_SSL_IS_CLIENT ) + other_endpoint = MBEDTLS_SSL_IS_SERVER; + + TEST_ASSERT( server_write_key->len == client_write_key->len ); + TEST_ASSERT( server_write_iv->len == client_write_iv->len ); + + memcpy( keys.client_write_key, + client_write_key->x, client_write_key->len ); + memcpy( keys.client_write_iv, + client_write_iv->x, client_write_iv->len ); + memcpy( keys.server_write_key, + server_write_key->x, server_write_key->len ); + memcpy( keys.server_write_iv, + server_write_iv->x, server_write_iv->len ); + + keys.key_len = server_write_key->len; + keys.iv_len = server_write_iv->len; + + mbedtls_ssl_transform_init( &transform_recv ); + mbedtls_ssl_transform_init( &transform_send ); + + TEST_ASSERT( mbedtls_ssl_tls13_populate_transform( + &transform_send, endpoint, + ciphersuite, &keys, NULL ) == 0 ); + TEST_ASSERT( mbedtls_ssl_tls13_populate_transform( + &transform_recv, other_endpoint, + ciphersuite, &keys, NULL ) == 0 ); + + /* Make sure we have enough space in the buffer even if + * we use more padding than the KAT. */ + buf_len = ciphertext->len + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY; + ASSERT_ALLOC( buf, buf_len ); + rec.type = MBEDTLS_SSL_MSG_APPLICATION_DATA; + + /* TLS 1.3 uses the version identifier from TLS 1.2 on the wire. */ + mbedtls_ssl_write_version( MBEDTLS_SSL_MAJOR_VERSION_3, + MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_TRANSPORT_STREAM, + rec.ver ); + + /* Copy plaintext into record structure */ + rec.buf = buf; + rec.buf_len = buf_len; + rec.data_offset = 0; + TEST_ASSERT( plaintext->len <= ciphertext->len ); + memcpy( rec.buf + rec.data_offset, plaintext->x, plaintext->len ); + rec.data_len = plaintext->len; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + rec.cid_len = 0; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + + memset( &rec.ctr[0], 0, 8 ); + rec.ctr[7] = ctr; + + TEST_ASSERT( mbedtls_ssl_encrypt_buf( NULL, &transform_send, &rec, + NULL, NULL ) == 0 ); + + if( padding_used == MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY ) + { + ASSERT_COMPARE( rec.buf + rec.data_offset, rec.data_len, + ciphertext->x, ciphertext->len ); + } + + TEST_ASSERT( mbedtls_ssl_decrypt_buf( NULL, &transform_recv, &rec ) == 0 ); + ASSERT_COMPARE( rec.buf + rec.data_offset, rec.data_len, + plaintext->x, plaintext->len ); + + mbedtls_free( buf ); + mbedtls_ssl_transform_free( &transform_send ); + mbedtls_ssl_transform_free( &transform_recv ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ void ssl_tls1_3_key_evolution( int hash_alg, data_t *secret,