godot/thirdparty/mbedtls/library/ssl_tls13_server.c

/*
 *  TLS 1.3 server-side functions
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

#include "common.h"

#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)

#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
#include "mbedtls/oid.h"
#include "mbedtls/psa_util.h"

#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
#include "ssl_debug_helpers.h"


static const mbedtls_ssl_ciphersuite_t *ssl_tls13_validate_peer_ciphersuite(
    mbedtls_ssl_context *ssl,
    unsigned int cipher_suite)
{}

static void ssl_tls13_select_ciphersuite(
    mbedtls_ssl_context *ssl,
    const unsigned char *cipher_suites,
    const unsigned char *cipher_suites_end,
    int psk_ciphersuite_id,
    psa_algorithm_t psk_hash_alg,
    const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
{}

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* From RFC 8446:
 *
 *   enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;
 *   struct {
 *       PskKeyExchangeMode ke_modes<1..255>;
 *   } PskKeyExchangeModes;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl,
                                                  const unsigned char *buf,
                                                  const unsigned char *end)
{}

/*
 * Non-error return values of
 * ssl_tls13_offered_psks_check_identity_match_ticket() and
 * ssl_tls13_offered_psks_check_identity_match(). They are positive to
 * not collide with error codes that are negative. Zero
 * (SSL_TLS1_3_PSK_IDENTITY_MATCH) in case of success as it may be propagated
 * up by the callers of this function as a generic success condition.
 *
 * The return value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE means
 * that the pre-shared-key identity matches that of a ticket or an externally-
 * provisioned pre-shared-key. We have thus been able to retrieve the
 * attributes of the pre-shared-key but at least one of them does not meet
 * some criteria and the pre-shared-key cannot be used. For example, a ticket
 * is expired or its version is not TLS 1.3. Note eventually that the return
 * value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE does not have
 * anything to do with binder check. A binder check is done only when a
 * suitable pre-shared-key has been selected and only for that selected
 * pre-shared-key: if the binder check fails, we fail the handshake and we do
 * not try to find another pre-shared-key for which the binder check would
 * succeed as recommended by the specification.
 */
#define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH
#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE
#define SSL_TLS1_3_PSK_IDENTITY_MATCH

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl);

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_identity_match_ticket(
    mbedtls_ssl_context *ssl,
    const unsigned char *identity,
    size_t identity_len,
    uint32_t obfuscated_ticket_age,
    mbedtls_ssl_session *session)
{}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_identity_match(
    mbedtls_ssl_context *ssl,
    const unsigned char *identity,
    size_t identity_len,
    uint32_t obfuscated_ticket_age,
    int *psk_type,
    mbedtls_ssl_session *session)
{}

/*
 * Non-error return values of ssl_tls13_offered_psks_check_binder_match().
 * They are positive to not collide with error codes that are negative. Zero
 * (SSL_TLS1_3_BINDER_MATCH) in case of success as it may be propagated up
 * by the callers of this function as a generic success condition.
 */
#define SSL_TLS1_3_BINDER_DOES_NOT_MATCH
#define SSL_TLS1_3_BINDER_MATCH
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_binder_match(
    mbedtls_ssl_context *ssl,
    const unsigned char *binder, size_t binder_len,
    int psk_type, psa_algorithm_t psk_hash_alg)
{}

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst,
                                         const mbedtls_ssl_session *src)
{}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

struct psk_attributes {};
#define PSK_ATTRIBUTES_INIT

/* Parser for pre_shared_key extension in client hello
 *    struct {
 *        opaque identity<1..2^16-1>;
 *        uint32 obfuscated_ticket_age;
 *    } PskIdentity;
 *
 *    opaque PskBinderEntry<32..255>;
 *
 *    struct {
 *        PskIdentity identities<7..2^16-1>;
 *        PskBinderEntry binders<33..2^16-1>;
 *    } OfferedPsks;
 *
 *    struct {
 *        select (Handshake.msg_type) {
 *            case client_hello: OfferedPsks;
 *            ....
 *        };
 *    } PreSharedKeyExtension;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_pre_shared_key_ext(
    mbedtls_ssl_context *ssl,
    const unsigned char *pre_shared_key_ext,
    const unsigned char *pre_shared_key_ext_end,
    const unsigned char *ciphersuites,
    const unsigned char *ciphersuites_end,
    struct psk_attributes *psk)
{}

/*
 * struct {
 *   select ( Handshake.msg_type ) {
 *      ....
 *      case server_hello:
 *          uint16 selected_identity;
 *   }
 * } PreSharedKeyExtension;
 */
