diff --git a/ChangeLog.d/tls13-key-share-validation.txt b/ChangeLog.d/tls13-key-share-validation.txt new file mode 100644 index 0000000000..f0c3893f85 --- /dev/null +++ b/ChangeLog.d/tls13-key-share-validation.txt @@ -0,0 +1,8 @@ +Bugfix + * On the TLS 1.3 server, reject a malformed key_share extension in the + ClientHello instead of closing the connection without an alert. A + zero-length key_exchange and trailing data after the client_shares list + are now rejected with a decode_error alert, and a key_exchange whose + length does not match the group with an illegal_parameter alert. The + shared key-exchange reader now also checks that a ServerHello key_share + is consumed exactly on the client side. Fixes #10887. Fixes #10737. diff --git a/ChangeLog.d/tls13-supported-groups-validation.txt b/ChangeLog.d/tls13-supported-groups-validation.txt new file mode 100644 index 0000000000..23f42a4270 --- /dev/null +++ b/ChangeLog.d/tls13-supported-groups-validation.txt @@ -0,0 +1,4 @@ +Bugfix + * On the TLS 1.3 server, reject an empty supported_groups list, and + trailing data after the list, in the ClientHello with a decode_error + alert, as required by RFC 8446. Fixes #10897. Fixes #10733. diff --git a/library/ssl_misc.h b/library/ssl_misc.h index ecd3e6cc07..af6908686a 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2613,6 +2613,7 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite( MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_tls13_read_public_xxdhe_share(mbedtls_ssl_context *ssl, + uint16_t named_group, const unsigned char *buf, size_t buf_len); diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index e8b6063f32..51abb5d237 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -498,7 +498,7 @@ static int ssl_tls13_parse_key_share_ext(mbedtls_ssl_context *ssl, mbedtls_ssl_tls13_named_group_is_ffdh(group)) { MBEDTLS_SSL_DEBUG_MSG(2, ("DHE group name: %s", mbedtls_ssl_named_group_to_str(group))); - ret = mbedtls_ssl_tls13_read_public_xxdhe_share(ssl, p, end - p); + ret = mbedtls_ssl_tls13_read_public_xxdhe_share(ssl, group, p, end - p); if (ret != 0) { return ret; } diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 60c0f2348c..104c60b3c6 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1482,35 +1482,6 @@ int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) -int mbedtls_ssl_tls13_read_public_xxdhe_share(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t buf_len) -{ - uint8_t *p = (uint8_t *) buf; - const uint8_t *end = buf + buf_len; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* Get size of the TLS opaque key_exchange field of the KeyShareEntry struct. */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - uint16_t peerkey_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* Check if key size is consistent with given buffer length. */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, peerkey_len); - - /* Store peer's ECDH/FFDH public key. */ - if (peerkey_len > sizeof(handshake->xxdh_psa_peerkey)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %u > %" MBEDTLS_PRINTF_SIZET, - (unsigned) peerkey_len, - sizeof(handshake->xxdh_psa_peerkey))); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - memcpy(handshake->xxdh_psa_peerkey, p, peerkey_len); - handshake->xxdh_psa_peerkey_len = peerkey_len; - - return 0; -} - #if defined(PSA_WANT_ALG_FFDH) static psa_status_t mbedtls_ssl_get_psa_ffdh_info_from_tls_id( uint16_t tls_id, size_t *bits, psa_key_type_t *key_type) @@ -1552,6 +1523,108 @@ static psa_status_t mbedtls_ssl_get_psa_ffdh_info_from_tls_id( } #endif /* PSA_WANT_ALG_FFDH */ +/* Length of the key_exchange field of a KeyShareEntry for the given named + * group, i.e. the exact size of a well-formed ECDHE/FFDHE public key. */ +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_named_group_share_len(uint16_t named_group, + size_t *share_len) +{ +#if defined(PSA_WANT_ALG_ECDH) + if (mbedtls_ssl_tls13_named_group_is_ecdhe(named_group)) { + psa_key_type_t key_type; + size_t bits; + if (mbedtls_ssl_get_psa_curve_info_from_tls_id( + named_group, &key_type, &bits) != PSA_SUCCESS) { + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + if (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_MONTGOMERY) { + /* Montgomery curves use the raw u-coordinate: X25519 32, X448 56. */ + *share_len = PSA_BITS_TO_BYTES(bits); + } else { + /* Weierstrass curves use the uncompressed point 0x04 || X || Y: + * secp256r1 65, secp384r1 97, secp521r1 133. */ + *share_len = 2 * PSA_BITS_TO_BYTES(bits) + 1; + } + return 0; + } +#endif /* PSA_WANT_ALG_ECDH */ +#if defined(PSA_WANT_ALG_FFDH) + if (mbedtls_ssl_tls13_named_group_is_ffdh(named_group)) { + psa_key_type_t key_type; + size_t bits; + if (mbedtls_ssl_get_psa_ffdh_info_from_tls_id( + named_group, &bits, &key_type) != PSA_SUCCESS) { + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + /* FFDHE public keys are the size of the group prime. */ + *share_len = PSA_BITS_TO_BYTES(bits); + return 0; + } +#endif /* PSA_WANT_ALG_FFDH */ + (void) named_group; + (void) share_len; + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; +} + +int mbedtls_ssl_tls13_read_public_xxdhe_share(mbedtls_ssl_context *ssl, + uint16_t named_group, + const unsigned char *buf, + size_t buf_len) +{ + uint8_t *p = (uint8_t *) buf; + const uint8_t *end = buf + buf_len; + mbedtls_ssl_handshake_params *handshake = ssl->handshake; + size_t expected_len; + int ret; + + /* Get size of the TLS opaque key_exchange field of the KeyShareEntry struct. */ + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); + uint16_t peerkey_len = MBEDTLS_GET_UINT16_BE(p, 0); + p += 2; + + /* Check if key size is consistent with given buffer length. */ + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, peerkey_len); + + /* key_exchange is the whole KeyShareEntry; no trailing data (RFC 8446 4.2.8). */ + if ((size_t) (end - p) != peerkey_len) { + MBEDTLS_SSL_DEBUG_MSG(1, ("key_share entry has trailing data")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR); + return MBEDTLS_ERR_SSL_DECODE_ERROR; + } + + /* A share whose length does not match the group is illegal_parameter. */ + ret = ssl_tls13_named_group_share_len(named_group, &expected_len); + if (ret != 0) { + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR, + MBEDTLS_ERR_SSL_INTERNAL_ERROR); + return ret; + } + if (peerkey_len != expected_len) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %u, expected %" + MBEDTLS_PRINTF_SIZET " for group %04x", + (unsigned) peerkey_len, expected_len, + (unsigned) named_group)); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); + return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; + } + + /* Store peer's ECDH/FFDH public key. */ + if (peerkey_len > sizeof(handshake->xxdh_psa_peerkey)) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %u > %" MBEDTLS_PRINTF_SIZET, + (unsigned) peerkey_len, + sizeof(handshake->xxdh_psa_peerkey))); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR, + MBEDTLS_ERR_SSL_INTERNAL_ERROR); + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + memcpy(handshake->xxdh_psa_peerkey, p, peerkey_len); + handshake->xxdh_psa_peerkey_len = peerkey_len; + + return 0; +} + int mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange( mbedtls_ssl_context *ssl, uint16_t named_group, diff --git a/library/ssl_tls13_invasive.h b/library/ssl_tls13_invasive.h index 73e0e304f9..d042c516f0 100644 --- a/library/ssl_tls13_invasive.h +++ b/library/ssl_tls13_invasive.h @@ -16,6 +16,20 @@ int mbedtls_ssl_tls13_parse_certificate(mbedtls_ssl_context *ssl, const unsigned char *buf, const unsigned char *end); + +#if defined(MBEDTLS_SSL_SRV_C) && \ + (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) +int mbedtls_ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end); +#endif + +#if defined(MBEDTLS_SSL_SRV_C) && \ + defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) +int mbedtls_ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end); +#endif #endif /* MBEDTLS_TEST_HOOKS */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 38f2fe9370..d9f7f2b28b 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -17,6 +17,7 @@ #include "mbedtls/psa_util.h" #include "ssl_tls13_keys.h" +#include "ssl_tls13_invasive.h" #include "ssl_debug_helpers.h" @@ -829,9 +830,10 @@ static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl, * } NamedGroupList; */ MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) +MBEDTLS_STATIC_TESTABLE +int mbedtls_ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end) { const unsigned char *p = buf; size_t named_group_list_len; @@ -841,8 +843,24 @@ static int ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl, MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); named_group_list_len = MBEDTLS_GET_UINT16_BE(p, 0); p += 2; + + /* named_group_list is NamedGroup<2..2^16-1>: at least one group (RFC 8446 4.2.7). */ + if (named_group_list_len < 2) { + MBEDTLS_SSL_DEBUG_MSG(1, ("supported_groups list is empty")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR); + return MBEDTLS_ERR_SSL_DECODE_ERROR; + } MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, named_group_list_len); named_group_list_end = p + named_group_list_len; + + /* named_group_list is the whole extension; no trailing data. */ + if (named_group_list_end != end) { + MBEDTLS_SSL_DEBUG_MSG(1, ("supported_groups extension has trailing data")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR); + return MBEDTLS_ERR_SSL_DECODE_ERROR; + } ssl->handshake->hrr_selected_group = 0; while (p < named_group_list_end) { @@ -891,9 +909,10 @@ static int ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl, * - A negative value for fatal errors. */ MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) +MBEDTLS_STATIC_TESTABLE +int mbedtls_ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char const *p = buf; @@ -916,6 +935,14 @@ static int ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl, ssl->handshake->offered_group_id = 0; client_shares_end = p + client_shares_len; + /* client_shares is the whole extension; no trailing data (RFC 8446 4.2.8). */ + if (client_shares_end != end) { + MBEDTLS_SSL_DEBUG_MSG(1, ("key_share extension has trailing data")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR); + return MBEDTLS_ERR_SSL_DECODE_ERROR; + } + /* We try to find a suitable key share entry and copy it to the * handshake context. Later, we have to find out whether we can do * something with the provided key share or whether we have to @@ -937,6 +964,14 @@ static int ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl, group = MBEDTLS_GET_UINT16_BE(p, 0); key_exchange_len = MBEDTLS_GET_UINT16_BE(p, 2); p += 4; + + /* key_exchange is opaque<1..2^16-1>: a zero-length share is malformed. */ + if (key_exchange_len == 0) { + MBEDTLS_SSL_DEBUG_MSG(1, ("key_share entry with empty key_exchange")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR); + return MBEDTLS_ERR_SSL_DECODE_ERROR; + } key_exchange = p; MBEDTLS_SSL_CHK_BUF_READ_PTR(p, client_shares_end, key_exchange_len); p += key_exchange_len; @@ -959,7 +994,7 @@ static int ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl, mbedtls_ssl_named_group_to_str(group), group)); ret = mbedtls_ssl_tls13_read_public_xxdhe_share( - ssl, key_exchange - 2, key_exchange_len + 2); + ssl, group, key_exchange - 2, key_exchange_len + 2); if (ret != 0) { return ret; } @@ -1533,11 +1568,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, * indicates the named groups which the client supports, * ordered from most preferred to least preferred. */ - ret = ssl_tls13_parse_supported_groups_ext( + ret = mbedtls_ssl_tls13_parse_supported_groups_ext( ssl, p, extension_data_end); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_parse_supported_groups_ext", ret); + 1, "mbedtls_ssl_tls13_parse_supported_groups_ext", ret); return ret; } @@ -1555,7 +1590,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, * contains the endpoint's cryptographic parameters for * ECDHE/DHE key establishment methods. */ - ret = ssl_tls13_parse_key_shares_ext( + ret = mbedtls_ssl_tls13_parse_key_shares_ext( ssl, p, extension_data_end); if (ret == SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH) { MBEDTLS_SSL_DEBUG_MSG(2, ("No usable share for key agreement.")); diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 3415c80c90..9d74c51ec3 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3653,3 +3653,37 @@ tls13_record_boundary_alignment:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HS_FINISHED TLS 1.3 EndOfEarlyData record boundary alignment enforcement depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_SESSION_TICKETS tls13_record_boundary_alignment:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HS_END_OF_EARLY_DATA + +TLS 1.3 srv parse key_shares: valid x25519 +depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ECC_MONTGOMERY_255 +tls13_server_parse_key_shares_ext:"0024001d00201111111111111111111111111111111111111111111111111111111111111111":0:-1 + +TLS 1.3 srv parse key_shares: zero-length share +tls13_server_parse_key_shares_ext:"0004001d0000":MBEDTLS_ERR_SSL_DECODE_ERROR:MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR + +TLS 1.3 srv parse key_shares: x25519 share too short (31) +depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ECC_MONTGOMERY_255 +tls13_server_parse_key_shares_ext:"0023001d001f11111111111111111111111111111111111111111111111111111111111111":MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER:MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER + +TLS 1.3 srv parse key_shares: x25519 share too long (33) +depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ECC_MONTGOMERY_255 +tls13_server_parse_key_shares_ext:"0025001d0021111111111111111111111111111111111111111111111111111111111111111111":MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER:MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER + +TLS 1.3 srv parse key_shares: ffdhe2048 share wrong length (255) +depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_DH_RFC7919_2048 +tls13_server_parse_key_shares_ext:"0103010000ff111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111":MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER:MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER + +TLS 1.3 srv parse key_shares: trailing data after client_shares +tls13_server_parse_key_shares_ext:"0024001d00201111111111111111111111111111111111111111111111111111111111111111ff":MBEDTLS_ERR_SSL_DECODE_ERROR:MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR + +TLS 1.3 srv parse supported_groups: valid +tls13_server_parse_supported_groups_ext:"0004001d0017":0:-1 + +TLS 1.3 srv parse supported_groups: empty list +tls13_server_parse_supported_groups_ext:"0000":MBEDTLS_ERR_SSL_DECODE_ERROR:MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR + +TLS 1.3 srv parse supported_groups: trailing data +tls13_server_parse_supported_groups_ext:"0004001d0017ff":MBEDTLS_ERR_SSL_DECODE_ERROR:MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR + +TLS 1.3 srv parse supported_groups: odd length +tls13_server_parse_supported_groups_ext:"0003001d00":MBEDTLS_ERR_SSL_DECODE_ERROR:MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 7a9a03adcd..833bad60ca 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4672,6 +4672,87 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ +void tls13_server_parse_key_shares_ext(data_t *ext, int expected_result, + int expected_alert) +{ + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + int ret; + + /* Offer both an ECDHE and an FFDHE group so a well-formed share for either + * reaches the key-exchange reader, whatever the build's default groups. */ + static const uint16_t groups[] = { + MBEDTLS_SSL_IANA_TLS_GROUP_X25519, + MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048, + MBEDTLS_SSL_IANA_TLS_GROUP_NONE + }; + + mbedtls_ssl_init(&ssl); + mbedtls_ssl_config_init(&conf); + MD_OR_USE_PSA_INIT(); + + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT), 0); + mbedtls_ssl_conf_groups(&conf, groups); + TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0); + + ret = mbedtls_ssl_tls13_parse_key_shares_ext(&ssl, ext->x, + ext->x + ext->len); + TEST_EQUAL(ret, expected_result); + + if (expected_alert >= 0) { + TEST_EQUAL(ssl.MBEDTLS_PRIVATE(send_alert), 1); + TEST_EQUAL(ssl.MBEDTLS_PRIVATE(alert_type), + (unsigned char) expected_alert); + } else { + TEST_EQUAL(ssl.MBEDTLS_PRIVATE(send_alert), 0); + } + +exit: + mbedtls_ssl_free(&ssl); + mbedtls_ssl_config_free(&conf); + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ +void tls13_server_parse_supported_groups_ext(data_t *ext, int expected_result, + int expected_alert) +{ + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + int ret; + + mbedtls_ssl_init(&ssl); + mbedtls_ssl_config_init(&conf); + MD_OR_USE_PSA_INIT(); + + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT), 0); + TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0); + + ret = mbedtls_ssl_tls13_parse_supported_groups_ext(&ssl, ext->x, + ext->x + ext->len); + TEST_EQUAL(ret, expected_result); + + if (expected_alert >= 0) { + TEST_EQUAL(ssl.MBEDTLS_PRIVATE(send_alert), 1); + TEST_EQUAL(ssl.MBEDTLS_PRIVATE(alert_type), + (unsigned char) expected_alert); + } else { + TEST_EQUAL(ssl.MBEDTLS_PRIVATE(send_alert), 0); + } + +exit: + mbedtls_ssl_free(&ssl); + mbedtls_ssl_config_free(&conf); + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA_ANY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 */ void reject_hrr_selecting_unoffered_group(void) {