/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

#include "crypto/s2n_pq.h"
#include "s2n.h"
#include "s2n_test.h"
#include "stuffer/s2n_stuffer.h"
#include "testlib/s2n_testlib.h"
#include "tls/extensions/s2n_client_renegotiation_info.h"
#include "tls/extensions/s2n_cookie.h"
#include "tls/extensions/s2n_extension_type_lists.h"
#include "tls/extensions/s2n_server_supported_versions.h"
#include "tls/s2n_cipher_suites.h"
#include "tls/s2n_connection.h"
#include "tls/s2n_security_policies.h"
#include "tls/s2n_tls.h"
#include "tls/s2n_tls13.h"
#include "tls/s2n_tls13_handshake.h"

/* This include is required to access static function s2n_server_hello_parse */
#include "error/s2n_errno.h"
#include "tls/extensions/s2n_early_data_indication.h"
#include "tls/extensions/s2n_server_key_share.h"
#include "tls/s2n_server_hello.c"
#include "utils/s2n_bitmap.h"
#include "utils/s2n_safety.h"

#define HELLO_RETRY_MSG_NO  1
#define SERVER_HELLO_MSG_NO 5

int s2n_parse_client_hello(struct s2n_connection *conn);

static int s2n_client_hello_cb_with_get_server_name(struct s2n_connection *conn, void *ctx)
{
    const char *expected_server_name = (const char *) ctx;
    const char *actual_server_name = s2n_get_server_name(conn);
    POSIX_ENSURE_EQ(strcmp(expected_server_name, actual_server_name), 0);
    return S2N_SUCCESS;
}