static int ssl_tls13_write_server_pre_shared_key_ext(mbedtls_ssl_context *ssl,
                                                     unsigned char *buf,
                                                     unsigned char *end,
                                                     size_t *olen)
{}

#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */

/* From RFC 8446:
 *   struct {
 *          ProtocolVersion versions<2..254>;
 *   } SupportedVersions;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl,
                                                  const unsigned char *buf,
                                                  const unsigned char *end)
{}

#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
/*
 *
 * From RFC 8446:
 *   enum {
 *       ... (0xFFFF)
 *   } NamedGroup;
 *   struct {
 *       NamedGroup named_group_list<2..2^16-1>;
 *   } NamedGroupList;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl,
                                                const unsigned char *buf,
                                                const unsigned char *end)
{}
#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */

#define SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
/*
 *  ssl_tls13_parse_key_shares_ext() verifies whether the information in the
 *  extension is correct and stores the first acceptable key share and its
 *  associated group.
 *
 *  Possible return values are:
 *  - 0: Successful processing of the client provided key share extension.
 *  - SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH: The key shares provided by
 *    the client does not match a group supported by the server. A
 *    HelloRetryRequest will be needed.
 *  - A negative value for fatal errors.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          const unsigned char *end)
{}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts(mbedtls_ssl_context *ssl,
                                           int exts_mask)
{}

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(
    mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_key_exchange(
    mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED */

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(
    mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED */

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_ephemeral_available(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
    defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)

#if defined(MBEDTLS_USE_PSA_CRYPTO)
static psa_algorithm_t ssl_tls13_iana_sig_alg_to_psa_alg(uint16_t sig_alg)
{
    switch (sig_alg) {
        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
            return PSA_ALG_ECDSA(PSA_ALG_SHA_256);
        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
            return PSA_ALG_ECDSA(PSA_ALG_SHA_384);
        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
            return PSA_ALG_ECDSA(PSA_ALG_SHA_512);
        case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
            return PSA_ALG_RSA_PSS(PSA_ALG_SHA_256);
        case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
            return PSA_ALG_RSA_PSS(PSA_ALG_SHA_384);
        case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
            return PSA_ALG_RSA_PSS(PSA_ALG_SHA_512);
        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
            return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256);
        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
            return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_384);
        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
            return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512);
        default:
            return PSA_ALG_NONE;
    }
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */

/*
 * Pick best ( private key, certificate chain ) pair based on the signature
 * algorithms supported by the client.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_pick_key_cert(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_X509_CRT_PARSE_C &&
          MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */

/*
 *
 * STATE HANDLING: ClientHello
 *
 * There are three possible classes of outcomes when parsing the ClientHello:
 *
 * 1) The ClientHello was well-formed and matched the server's configuration.
 *
 *    In this case, the server progresses to sending its ServerHello.
 *
 * 2) The ClientHello was well-formed but didn't match the server's
 *    configuration.
 *
 *    For example, the client might not have offered a key share which
 *    the server supports, or the server might require a cookie.
 *
 *    In this case, the server sends a HelloRetryRequest.
 *
 * 3) The ClientHello was ill-formed
 *
 *    In this case, we abort the handshake.
 *
 */

/*
 * Structure of this message:
 *
 * uint16 ProtocolVersion;
 * opaque Random[32];
 * uint8 CipherSuite[2];    // Cryptographic suite selector
 *
 * struct {
 *      ProtocolVersion legacy_version = 0x0303;    // TLS v1.2
 *      Random random;
 *      opaque legacy_session_id<0..32>;
 *      CipherSuite cipher_suites<2..2^16-2>;
 *      opaque legacy_compression_methods<1..2^8-1>;
 *      Extension extensions<8..2^16-1>;
 * } ClientHello;
 */

#define SSL_CLIENT_HELLO_OK
#define SSL_CLIENT_HELLO_HRR_REQUIRED
#define SSL_CLIENT_HELLO_TLS1_2

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
                                        const unsigned char *buf,
                                        const unsigned char *end)
{}