int main(int argc, char **argv)
{
    BEGIN_TEST();

    if (!s2n_is_tls13_fully_supported()) {
        END_TEST();
    }

    EXPECT_SUCCESS(s2n_enable_tls13_in_test());

    /* Test s2n_server_hello_retry_recv */
    {
        /* s2n_server_hello_retry_recv must fail when a keyshare for a matching curve was already present */
        {
            struct s2n_config *config = NULL;
            struct s2n_connection *conn = NULL;

            EXPECT_NOT_NULL(config = s2n_config_new());
            EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
            EXPECT_SUCCESS(s2n_connection_set_config(conn, config));

            const struct s2n_ecc_preferences *ecc_pref = NULL;
            POSIX_GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
            EXPECT_NOT_NULL(ecc_pref);

            conn->actual_protocol_version = S2N_TLS13;
            conn->kex_params.server_ecc_evp_params.negotiated_curve = ecc_pref->ecc_curves[0];
            conn->kex_params.client_ecc_evp_params.negotiated_curve = ecc_pref->ecc_curves[0];

            EXPECT_NULL(conn->kex_params.client_ecc_evp_params.evp_pkey);
            EXPECT_SUCCESS(s2n_ecc_evp_generate_ephemeral_key(&conn->kex_params.client_ecc_evp_params));
            EXPECT_NOT_NULL(conn->kex_params.client_ecc_evp_params.evp_pkey);

            EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY);

            EXPECT_SUCCESS(s2n_config_free(config));
            EXPECT_SUCCESS(s2n_connection_free(conn));
        };

        /* s2n_server_hello_retry_recv must fail for a connection with actual protocol version less than TLS13 */
        {
            struct s2n_config *config = NULL;
            struct s2n_connection *conn = NULL;

            EXPECT_NOT_NULL(config = s2n_config_new());
            EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
            EXPECT_SUCCESS(s2n_connection_set_config(conn, config));

            conn->actual_protocol_version = S2N_TLS12;

            EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY);

            EXPECT_SUCCESS(s2n_config_free(config));
            EXPECT_SUCCESS(s2n_connection_free(conn));
        };

        /* Test ECC success case for s2n_server_hello_retry_recv */
        {
            struct s2n_config *server_config = NULL;
            struct s2n_config *client_config = NULL;

            struct s2n_connection *server_conn = NULL;
            struct s2n_connection *client_conn = NULL;

            struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL;
            char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 };
            char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 };

            EXPECT_NOT_NULL(server_config = s2n_config_new());
            EXPECT_NOT_NULL(client_config = s2n_config_new());

            EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
            EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));

            EXPECT_NOT_NULL(tls13_chain_and_key = s2n_cert_chain_and_key_new());
            EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, tls13_cert_chain, S2N_MAX_TEST_PEM_SIZE));
            EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, tls13_private_key, S2N_MAX_TEST_PEM_SIZE));
            EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(tls13_chain_and_key, tls13_cert_chain, tls13_private_key));
            EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(client_config, tls13_chain_and_key));
            EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, tls13_chain_and_key));

            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
            EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                    s2n_stuffer_data_available(&client_conn->handshake.io)));

            /* Server receives ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));

            server_conn->kex_params.server_ecc_evp_params.negotiated_curve = s2n_all_supported_curves_list[0];
            EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

            /* Server sends HelloRetryMessage */
            EXPECT_SUCCESS(s2n_server_hello_retry_send(server_conn));

            EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
            EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                    s2n_stuffer_data_available(&server_conn->handshake.io)));
            client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;
            /* Read the message off the wire */
            EXPECT_SUCCESS(s2n_server_hello_parse(client_conn));
            client_conn->actual_protocol_version_established = 1;

            EXPECT_SUCCESS(s2n_conn_set_handshake_type(client_conn));
            /* Client receives the HelloRetryRequest mesage */
            EXPECT_SUCCESS(s2n_server_hello_retry_recv(client_conn));

            EXPECT_SUCCESS(s2n_config_free(client_config));
            EXPECT_SUCCESS(s2n_config_free(server_config));
            EXPECT_SUCCESS(s2n_connection_free(server_conn));
            EXPECT_SUCCESS(s2n_connection_free(client_conn));
            EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key));
        };

        {
            const struct s2n_security_policy test_security_policy = {
                .minimum_protocol_version = S2N_SSLv3,
                .cipher_preferences = &cipher_preferences_test_all_tls13,
                .kem_preferences = &kem_preferences_all,
                .signature_preferences = &s2n_signature_preferences_20200207,
                .ecc_preferences = &s2n_ecc_preferences_20200310,
            };

            if (!s2n_pq_is_enabled()) {
                struct s2n_connection *conn = NULL;
                EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
                conn->actual_protocol_version = S2N_TLS13;
                conn->security_policy_override = &test_security_policy;

                const struct s2n_kem_preferences *kem_pref = NULL;
                POSIX_GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
                EXPECT_NOT_NULL(kem_pref);

                conn->kex_params.server_kem_group_params.kem_group = kem_pref->tls13_kem_groups[0];
                EXPECT_NULL(conn->kex_params.server_ecc_evp_params.negotiated_curve);

                EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY);

                EXPECT_SUCCESS(s2n_connection_free(conn));
            } else {
                /* s2n_server_hello_retry_recv must fail when a keyshare for a matching PQ KEM was already present */
                {
                    struct s2n_connection *conn = NULL;
                    EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
                    conn->actual_protocol_version = S2N_TLS13;
                    conn->security_policy_override = &test_security_policy;

                    const struct s2n_kem_preferences *kem_pref = NULL;
                    POSIX_GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
                    EXPECT_NOT_NULL(kem_pref);

                    const struct s2n_kem_group *kem_group = s2n_kem_preferences_get_highest_priority_group(kem_pref);
                    EXPECT_NOT_NULL(kem_group);

                    conn->kex_params.server_kem_group_params.kem_group = kem_group;
                    EXPECT_NULL(conn->kex_params.server_ecc_evp_params.negotiated_curve);

                    struct s2n_kem_group_params *client_params = &conn->kex_params.client_kem_group_params;
                    client_params->kem_group = kem_group;
                    client_params->kem_params.kem = kem_group->kem;
                    client_params->ecc_params.negotiated_curve = kem_group->curve;

                    EXPECT_NULL(client_params->ecc_params.evp_pkey);
                    EXPECT_NULL(client_params->kem_params.private_key.data);

                    kem_public_key_size public_key_size = kem_group->kem->public_key_length;
                    EXPECT_SUCCESS(s2n_alloc(&client_params->kem_params.public_key, public_key_size));

                    EXPECT_OK(s2n_kem_generate_keypair(&client_params->kem_params));
                    EXPECT_NOT_NULL(client_params->kem_params.private_key.data);
                    EXPECT_SUCCESS(s2n_ecc_evp_generate_ephemeral_key(&client_params->ecc_params));
                    EXPECT_NOT_NULL(client_params->ecc_params.evp_pkey);

                    EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY);

                    EXPECT_SUCCESS(s2n_free(&client_params->kem_params.public_key));
                    EXPECT_SUCCESS(s2n_connection_free(conn));
                };
                /* Test failure if exactly one of {named_curve, kem_group} isn't non-null */
                {
                    struct s2n_connection *conn = NULL;
                    EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
                    conn->actual_protocol_version = S2N_TLS13;
                    conn->security_policy_override = &test_security_policy;

                    conn->kex_params.server_kem_group_params.kem_group = &s2n_secp256r1_kyber_512_r3;
                    conn->kex_params.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp256r1;

                    EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY);

                    conn->kex_params.server_kem_group_params.kem_group = NULL;
                    conn->kex_params.server_ecc_evp_params.negotiated_curve = NULL;

                    EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY);

                    EXPECT_SUCCESS(s2n_connection_free(conn));
                };
                /* Test PQ KEM success case for s2n_server_hello_retry_recv. */
                /* Need at least two KEM's to test fallback */
                uint32_t available_groups = 0;
                EXPECT_OK(s2n_kem_preferences_groups_available(test_security_policy.kem_preferences, &available_groups));
                if (available_groups >= 2) {
                    struct s2n_config *config = NULL;
                    struct s2n_connection *conn = NULL;

                    struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL;
                    char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 };
                    char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 };

                    EXPECT_NOT_NULL(config = s2n_config_new());
                    EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
                    conn->security_policy_override = &test_security_policy;

                    EXPECT_NOT_NULL(tls13_chain_and_key = s2n_cert_chain_and_key_new());
                    EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, tls13_cert_chain, S2N_MAX_TEST_PEM_SIZE));
                    EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, tls13_private_key, S2N_MAX_TEST_PEM_SIZE));
                    EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(tls13_chain_and_key, tls13_cert_chain, tls13_private_key));
                    EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, tls13_chain_and_key));

                    /* Client sends ClientHello containing key share for p256+Kyber
                     * (but indicates support for x25519+Kyber in supported_groups) */
                    EXPECT_SUCCESS(s2n_client_hello_send(conn));

                    EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->handshake.io));
                    conn->session_id_len = 0; /* Wipe the session id to match the HRR hex */

                    /* Server responds with HRR indicating x25519+Kyber as choice for negotiation;
                     * the last 6 bytes (0033 0002 2F39) are the key share extension with x25519+Kyber */
                    DEFER_CLEANUP(struct s2n_stuffer hrr = { 0 }, s2n_stuffer_free);
                    EXPECT_OK(s2n_stuffer_alloc_from_hex(&hrr,
                            "0303CF21AD74E59A6111BE1D8C021E65B891C2A211167ABB8C5E079E09E2C8A8339C00130200000C002B00020304003300022F39"));

                    EXPECT_SUCCESS(s2n_stuffer_copy(&hrr, &conn->handshake.io, s2n_stuffer_data_available(&hrr)));
                    conn->handshake.message_number = HELLO_RETRY_MSG_NO;
                    /* Read the message off the wire */
                    EXPECT_SUCCESS(s2n_server_hello_parse(conn));
                    conn->actual_protocol_version_established = 1;

                    EXPECT_SUCCESS(s2n_conn_set_handshake_type(conn));
                    /* Client receives the HelloRetryRequest message */
                    EXPECT_SUCCESS(s2n_server_hello_retry_recv(conn));

                    EXPECT_SUCCESS(s2n_config_free(config));
                    EXPECT_SUCCESS(s2n_connection_free(conn));
                    EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key));
                }
            }
        };
    };

    /* Verify that the hash transcript recreation function is called correctly,
     * within the s2n_server_hello_retry_send and s2n_server_hello_retry_recv functions.
     * The hash transcript recreation function, if called correctly takes the existing ClientHello1
     * hash, and generates a synthetic message. This test verifies that transcript hash recreated is the same
     * on both the server and client side. */
    {
        struct s2n_config *server_config = NULL;
        struct s2n_config *client_config = NULL;

        struct s2n_connection *server_conn = NULL;
        struct s2n_connection *client_conn = NULL;

        struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL;
        char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 };
        char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 };

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_NOT_NULL(client_config = s2n_config_new());

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));

        EXPECT_NOT_NULL(tls13_chain_and_key = s2n_cert_chain_and_key_new());
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, tls13_cert_chain, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, tls13_private_key, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(tls13_chain_and_key, tls13_cert_chain, tls13_private_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(client_config, tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, tls13_chain_and_key));

        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry;

        /* ClientHello 1 */
        EXPECT_SUCCESS(s2n_client_hello_send(client_conn));

        EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                s2n_stuffer_data_available(&client_conn->handshake.io)));

        /* Server receives ClientHello 1 */
        EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
        EXPECT_TRUE(s2n_is_hello_retry_handshake(server_conn));
        EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

        server_conn->kex_params.server_ecc_evp_params.negotiated_curve = s2n_all_supported_curves_list[0];

        /* Server sends HelloRetryRequest message, note that s2n_server_hello_retry_recreate_transcript
         * is called within the s2n_server_hello_retry_send function */
        EXPECT_SUCCESS(s2n_server_hello_retry_send(server_conn));

        s2n_tls13_connection_keys(server_keys, server_conn);
        uint8_t hash_digest_length = server_keys.size;

        /* Obtain the transcript hash recreated within the HelloRetryRequest message */
        DEFER_CLEANUP(struct s2n_hash_state server_hash = { 0 }, s2n_hash_free);
        uint8_t server_digest_out[S2N_MAX_DIGEST_LEN] = { 0 };
        POSIX_GUARD(s2n_hash_new(&server_hash));
        POSIX_GUARD_RESULT(s2n_handshake_copy_hash_state(server_conn, server_keys.hash_algorithm, &server_hash));
        POSIX_GUARD(s2n_hash_digest(&server_hash, server_digest_out, hash_digest_length));

        struct s2n_blob server_blob = { 0 };
        EXPECT_SUCCESS(s2n_blob_init(&server_blob, server_digest_out, hash_digest_length));

        EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
        EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                s2n_stuffer_data_available(&server_conn->handshake.io)));
        client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;
        /* Client receives the HelloRetryRequest mesage, note that s2n_server_hello_retry_recreate_transcript
         * is called within the s2n_server_hello_recv function */
        EXPECT_SUCCESS(s2n_server_hello_recv(client_conn));

        s2n_tls13_connection_keys(client_keys, client_conn);
        hash_digest_length = client_keys.size;

        /* Obtain the transcript hash recreated within ClientHello2 message */
        DEFER_CLEANUP(struct s2n_hash_state client_hash = { 0 }, s2n_hash_free);
        uint8_t client_digest_out[S2N_MAX_DIGEST_LEN];
        POSIX_GUARD(s2n_hash_new(&client_hash));
        POSIX_GUARD_RESULT(s2n_handshake_copy_hash_state(client_conn, client_keys.hash_algorithm, &client_hash));
        POSIX_GUARD(s2n_hash_digest(&client_hash, client_digest_out, hash_digest_length));

        struct s2n_blob client_blob = { 0 };
        EXPECT_SUCCESS(s2n_blob_init(&client_blob, client_digest_out, hash_digest_length));

        /* Test that the transcript hash recreated MUST be the same on the server and client side */
        S2N_BLOB_EXPECT_EQUAL(client_blob, server_blob);

        EXPECT_SUCCESS(s2n_config_free(client_config));
        EXPECT_SUCCESS(s2n_config_free(server_config));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key));
    };

    /**
     * Self-Talk test: the client initiates a handshake with an unknown keyshare.
     * The server sends a HelloRetryRequest that requires the client to generate a
     * key share on the server negotiated curve.
     *
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
     *= type=test
     *# Otherwise, the client MUST process all extensions in the
     *# HelloRetryRequest and send a second updated ClientHello.
     **/
    {
        struct s2n_config *server_config = NULL;
        struct s2n_config *client_config = NULL;

        struct s2n_connection *server_conn = NULL;
        struct s2n_connection *client_conn = NULL;

        struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL;
        char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 };
        char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 };

        /* Create nonblocking pipes */
        struct s2n_test_io_pair io_pair;
        EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_NOT_NULL(client_config = s2n_config_new());

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));

        EXPECT_NOT_NULL(tls13_chain_and_key = s2n_cert_chain_and_key_new());
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, tls13_cert_chain, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, tls13_private_key, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(tls13_chain_and_key, tls13_cert_chain, tls13_private_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(client_config, tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config));

        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config));

        server_conn->x509_validator.skip_cert_validation = 1;
        client_conn->x509_validator.skip_cert_validation = 1;

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry;

        EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

        /* Negotiate handshake */
        EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));

        EXPECT_SUCCESS(s2n_shutdown_test_server_and_client(server_conn, client_conn));

        EXPECT_SUCCESS(s2n_config_free(client_config));
        EXPECT_SUCCESS(s2n_config_free(server_config));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_io_pair_close(&io_pair));
    };

    /**
     * Self-Talk test: the client initiates a handshake with an X25519 share.
     * The server, however does not support x25519 and prefers P-256.
     * The server then sends a HelloRetryRequest that requires the
     * client to generate a key share on the P-256 curve.
     *
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.1
     *= type=test
     *# If the server selects an (EC)DHE group and the client did not offer a
     *# compatible "key_share" extension in the initial ClientHello, the
     *# server MUST respond with a HelloRetryRequest (Section 4.1.4) message.
     **/
    if (s2n_is_evp_apis_supported()) {
        struct s2n_config *server_config = NULL;
        struct s2n_config *client_config = NULL;

        struct s2n_connection *server_conn = NULL;
        struct s2n_connection *client_conn = NULL;

        struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL;
        char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 };
        char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 };

        /* Create nonblocking pipes */
        struct s2n_test_io_pair io_pair;
        EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_NOT_NULL(client_config = s2n_config_new());

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));

        EXPECT_NOT_NULL(tls13_chain_and_key = s2n_cert_chain_and_key_new());
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, tls13_cert_chain, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, tls13_private_key, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(tls13_chain_and_key, tls13_cert_chain, tls13_private_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(client_config, tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config));

        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_config, "20190801")); /* contains x25519 */
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_config, "20190802")); /* does not contain x25519 */

        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config));

        server_conn->x509_validator.skip_cert_validation = 1;
        client_conn->x509_validator.skip_cert_validation = 1;

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry;

        EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

        /* Negotiate handshake */
        EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));

        EXPECT_SUCCESS(s2n_shutdown_test_server_and_client(server_conn, client_conn));

        /* Ensure the handshake included a hello retry request */
        EXPECT_TRUE(IS_HELLO_RETRY_HANDSHAKE(client_conn));
        EXPECT_TRUE(IS_HELLO_RETRY_HANDSHAKE(server_conn));

        EXPECT_SUCCESS(s2n_config_free(client_config));
        EXPECT_SUCCESS(s2n_config_free(server_config));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_io_pair_close(&io_pair));
    }

    /**
     * Ensure the client aborts the handshake if more than one
     * HelloRetryRequest is received
     *
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
     *= type=test
     *# If a client receives a second
     *# HelloRetryRequest in the same connection (i.e., where the ClientHello
     *# was itself in response to a HelloRetryRequest), it MUST abort the
     *# handshake with an "unexpected_message" alert.
     **/
    {
        struct s2n_config *server_config = NULL;
        struct s2n_config *client_config = NULL;

        struct s2n_connection *server_conn = NULL;
        struct s2n_connection *client_conn = NULL;

        struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL;
        char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 };
        char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 };

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_NOT_NULL(client_config = s2n_config_new());

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));

        EXPECT_NOT_NULL(tls13_chain_and_key = s2n_cert_chain_and_key_new());
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, tls13_cert_chain, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, tls13_private_key, S2N_MAX_TEST_PEM_SIZE));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(tls13_chain_and_key, tls13_cert_chain, tls13_private_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(client_config, tls13_chain_and_key));
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, tls13_chain_and_key));

        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry;

        /* ClientHello 1 */
        EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
        EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                s2n_stuffer_data_available(&client_conn->handshake.io)));
        EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
        EXPECT_TRUE(s2n_is_hello_retry_handshake(server_conn));
        EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

        /* Server HelloRetryRequest 1 */
        EXPECT_SUCCESS(s2n_server_hello_retry_send(server_conn));
        EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

        EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
        EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                s2n_stuffer_data_available(&server_conn->handshake.io)));
        client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;
        EXPECT_SUCCESS(s2n_server_hello_recv(client_conn));

        /* ClientHello 2 */
        EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
        EXPECT_SUCCESS(s2n_stuffer_wipe(&server_conn->handshake.io));
        EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                s2n_stuffer_data_available(&client_conn->handshake.io)));
        EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));

        /* Server HelloRetryRequest 2 */
        EXPECT_SUCCESS(s2n_server_hello_retry_send(server_conn));

        EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
        EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                s2n_stuffer_data_available(&server_conn->handshake.io)));

        EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_recv(client_conn), S2N_ERR_INVALID_HELLO_RETRY);

        EXPECT_SUCCESS(s2n_config_free(client_config));
        EXPECT_SUCCESS(s2n_config_free(server_config));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key));
    };

    /**
     * Ensure that s2n_random_value_is_hello_retry returns true for hello
     * retry random values, and false otherwise
     *
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.3
     *= type=test
     *# Upon receiving a message with type server_hello, implementations MUST
     *# first examine the Random value and, if it matches this value, process
     *# it as described in Section 4.1.4).
     **/
    {
        struct s2n_connection *conn = NULL;
        EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
        const uint8_t not_hello_retry_request_random[S2N_TLS_RANDOM_DATA_LEN] = { 0 };
        EXPECT_MEMCPY_SUCCESS(conn->handshake_params.server_random, not_hello_retry_request_random,
                S2N_TLS_RANDOM_DATA_LEN);

        EXPECT_FAILURE_WITH_ERRNO(s2n_random_value_is_hello_retry(conn), S2N_ERR_INVALID_HELLO_RETRY);

        EXPECT_MEMCPY_SUCCESS(conn->handshake_params.server_random, hello_retry_req_random, S2N_TLS_RANDOM_DATA_LEN);
        EXPECT_SUCCESS(s2n_random_value_is_hello_retry(conn));

        EXPECT_SUCCESS(s2n_connection_free(conn));
    };

    /**
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
     *= type=test
     *# Upon receiving
     *# the ServerHello, clients MUST check that the cipher suite supplied in
     *# the ServerHello is the same as that in the HelloRetryRequest and
     *# otherwise abort the handshake with an "illegal_parameter" alert.
     **/
    {
        struct s2n_connection *server_conn = NULL;
        struct s2n_connection *client_conn = NULL;

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));

        /* A Hello Retry Request has been processed */
        EXPECT_SUCCESS(s2n_set_hello_retry_required(client_conn));
        client_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384;
        client_conn->server_protocol_version = S2N_TLS13;
        client_conn->handshake.handshake_type |= NEGOTIATED;
        client_conn->handshake.handshake_type |= FULL_HANDSHAKE;
        client_conn->handshake.message_number = SERVER_HELLO_MSG_NO;

        /* Server Hello with cipher suite that does not match Hello Retry Request cipher suite */
        server_conn->secure->cipher_suite = &s2n_tls13_chacha20_poly1305_sha256;
        EXPECT_SUCCESS(s2n_server_hello_send(server_conn));

        EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
        EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                s2n_stuffer_data_available(&server_conn->handshake.io)));

        EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_recv(client_conn), S2N_ERR_CIPHER_NOT_SUPPORTED);

        EXPECT_SUCCESS(s2n_connection_free(server_conn));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
    };

    /*
     * Self-Talk
     *
     *= https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2
     *= type=test
     *# The client will also send a
     *# ClientHello when the server has responded to its ClientHello with a
     *# HelloRetryRequest.  In that case, the client MUST send the same
     *# ClientHello without modification
     */
    if (s2n_is_tls13_fully_supported()) {
        DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL,
                s2n_cert_chain_and_key_ptr_free);
        EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
                S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY));

        DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(),
                s2n_config_ptr_free);
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13"));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(config));

        /* Sanity Check: The server accepts an unchanged ClientHello */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Send ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

            /* Finish handshake */
            EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
        };

        /* Test: The server rejects a second ClientHello with a changed legacy version */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Skip to before the client sends the second ClientHello. */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

            /* Change the legacy version. */
            client_conn->client_protocol_version = S2N_TLS11;

            /* Expect failure because second client hello doesn't match */
            EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                    S2N_ERR_BAD_MESSAGE);
        };

        /* Test: The server rejects a second ClientHello with changed client random */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Send ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

            /* Change client random */
            client_conn->handshake_params.client_random[0]++;

            /* Expect failure because second client hello doesn't match */
            EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                    S2N_ERR_BAD_MESSAGE);
        };

        /* Test: Outside of testing, the server accepts a second ClientHello with a changed client random */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Send ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

            /* Change client random */
            client_conn->handshake_params.client_random[0]++;

            /* Expect success if we pretend that this isn't a unit test */
            EXPECT_SUCCESS(s2n_in_unit_test_set(false));
            EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
            EXPECT_SUCCESS(s2n_in_unit_test_set(true));
        }

        /* Test: The server accepts a second ClientHello with a changed session ID */
        for (size_t test_in_test_mode = 0; test_in_test_mode <= 1; test_in_test_mode++) {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path. */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Skip to before the client sends the second ClientHello. */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

            /* Change session id */
            client_conn->session_id[0]++;

            if (test_in_test_mode) {
                /* Ensure that validation fails in test mode to prevent regressions. */
                EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                        S2N_ERR_BAD_MESSAGE);
            } else {
                EXPECT_SUCCESS(s2n_in_unit_test_set(false));
                EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
                EXPECT_SUCCESS(s2n_in_unit_test_set(true));
            }
        };

        /* Test: The server accepts a second ClientHello with a changed cipher suite list */
        for (size_t test_in_test_mode = 0; test_in_test_mode <= 1; test_in_test_mode++) {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            struct s2n_security_policy test_policy = security_policy_test_tls13_retry;
            struct s2n_cipher_suite *test_cipher_suites[] = {
                &s2n_tls13_aes_128_gcm_sha256,
                &s2n_tls13_aes_256_gcm_sha384
            };
            struct s2n_cipher_preferences test_cipher_preferences = {
                .count = s2n_array_len(test_cipher_suites),
                .suites = test_cipher_suites,
            };
            test_policy.cipher_preferences = &test_cipher_preferences;

            /* Force the HRR path. */
            client_conn->security_policy_override = &test_policy;

            /* Skip to before the client sends the second ClientHello. */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

            /* Modify a cipher suite. */
            test_cipher_suites[1] = &s2n_tls13_chacha20_poly1305_sha256;

            if (test_in_test_mode) {
                /* Ensure that validation fails in test mode to prevent regressions. */
                EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                        S2N_ERR_BAD_MESSAGE);
            } else {
                EXPECT_SUCCESS(s2n_in_unit_test_set(false));
                EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
                EXPECT_SUCCESS(s2n_in_unit_test_set(true));
            }
        };

        /* Test: Ensure that the connection fails if the cipher suite list changes such that the
         * server cannot negotiate its original selection from the first ClientHello
         *
         *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
         *= type=test
         *# Servers MUST ensure that they negotiate the
         *# same cipher suite when receiving a conformant updated ClientHello (if
         *# the server selects the cipher suite as the first step in the
         *# negotiation, then this will happen automatically).
         **/
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            struct s2n_security_policy test_policy = security_policy_test_tls13_retry;
            struct s2n_cipher_suite *test_cipher_suites[] = {
                &s2n_tls13_aes_128_gcm_sha256,
                &s2n_tls13_aes_256_gcm_sha384
            };
            struct s2n_cipher_preferences test_cipher_preferences = {
                .count = s2n_array_len(test_cipher_suites),
                .suites = test_cipher_suites,
            };
            test_policy.cipher_preferences = &test_cipher_preferences;

            /* Force the HRR path. */
            client_conn->security_policy_override = &test_policy;

            /* Skip to before the client sends the second ClientHello. */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

            /* Replace the most preferred cipher suite, forcing the server to select a different
             * cipher suite when processing the second ClientHello.
             */
            test_cipher_suites[0] = &s2n_tls13_chacha20_poly1305_sha256;

            /* Test mode is disabled to skip the failing ClientHello comparison check due to a
             * changed cipher suite list.
             */
            EXPECT_SUCCESS(s2n_in_unit_test_set(false));
            EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                    S2N_ERR_BAD_MESSAGE);
            EXPECT_SUCCESS(s2n_in_unit_test_set(true));
        };

        /* The server rejects a second ClientHello with a changed compression methods field */
        for (uint8_t test_compression_method = 0; test_compression_method <= 1; test_compression_method++) {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path. */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Skip to before the client sends the second ClientHello. */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

            /* Send the second ClientHello. */
            EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
            EXPECT_SUCCESS(s2n_stuffer_wipe(&server_conn->handshake.io));
            EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                    s2n_stuffer_data_available(&client_conn->handshake.io)));

            struct s2n_stuffer client_hello_stuffer = { 0 };
            EXPECT_SUCCESS(s2n_stuffer_init_written(&client_hello_stuffer, &server_conn->handshake.io.blob));

            /* Read up to the single null compression method byte */
            EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, S2N_TLS_PROTOCOL_VERSION_LEN));
            EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, S2N_TLS_RANDOM_DATA_LEN));
            uint8_t session_id_len = 0;
            EXPECT_SUCCESS(s2n_stuffer_read_uint8(&client_hello_stuffer, &session_id_len));
            EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, session_id_len));
            uint16_t cipher_suites_len = 0;
            EXPECT_SUCCESS(s2n_stuffer_read_uint16(&client_hello_stuffer, &cipher_suites_len));
            EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, cipher_suites_len));
            uint8_t compression_methods_len = 0;
            EXPECT_SUCCESS(s2n_stuffer_read_uint8(&client_hello_stuffer, &compression_methods_len));
            EXPECT_EQUAL(compression_methods_len, 1);
            uint32_t compression_method_pos = client_hello_stuffer.read_cursor;

            /* Overwrite the compression method in the second ClientHello. */
            EXPECT_SUCCESS(s2n_stuffer_rewrite(&client_hello_stuffer));
            EXPECT_SUCCESS(s2n_stuffer_skip_write(&client_hello_stuffer, compression_method_pos));
            EXPECT_SUCCESS(s2n_stuffer_write_uint8(&client_hello_stuffer, test_compression_method));

            if (test_compression_method == 0) {
                /* A second ClientHello with a compression method of 0 shouldn't be different from
                 * the first ClientHello, so validation should succeed.
                 */
                EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
            } else {
                EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_recv(server_conn), S2N_ERR_BAD_MESSAGE);
            }
        };

        /* The server accepts a second ClientHello with a changed supported versions extension */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            struct s2n_security_policy test_policy = security_policy_test_tls13_retry;
            test_policy.minimum_protocol_version = S2N_TLS10;

            /* Force the HRR path. */
            client_conn->security_policy_override = &test_policy;

            /* Skip to after the first ClientHello is received. */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));

            struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(server_conn);
            EXPECT_NOT_NULL(client_hello);
            ssize_t first_supported_versions_length = s2n_client_hello_get_extension_length(client_hello,
                    S2N_EXTENSION_SUPPORTED_VERSIONS);

            /* Skip to before the client sends the second ClientHello. */
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

            /* Increase the minimum protocol version for the security policy to send fewer
             * supported versions in the second ClientHello.
             */
            test_policy.minimum_protocol_version = S2N_TLS11;

            EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));

            /* Ensure that the supported versions extension changed. */
            ssize_t second_supported_versions_length = s2n_client_hello_get_extension_length(client_hello,
                    S2N_EXTENSION_SUPPORTED_VERSIONS);
            EXPECT_TRUE(first_supported_versions_length != second_supported_versions_length);
        }

        /* Test: The server rejects a supported versions extension with < TLS 1.3 in the second ClientHello */
        for (uint8_t test_version = S2N_TLS10; test_version <= S2N_TLS13; test_version++) {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path. */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Skip to before the client sends the second ClientHello. */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

            /* Send the second ClientHello. */
            EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
            EXPECT_SUCCESS(s2n_stuffer_wipe(&server_conn->handshake.io));
            EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                    s2n_stuffer_data_available(&client_conn->handshake.io)));

            /* Parse the ClientHello, but don't process the extensions yet. */
            EXPECT_SUCCESS(s2n_parse_client_hello(server_conn));
            server_conn->client_hello.parsed = true;

            uint8_t extension_data[3] = { 0 };
            struct s2n_blob extension_blob = { 0 };
            EXPECT_SUCCESS(s2n_blob_init(&extension_blob, extension_data, sizeof(extension_data)));
            struct s2n_stuffer extension_stuffer = { 0 };
            EXPECT_SUCCESS(s2n_stuffer_init(&extension_stuffer, &extension_blob));

            /* Overwrite the received supported versions extension with only the test version. */
            uint8_t extension_length = 2;
            EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension_stuffer, extension_length));
            EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension_stuffer, test_version / 10));
            EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension_stuffer, test_version % 10));

            struct s2n_client_hello *second_client_hello = s2n_connection_get_client_hello(server_conn);
            EXPECT_NOT_NULL(second_client_hello);
            s2n_extension_type_id supported_versions_id = 0;
            EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(S2N_EXTENSION_SUPPORTED_VERSIONS, &supported_versions_id));
            s2n_parsed_extension *extension = &second_client_hello->extensions.parsed_extensions[supported_versions_id];
            extension->extension_type = S2N_EXTENSION_SUPPORTED_VERSIONS;
            extension->extension = extension_blob;

            int ret = s2n_client_hello_recv(server_conn);
            if (test_version == S2N_TLS13) {
                EXPECT_SUCCESS(ret);
            } else {
                EXPECT_FAILURE_WITH_ERRNO(ret, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
            }
        }

        /* Test: The server rejects a second ClientHello with a changed extension */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));
            EXPECT_SUCCESS(s2n_set_server_name(client_conn, "localhost"));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Send ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

            /* Change server name */
            client_conn->server_name[0]++;

            /* Expect failure because second client hello doesn't match */
            EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                    S2N_ERR_BAD_MESSAGE);
        };

        /* Test: The server rejects a second ClientHello with a removed extension */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));
            EXPECT_SUCCESS(s2n_set_server_name(client_conn, "localhost"));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Send ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

            /* Clear server name.
             * Without a server name, we don't send the server name extension. */
            client_conn->server_name[0] = '\0';

            /* Expect failure because second client hello doesn't match */
            EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                    S2N_ERR_BAD_MESSAGE);
        };

        /* Test: The server rejects a second ClientHello with an added extension */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Send ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

            /* Add a server name.
             * Without a server name, we don't send the server name extension. */
            EXPECT_SUCCESS(s2n_set_server_name(client_conn, "localhost"));

            /* Expect failure because second client hello doesn't match */
            EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                    S2N_ERR_BAD_MESSAGE);
        };

        /*
         * Test: If the initial ClientHello includes all extensions, so does the second ClientHello.
         *
         * This includes TLS1.2 extensions, since the ClientHello is sent before
         * the client knows what version the server will negotiate.
         *
         * We have to test with all extensions to ensure that an s2n server will never reject
         * an s2n client's second ClientHello.
         *
         * TLS1.2 and TLS1.3 session tickets are mutually exclusive and use different
         * extensions, so we test once with each.
         */
        for (size_t tls13_tickets = 0; tls13_tickets < 2; tls13_tickets++) {
            DEFER_CLEANUP(struct s2n_config *client_config = s2n_config_new(),
                    s2n_config_ptr_free);
            EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config));

            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            const struct s2n_security_policy security_policy_test_tls13_retry_with_pq = {
                .minimum_protocol_version = S2N_TLS11,
                .cipher_preferences = &cipher_preferences_pq_tls_1_1_2021_05_21,
                .kem_preferences = &kem_preferences_pq_tls_1_0_2021_05,
                .signature_preferences = &s2n_signature_preferences_20200207,
                .ecc_preferences = &ecc_preferences_for_retry,
            };
            client_conn->security_policy_override = &security_policy_test_tls13_retry_with_pq;

            /* Setup all extensions */
            uint8_t apn[] = "https";
            EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_config, "PQ-TLS-1-2-2023-10-07"));
            EXPECT_SUCCESS(s2n_config_set_status_request_type(client_config, S2N_STATUS_REQUEST_OCSP));
            EXPECT_SUCCESS(s2n_config_set_ct_support_level(client_config, S2N_CT_SUPPORT_REQUEST));
            EXPECT_SUCCESS(s2n_config_send_max_fragment_length(client_config, S2N_TLS_MAX_FRAG_LEN_4096));
            EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(client_config, 1));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config));
            EXPECT_SUCCESS(s2n_set_server_name(client_conn, "localhost"));
            EXPECT_SUCCESS(s2n_connection_append_protocol_preference(client_conn, apn, sizeof(apn)));
            EXPECT_SUCCESS(s2n_connection_set_early_data_expected(client_conn));
            client_conn->config->npn_supported = true;
            if (tls13_tickets) {
                EXPECT_OK(s2n_append_test_psk_with_early_data(client_conn, 1, &s2n_tls13_aes_256_gcm_sha384));
            }
            EXPECT_SUCCESS(s2n_connection_enable_quic(client_conn));
            /* Need to enable quic on both sides so they can communicate */
            EXPECT_SUCCESS(s2n_connection_enable_quic(server_conn));

            /* Send and receive ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));

            /* All ClientHello extensions must be present (except very specific exceptions)  */
            s2n_extension_type_list *extensions = NULL;
            EXPECT_SUCCESS(s2n_extension_type_list_get(S2N_EXTENSION_LIST_CLIENT_HELLO, &extensions));
            for (size_t i = 0; i < extensions->count; i++) {
                uint16_t iana = extensions->extension_types[i]->iana_value;

                /* The cookie is a special case and only appears AFTER the retry */
                if (iana == TLS_EXTENSION_COOKIE) {
                    continue;
                }

                /* PQ TLS 1.2  extension is not enabled */
                if (iana == TLS_EXTENSION_PQ_KEM_PARAMETERS) {
                    continue;
                }

                /* TLS1.2 session tickets and TLS1.3 session tickets are mutually exclusive */
                if (tls13_tickets && iana == TLS_EXTENSION_SESSION_TICKET) {
                    continue;
                } else if (!tls13_tickets
                        && (iana == TLS_EXTENSION_PRE_SHARED_KEY
                                || iana == TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES
                                || iana == TLS_EXTENSION_EARLY_DATA)) {
                    continue;
                }

                /* No extension is sent for an initial handshake,
                 * and TLS1.3 doesn't support renegotiation handshakes.
                 */
                if (iana == TLS_EXTENSION_RENEGOTIATION_INFO) {
                    continue;
                }

                bool extension_exists = false;
                EXPECT_SUCCESS(s2n_client_hello_has_extension(&server_conn->client_hello,
                        iana, &extension_exists));
                EXPECT_TRUE(extension_exists);
            }

            /* Expect successful retry */
            EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
        }

        /* Processing an extension early does not affect the extension matching check.
         *
         * This test exists because of a previously released bug. Triggering the bug
         * required a specific series of events:
         * - The first ClientHello is received.
         * - The extensions are parsed.
         * - The ClientHello callback triggers.
         * - The customer's ClientHello callback implementation calls the s2n_get_server_name API.
         *   - To retrieve the server name, s2n_get_server_name processes the server name extension early.
         *     - The server name extension is wiped. Before the "processed" flag, we wiped extensions
         *       to mark that they had been processed.
         * - The server sends a HelloRetryRequest, triggering a retry.
         * - The second ClientHello is received.
         * - The extensions are parsed.
         * - The customer's ClientHello callback does NOT trigger this time. The callback only
         *   triggers after the first ClientHello.
         *   - Therefore, s2n_get_server_name is not called and the server name extension is not
         *     processed early or wiped.
         * - The first ClientHello is compared to the second ClientHello. The second ClientHello
         *   appears to contain a server name extension not present in the first ClientHello.
         * - The handshake fails because the ClientHellos must match.
         */
        {
            char server_name[] = "test server name";

            DEFER_CLEANUP(struct s2n_config *config_with_cb = s2n_config_new(),
                    s2n_config_ptr_free);
            EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config_with_cb, chain_and_key));
            EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config_with_cb, "default_tls13"));
            EXPECT_SUCCESS(s2n_config_disable_x509_verification(config_with_cb));

            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config_with_cb));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config_with_cb));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Setup server name and client hello callback */
            EXPECT_SUCCESS(s2n_set_server_name(client_conn, server_name));
            EXPECT_SUCCESS(s2n_config_set_client_hello_cb(config_with_cb,
                    s2n_client_hello_cb_with_get_server_name, server_name));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Handshake should complete as expected */
            EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
            EXPECT_EQUAL(strcmp(s2n_get_server_name(server_conn), server_name), 0);
            EXPECT_TRUE(IS_HELLO_RETRY_HANDSHAKE(client_conn));
            EXPECT_TRUE(IS_HELLO_RETRY_HANDSHAKE(server_conn));
        };
    }

    /**
     * Ensure all hello retry extensions sent by the server will have first
     * been sent by the client.
     *
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
     *= type=test
     *# As with the ServerHello, a HelloRetryRequest MUST NOT contain any
     *# extensions that were not first offered by the client in its
     *# ClientHello, with the exception of optionally the "cookie" (see
     *# Section 4.2.2) extension.
     **/
    {
        s2n_extension_type_list *hello_retry_extension_types = 0;
        POSIX_GUARD(s2n_extension_type_list_get(S2N_EXTENSION_LIST_HELLO_RETRY_REQUEST, &hello_retry_extension_types));

        for (int i = 0; i < hello_retry_extension_types->count; ++i) {
            const s2n_extension_type *const extension_type = hello_retry_extension_types->extension_types[i];

            /* with the exception of optionally the "cookie" extension. */
            if (extension_type->iana_value == TLS_EXTENSION_COOKIE) {
                continue;
            }

            EXPECT_TRUE(extension_type->is_response);
        }
    };

    /**
     * Ensure each of the following are checked: legacy_version,
     * legacy_session_id_echo, cipher_suite, and
     * legacy_compression_method
     *
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
     *= type=test
     *# Upon receipt of a HelloRetryRequest, the client MUST check the
     *# legacy_version, legacy_session_id_echo, cipher_suite, and
     *# legacy_compression_method as specified in Section 4.1.3 and then
     *# process the extensions, starting with determining the version using
     *# "supported_versions".
     **/
    {
        DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL,
                s2n_cert_chain_and_key_ptr_free);
        EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
                S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY));

        DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(),
                s2n_config_ptr_free);
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13"));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(config));

        /* The client MUST check the legacy_version */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
            EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                    s2n_stuffer_data_available(&client_conn->handshake.io)));

            /* Server receives ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
            EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

            /* Force the server to send an erroneous legacy protocol version in the HelloRetryRequest message */
            server_conn->actual_protocol_version = S2N_TLS11;

            /* Server sends HelloRetryRequest */
            EXPECT_SUCCESS(s2n_server_hello_retry_send(server_conn));

            EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
            EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                    s2n_stuffer_data_available(&server_conn->handshake.io)));
            client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;

            /* Client receives HelloRetryRequest */
            EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_recv(client_conn),
                    S2N_ERR_INVALID_HELLO_RETRY);
        };

        /* The client MUST check the legacy_session_id_echo */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
            EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                    s2n_stuffer_data_available(&client_conn->handshake.io)));

            /* Server receives ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
            EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

            /* Set a session id that's different from the client hello */
            POSIX_CHECKED_MEMSET(&server_conn->session_id, 0, S2N_TLS_SESSION_ID_MAX_LEN);

            /* Server sends HelloRetryRequest */
            EXPECT_SUCCESS(s2n_server_hello_retry_send(server_conn));

            EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
            EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                    s2n_stuffer_data_available(&server_conn->handshake.io)));
            client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;

            /* Client receives HelloRetryRequest */
            EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_recv(client_conn),
                    S2N_ERR_BAD_MESSAGE);
        };

        /**
         * The client MUST check the cipher_suite
         *
         *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
         *= type=test
         *# A client which receives a cipher suite that was not offered MUST
         *# abort the handshake.
         **/
        {
            EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20200207"));

            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* Send ClientHello */
            s2n_blocked_status blocked = 0;
            EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

            /* Receive ClientHello */
            EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));

            /*
             * Pick a cipher that wasn't offered in the CH, and should cause the
             * handshake to abort.
             */
            server_conn->secure->cipher_suite = &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384;

            /* Finish handshake */
            EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                    S2N_ERR_CIPHER_NOT_SUPPORTED);
        };

        /* The client MUST check the legacy_compression_method */
        {
            DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(server_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

            DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                    s2n_connection_ptr_free);
            EXPECT_NOT_NULL(client_conn);
            EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

            DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
            EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
            EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

            /* Force the HRR path */
            client_conn->security_policy_override = &security_policy_test_tls13_retry;

            /* ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
            EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                    s2n_stuffer_data_available(&client_conn->handshake.io)));

            /* Server receives ClientHello 1 */
            EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
            EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

            /* Server sends HelloRetryRequest */
            POSIX_CHECKED_MEMCPY(server_conn->handshake_params.server_random, hello_retry_req_random, S2N_TLS_RANDOM_DATA_LEN);
            EXPECT_SUCCESS(s2n_server_hello_write_message(server_conn));

            /* Overwrite compression method to 1 */
            struct s2n_stuffer *io = &server_conn->handshake.io;
            io->write_cursor -= 1;
            EXPECT_SUCCESS(s2n_stuffer_write_uint8(io, 1));

            /* Write the extensions */
            EXPECT_SUCCESS(s2n_server_extensions_send(server_conn, &server_conn->handshake.io));

            EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
            EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                    s2n_stuffer_data_available(&server_conn->handshake.io)));
            client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;

            /* Client receives HelloRetryRequest */
            EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_recv(client_conn),
                    S2N_ERR_BAD_MESSAGE);
        };
    };

    /**
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
     *= type=test
     *# The server's extensions MUST contain "supported_versions".
     **/
    {
        DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL,
                s2n_cert_chain_and_key_ptr_free);
        EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
                S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY));

        DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(),
                s2n_config_ptr_free);
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13"));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(config));

        DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                s2n_connection_ptr_free);
        EXPECT_NOT_NULL(server_conn);
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

        DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                s2n_connection_ptr_free);
        EXPECT_NOT_NULL(client_conn);
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

        DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
        EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
        EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry;

        /* ClientHello 1 */
        EXPECT_SUCCESS(s2n_client_hello_send(client_conn));

        EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                s2n_stuffer_data_available(&client_conn->handshake.io)));

        /* Server receives ClientHello 1 */
        EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
        EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

        POSIX_CHECKED_MEMCPY(server_conn->handshake_params.server_random, hello_retry_req_random, S2N_TLS_RANDOM_DATA_LEN);
        POSIX_GUARD(s2n_server_hello_write_message(server_conn));
        struct s2n_stuffer_reservation total_extensions_size = { 0 };
        POSIX_GUARD(s2n_stuffer_reserve_uint16(&server_conn->handshake.io, &total_extensions_size));

        /* Only send key share extension - exclude supported_versions */
        s2n_extension_send(&s2n_server_key_share_extension, server_conn, &server_conn->handshake.io);

        POSIX_GUARD(s2n_stuffer_write_vector_size(&total_extensions_size));

        EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
        EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                s2n_stuffer_data_available(&server_conn->handshake.io)));
        client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;

        /* Client receives HelloRetryRequest */
        EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_recv(client_conn),
                S2N_ERR_MISSING_EXTENSION);
    };

    /**
     *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
     *= type=test
     *# Servers MUST ensure that they negotiate the
     *# same cipher suite when receiving a conformant updated ClientHello (if
     *# the server selects the cipher suite as the first step in the
     *# negotiation, then this will happen automatically).
     **/
    {
        /* Create a custom security policy so it can be changed mid-handshake */
        struct s2n_cipher_suite *test_cipher_suites[] = {
            &s2n_tls13_aes_128_gcm_sha256,
            &s2n_tls13_aes_256_gcm_sha384
        };
        struct s2n_cipher_preferences test_cipher_preferences = {
            .count = s2n_array_len(test_cipher_suites),
            .suites = test_cipher_suites,
        };
        struct s2n_security_policy security_policy_test_tls13_retry_temp = {
            .minimum_protocol_version = S2N_TLS10,
            .cipher_preferences = &test_cipher_preferences,
            .kem_preferences = &kem_preferences_null,
            .signature_preferences = &s2n_signature_preferences_20200207,
            .certificate_signature_preferences = &s2n_certificate_signature_preferences_20201110,
            .ecc_preferences = &ecc_preferences_for_retry,
        };

        DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL, s2n_cert_chain_and_key_ptr_free);
        EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
                S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY));

        DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13"));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(config));

        DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free);
        EXPECT_NOT_NULL(server_conn);
        EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

        DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free);
        EXPECT_NOT_NULL(client_conn);
        EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

        DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
        EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
        EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry_temp;

        /* Send ClientHello */
        s2n_blocked_status blocked = 0;
        EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

        /* Receive ClientHello */
        EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));

        /* Rearrange the cipher preference order so that a different cipher will be
          * picked by the server */
        server_conn->config->security_policy->cipher_preferences->suites[0] = &s2n_tls13_aes_256_gcm_sha384;

        EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                S2N_ERR_BAD_MESSAGE);
    };

    /**
      * Ensure that the client aborts the handshake if selected_version
      * differs in the received server hellos
      *
      *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
      *= type=test
      *# The value of selected_version in the HelloRetryRequest
      *# "supported_versions" extension MUST be retained in the ServerHello,
      *# and a client MUST abort the handshake with an "illegal_parameter"
      *# alert if the value changes.
      **/
    {
        DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL, s2n_cert_chain_and_key_ptr_free);
        EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
                S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY));

        DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13"));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(config));

        DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free);
        EXPECT_NOT_NULL(server_conn);
        EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

        DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free);
        EXPECT_NOT_NULL(client_conn);
        EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

        DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
        EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
        EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry;

        /* Send ClientHello */
        s2n_blocked_status blocked = 0;
        EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));

        /* Receive ClientHello */
        EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));

        /* Skip to before server sends ServerHello */
        EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
        EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));

        /* Change the server_protocol_version so the value found in the ServerHello
          * differs from the value found in the HelloRetryRequest */
        server_conn->server_protocol_version = S2N_TLS13 + 10;

        EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn),
                S2N_ERR_BAD_MESSAGE);
    };

    /**
     *= https://www.rfc-editor.org/rfc/rfc8446#4.2.8
     *= type=test
     *# Upon receipt of this extension in a HelloRetryRequest, the client
     *# MUST verify that (1) the selected_group field corresponds to a group
     *# which was provided in the "supported_groups" extension in the
     *# original ClientHello
     **/
    {
        /* Create a custom security policy without secp521r1 */
        const struct s2n_ecc_named_curve *const test_ecc_pref_list_for_retry[] = {
            &s2n_ecc_curve_secp256r1,
            &s2n_ecc_curve_secp384r1,
        };
        const struct s2n_ecc_preferences test_ecc_preferences_for_retry = {
            .count = s2n_array_len(test_ecc_pref_list_for_retry),
            .ecc_curves = test_ecc_pref_list_for_retry,
        };
        struct s2n_security_policy security_policy_test_tls13_retry_temp = {
            .minimum_protocol_version = S2N_TLS10,
            .cipher_preferences = &cipher_preferences_20190801,
            .kem_preferences = &kem_preferences_null,
            .signature_preferences = &s2n_signature_preferences_20200207,
            .certificate_signature_preferences = &s2n_certificate_signature_preferences_20201110,
            .ecc_preferences = &test_ecc_preferences_for_retry,
        };

        DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL,
                s2n_cert_chain_and_key_ptr_free);
        EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
                S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN,
                S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY));

        DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(),
                s2n_config_ptr_free);
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13"));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(config));

        DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                s2n_connection_ptr_free);
        EXPECT_NOT_NULL(server_conn);
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));

        DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                s2n_connection_ptr_free);
        EXPECT_NOT_NULL(client_conn);
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));

        DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
        EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
        EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry_temp;

        /* ClientHello 1 */
        EXPECT_SUCCESS(s2n_client_hello_send(client_conn));
        EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io,
                s2n_stuffer_data_available(&client_conn->handshake.io)));

        /* Server receives ClientHello 1 */
        EXPECT_SUCCESS(s2n_client_hello_recv(server_conn));
        EXPECT_SUCCESS(s2n_set_connection_hello_retry_flags(server_conn));

        /* Server sends HelloRetryRequest */
        EXPECT_SUCCESS(s2n_server_hello_retry_send(server_conn));

        EXPECT_SUCCESS(s2n_stuffer_wipe(&client_conn->handshake.io));
        EXPECT_SUCCESS(s2n_stuffer_copy(&server_conn->handshake.io, &client_conn->handshake.io,
                s2n_stuffer_data_available(&server_conn->handshake.io)));
        client_conn->handshake.message_number = HELLO_RETRY_MSG_NO;

        /* Set the curve to secp521r1, which was not provided in supported_groups */
        client_conn->kex_params.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp521r1;

        /* Client receives HelloRetryRequest */
        EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_recv(client_conn),
                S2N_ERR_INVALID_HELLO_RETRY);
    };

    /**
     *= https://www.rfc-editor.org/rfc/rfc8446#4.2.8
     *= type=test
     *# If using (EC)DHE key establishment and a HelloRetryRequest containing a
     *# "key_share" extension was received by the client, the client MUST
     *# verify that the selected NamedGroup in the ServerHello is the same as
     *# that in the HelloRetryRequest. If this check fails, the client MUST
     *# abort the handshake with an "illegal_parameter" alert.
     **/
    {
        DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL,
                s2n_cert_chain_and_key_ptr_free);
        EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
                S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN,
                S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY));

        DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(),
                s2n_config_ptr_free);
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
        EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13"));
        EXPECT_SUCCESS(s2n_config_disable_x509_verification(config));

        DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER),
                s2n_connection_ptr_free);
        EXPECT_NOT_NULL(server_conn);
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config));
        EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING));

        DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT),
                s2n_connection_ptr_free);
        EXPECT_NOT_NULL(client_conn);
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config));
        EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING));

        DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
        EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
        EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

        /* Force the HRR path */
        client_conn->security_policy_override = &security_policy_test_tls13_retry;

        /* Skip to before client receives ServerHello 2 */
        s2n_blocked_status blocked = 0;
        EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
        EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG));
        EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO));
        EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO));
        EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO));
        EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, SERVER_HELLO));
        EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, ENCRYPTED_EXTENSIONS));

        /* Set the negotiated curve to something other than what was sent in the HRR */
        client_conn->kex_params.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp521r1;

        /* Client receives ServerHello 2 */
        EXPECT_ERROR_WITH_ERRNO(s2n_negotiate_until_message(client_conn, &blocked, ENCRYPTED_EXTENSIONS),
                S2N_ERR_BAD_MESSAGE);
    };

    EXPECT_SUCCESS(s2n_disable_tls13_in_test());

    END_TEST();
}