#if defined(MBEDTLS_SSL_EARLY_DATA)
static int ssl_tls13_check_early_data_requirements(mbedtls_ssl_context *ssl)
{
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;

    if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
        MBEDTLS_SSL_DEBUG_MSG(
            1,
            ("EarlyData: rejected, feature disabled in server configuration."));
        return -1;
    }

    if (!handshake->resume) {
        /* We currently support early data only in the case of PSKs established
           via a NewSessionTicket message thus in the case of a session
           resumption. */
        MBEDTLS_SSL_DEBUG_MSG(
            1, ("EarlyData: rejected, not a session resumption."));
        return -1;
    }

    /* RFC 8446 4.2.10
     *
     * In order to accept early data, the server MUST have accepted a PSK cipher
     * suite and selected the first key offered in the client's "pre_shared_key"
     * extension. In addition, it MUST verify that the following values are the
     * same as those associated with the selected PSK:
     * - The TLS version number
     * - The selected cipher suite
     * - The selected ALPN [RFC7301] protocol, if any
     *
     * NOTE:
     *  - The TLS version number is checked in
     *    ssl_tls13_offered_psks_check_identity_match_ticket().
     */

    if (handshake->selected_identity != 0) {
        MBEDTLS_SSL_DEBUG_MSG(
            1, ("EarlyData: rejected, the selected key in "
                "`pre_shared_key` is not the first one."));
        return -1;
    }

    if (handshake->ciphersuite_info->id !=
        ssl->session_negotiate->ciphersuite) {
        MBEDTLS_SSL_DEBUG_MSG(
            1, ("EarlyData: rejected, the selected ciphersuite is not the one "
                "of the selected pre-shared key."));
        return -1;

    }

    if (!mbedtls_ssl_tls13_session_ticket_allow_early_data(ssl->session_negotiate)) {
        MBEDTLS_SSL_DEBUG_MSG(
            1,
            ("EarlyData: rejected, early_data not allowed in ticket "
             "permission bits."));
        return -1;
    }

#if defined(MBEDTLS_SSL_ALPN)
    const char *alpn = mbedtls_ssl_get_alpn_protocol(ssl);
    size_t alpn_len;

    if (alpn == NULL && ssl->session_negotiate->ticket_alpn == NULL) {
        return 0;
    }

    if (alpn != NULL) {
        alpn_len = strlen(alpn);
    }

    if (alpn == NULL ||
        ssl->session_negotiate->ticket_alpn == NULL ||
        alpn_len != strlen(ssl->session_negotiate->ticket_alpn) ||
        (memcmp(alpn, ssl->session_negotiate->ticket_alpn, alpn_len) != 0)) {
        MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, the selected ALPN is different "
                                  "from the one associated with the pre-shared key."));
        return -1;
    }
#endif

    return 0;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */

/* Update the handshake state machine */

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
                                              int hrr_required)
{}

/*
 * Main entry point from the state machine; orchestrates the otherfunctions.
 */

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
{}

/*
 * Handler for MBEDTLS_SSL_SERVER_HELLO
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_prepare_server_hello(mbedtls_ssl_context *ssl)
{}

/*
 * ssl_tls13_write_server_hello_supported_versions_ext ():
 *
 * struct {
 *      ProtocolVersion selected_version;
 * } SupportedVersions;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_hello_supported_versions_ext(
    mbedtls_ssl_context *ssl,
    unsigned char *buf,
    unsigned char *end,
    size_t *out_len)
{}



/* Generate and export a single key share. For hybrid KEMs, this can
 * be called multiple times with the different components of the hybrid. */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_generate_and_write_key_share(mbedtls_ssl_context *ssl,
                                                  uint16_t named_group,
                                                  unsigned char *buf,
                                                  unsigned char *end,
                                                  size_t *out_len)
{}

/*
 * ssl_tls13_write_key_share_ext
 *
 * Structure of key_share extension in ServerHello:
 *
 * struct {
 *     NamedGroup group;
 *     opaque key_exchange<1..2^16-1>;
 * } KeyShareEntry;
 * struct {
 *     KeyShareEntry server_share;
 * } KeyShareServerHello;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl,
                                         unsigned char *buf,
                                         unsigned char *end,
                                         size_t *out_len)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_hrr_key_share_ext(mbedtls_ssl_context *ssl,
                                             unsigned char *buf,
                                             unsigned char *end,
                                             size_t *out_len)
{}

/*
 * Structure of ServerHello message:
 *
 *     struct {
 *        ProtocolVersion legacy_version = 0x0303;    // TLS v1.2
 *        Random random;
 *        opaque legacy_session_id_echo<0..32>;
 *        CipherSuite cipher_suite;
 *        uint8 legacy_compression_method = 0;
 *        Extension extensions<6..2^16-1>;
 *    } ServerHello;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_hello_body(mbedtls_ssl_context *ssl,
                                             unsigned char *buf,
                                             unsigned char *end,
                                             size_t *out_len,
                                             int is_hrr)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_finalize_server_hello(mbedtls_ssl_context *ssl)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl)
{}


/*
 * Handler for MBEDTLS_SSL_HELLO_RETRY_REQUEST
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_prepare_hello_retry_request(mbedtls_ssl_context *ssl)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_hello_retry_request(mbedtls_ssl_context *ssl)
{}

/*
 * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
 */

/*
 * struct {
 *    Extension extensions<0..2 ^ 16 - 1>;
 * } EncryptedExtensions;
 *
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
                                                     unsigned char *buf,
                                                     unsigned char *end,
                                                     size_t *out_len)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
#define SSL_CERTIFICATE_REQUEST_SEND_REQUEST
#define SSL_CERTIFICATE_REQUEST_SKIP
/* Coordination:
 * Check whether a CertificateRequest message should be written.
 * Returns a negative code on failure, or
 * - SSL_CERTIFICATE_REQUEST_SEND_REQUEST
 * - SSL_CERTIFICATE_REQUEST_SKIP
 * indicating if the writing of the CertificateRequest
 * should be skipped or not.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_certificate_request_coordinate(mbedtls_ssl_context *ssl)
{}

/*
 * struct {
 *   opaque certificate_request_context<0..2^8-1>;
 *   Extension extensions<2..2^16-1>;
 * } CertificateRequest;
 *
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_certificate_request_body(mbedtls_ssl_context *ssl,
                                                    unsigned char *buf,
                                                    const unsigned char *end,
                                                    size_t *out_len)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_certificate_request(mbedtls_ssl_context *ssl)
{}

/*
 * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_certificate(mbedtls_ssl_context *ssl)
{}

/*
 * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */

/*
 * RFC 8446 section A.2
 *
 *                                | Send ServerHello
 *                                | K_send = handshake
 *                                | Send EncryptedExtensions
 *                                | [Send CertificateRequest]
 * Can send                       | [Send Certificate + CertificateVerify]
 * app data                       | Send Finished
 * after   -->                    | K_send = application
 * here                  +--------+--------+
 *              No 0-RTT |                 | 0-RTT
 *                       |                 |
 *   K_recv = handshake  |                 | K_recv = early data
 * [Skip decrypt errors] |    +------> WAIT_EOED -+
 *                       |    |       Recv |      | Recv EndOfEarlyData
 *                       |    | early data |      | K_recv = handshake
 *                       |    +------------+      |
 *                       |                        |
 *                       +> WAIT_FLIGHT2 <--------+
 *                                |
 *                       +--------+--------+
 *               No auth |                 | Client auth
 *                       |                 |
 *                       |                 v
 *                       |             WAIT_CERT
 *                       |        Recv |       | Recv Certificate
 *                       |       empty |       v
 *                       | Certificate |    WAIT_CV
 *                       |             |       | Recv
 *                       |             v       | CertificateVerify
 *                       +-> WAIT_FINISHED <---+
 *                                | Recv Finished
 *
 *
 * The following function handles the state changes after WAIT_FLIGHT2 in the
 * above diagram. We are not going to receive early data related messages
 * anymore, prepare to receive the first handshake message of the client
 * second flight.
 */
static void ssl_tls13_prepare_for_handshake_second_flight(
    mbedtls_ssl_context *ssl)
{}

/*
 * Handler for MBEDTLS_SSL_SERVER_FINISHED
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_EARLY_DATA)
/*
 * Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
 */
#define SSL_GOT_END_OF_EARLY_DATA
#define SSL_GOT_EARLY_DATA
/* Coordination:
 * Deals with the ambiguity of not knowing if the next message is an
 * EndOfEarlyData message or an application message containing early data.
 * Returns a negative code on failure, or
 * - SSL_GOT_END_OF_EARLY_DATA
 * - SSL_GOT_EARLY_DATA
 * indicating which message is received.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
        return ret;
    }
    ssl->keep_current_message = 1;

    if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE        &&
        ssl->in_msg[0]  == MBEDTLS_SSL_HS_END_OF_EARLY_DATA) {
        MBEDTLS_SSL_DEBUG_MSG(3, ("Received an end_of_early_data message."));
        return SSL_GOT_END_OF_EARLY_DATA;
    }

    if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
        if (ssl->in_offt == NULL) {
            MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
            /* Set the reading pointer */
            ssl->in_offt = ssl->in_msg;
            ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen);
            if (ret != 0) {
                return ret;
            }
        }
        return SSL_GOT_EARLY_DATA;
    }

    MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
                                 MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
    return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl,
                                             const unsigned char *buf,
                                             const unsigned char *end)
{
    /* RFC 8446 section 4.5
     *
     * struct {} EndOfEarlyData;
     */
    if (buf != end) {
        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
                                     MBEDTLS_ERR_SSL_DECODE_ERROR);
        return MBEDTLS_ERR_SSL_DECODE_ERROR;
    }
    return 0;
}

/*
 * RFC 8446 section A.2
 *
 *                                | Send ServerHello
 *                                | K_send = handshake
 *                                | Send EncryptedExtensions
 *                                | [Send CertificateRequest]
 * Can send                       | [Send Certificate + CertificateVerify]
 * app data                       | Send Finished
 * after   -->                    | K_send = application
 * here                  +--------+--------+
 *              No 0-RTT |                 | 0-RTT
 *                       |                 |
 *   K_recv = handshake  |                 | K_recv = early data
 * [Skip decrypt errors] |    +------> WAIT_EOED -+
 *                       |    |       Recv |      | Recv EndOfEarlyData
 *                       |    | early data |      | K_recv = handshake
 *                       |    +------------+      |
 *                       |                        |
 *                       +> WAIT_FLIGHT2 <--------+
 *                                |
 *                       +--------+--------+
 *               No auth |                 | Client auth
 *                       |                 |
 *                       |                 v
 *                       |             WAIT_CERT
 *                       |        Recv |       | Recv Certificate
 *                       |       empty |       v
 *                       | Certificate |    WAIT_CV
 *                       |             |       | Recv
 *                       |             v       | CertificateVerify
 *                       +-> WAIT_FINISHED <---+
 *                                | Recv Finished
 *
 * The function handles actions and state changes from 0-RTT to WAIT_FLIGHT2 in
 * the above diagram.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_process_end_of_early_data"));

    MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_end_of_early_data_coordinate(ssl));

    if (ret == SSL_GOT_END_OF_EARLY_DATA) {
        unsigned char *buf;
        size_t buf_len;

        MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
                                 ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA,
                                 &buf, &buf_len));

        MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data(
                                 ssl, buf, buf + buf_len));

        MBEDTLS_SSL_DEBUG_MSG(
            1, ("Switch to handshake keys for inbound traffic"
                "( K_recv = handshake )"));
        mbedtls_ssl_set_inbound_transform(
            ssl, ssl->handshake->transform_handshake);

        MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
                                 ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA,
                                 buf, buf_len));

        ssl_tls13_prepare_for_handshake_second_flight(ssl);

    } else if (ret == SSL_GOT_EARLY_DATA) {
        ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA;
        goto cleanup;
    } else {
        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
        goto cleanup;
    }

cleanup:
    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_process_end_of_early_data"));
    return ret;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */

/*
 * Handler for MBEDTLS_SSL_CLIENT_FINISHED
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_client_finished(mbedtls_ssl_context *ssl)
{}

/*
 * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
/*
 * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
 */
#define SSL_NEW_SESSION_TICKET_SKIP
#define SSL_NEW_SESSION_TICKET_WRITE
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_new_session_ticket_coordinate(mbedtls_ssl_context *ssl)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
                                                unsigned char *ticket_nonce,
                                                size_t ticket_nonce_size)
{}

/* This function creates a NewSessionTicket message in the following format:
 *
 * struct {
 *    uint32 ticket_lifetime;
 *    uint32 ticket_age_add;
 *    opaque ticket_nonce<0..255>;
 *    opaque ticket<1..2^16-1>;
 *    Extension extensions<0..2^16-2>;
 * } NewSessionTicket;
 *
 * The ticket inside the NewSessionTicket message is an encrypted container
 * carrying the necessary information so that the server is later able to
 * re-start the communication.
 *
 * The following fields are placed inside the ticket by the
 * f_ticket_write() function:
 *
 *  - creation time (ticket_creation_time)
 *  - flags (ticket_flags)
 *  - age add (ticket_age_add)
 *  - key (resumption_key)
 *  - key length (resumption_key_len)
 *  - ciphersuite (ciphersuite)
 *  - max_early_data_size (max_early_data_size)
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
                                                   unsigned char *buf,
                                                   unsigned char *end,
                                                   size_t *out_len,
                                                   unsigned char *ticket_nonce,
                                                   size_t ticket_nonce_size)
{}

/*
 * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
 */
static int ssl_tls13_write_new_session_ticket(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

/*
 * TLS 1.3 State Machine -- server side
 */
int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl)
{}

#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_3 */