godot/thirdparty/mbedtls/library/ssl_tls.c

/*
 *  TLS shared functions
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */
/*
 *  http://www.ietf.org/rfc/rfc2246.txt
 *  http://www.ietf.org/rfc/rfc4346.txt
 */

#include "common.h"

#if defined(MBEDTLS_SSL_TLS_C)

#include "mbedtls/platform.h"

#include "mbedtls/ssl.h"
#include "ssl_client.h"
#include "ssl_debug_helpers.h"
#include "ssl_misc.h"

#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/version.h"
#include "mbedtls/constant_time.h"

#include <string.h>

#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "mbedtls/psa_util.h"
#include "md_psa.h"
#include "psa_util_internal.h"
#include "psa/crypto.h"
#endif

#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/oid.h"
#endif

#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Define local translating functions to save code size by not using too many
 * arguments in each translating place. */
static int local_err_translation(psa_status_t status)
{
    return psa_status_to_mbedtls(status, psa_to_ssl_errors,
                                 ARRAY_LENGTH(psa_to_ssl_errors),
                                 psa_generic_status_to_mbedtls);
}
#define PSA_TO_MBEDTLS_ERR
#endif

#if defined(MBEDTLS_TEST_HOOKS)
static mbedtls_ssl_chk_buf_ptr_args chk_buf_ptr_fail_args;

void mbedtls_ssl_set_chk_buf_ptr_fail_args(
    const uint8_t *cur, const uint8_t *end, size_t need)
{
    chk_buf_ptr_fail_args.cur = cur;
    chk_buf_ptr_fail_args.end = end;
    chk_buf_ptr_fail_args.need = need;
}

void mbedtls_ssl_reset_chk_buf_ptr_fail_args(void)
{
    memset(&chk_buf_ptr_fail_args, 0, sizeof(chk_buf_ptr_fail_args));
}

int mbedtls_ssl_cmp_chk_buf_ptr_fail_args(mbedtls_ssl_chk_buf_ptr_args *args)
{
    return (chk_buf_ptr_fail_args.cur  != args->cur) ||
           (chk_buf_ptr_fail_args.end  != args->end) ||
           (chk_buf_ptr_fail_args.need != args->need);
}
#endif /* MBEDTLS_TEST_HOOKS */

#if defined(MBEDTLS_SSL_PROTO_DTLS)

#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
/* Top-level Connection ID API */

int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf,
                         size_t len,
                         int ignore_other_cid)
{}

int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl,
                        int enable,
                        unsigned char const *own_cid,
                        size_t own_cid_len)
{}

int mbedtls_ssl_get_own_cid(mbedtls_ssl_context *ssl,
                            int *enabled,
                            unsigned char own_cid[MBEDTLS_SSL_CID_IN_LEN_MAX],
                            size_t *own_cid_len)
{}

int mbedtls_ssl_get_peer_cid(mbedtls_ssl_context *ssl,
                             int *enabled,
                             unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX],
                             size_t *peer_cid_len)
{}
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */

#endif /* MBEDTLS_SSL_PROTO_DTLS */

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/*
 * Convert max_fragment_length codes to length.
 * RFC 6066 says:
 *    enum{
 *        2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
 *    } MaxFragmentLength;
 * and we add 0 -> extension unused
 */
static unsigned int ssl_mfl_code_to_length(int mfl)
{}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */

int mbedtls_ssl_session_copy(mbedtls_ssl_session *dst,
                             const mbedtls_ssl_session *src)
{}

#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
MBEDTLS_CHECK_RETURN_CRITICAL
static int resize_buffer(unsigned char **buffer, size_t len_new, size_t *len_old)
{
    unsigned char *resized_buffer = mbedtls_calloc(1, len_new);
    if (resized_buffer == NULL) {
        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
    }

    /* We want to copy len_new bytes when downsizing the buffer, and
     * len_old bytes when upsizing, so we choose the smaller of two sizes,
     * to fit one buffer into another. Size checks, ensuring that no data is
     * lost, are done outside of this function. */
    memcpy(resized_buffer, *buffer,
           (len_new < *len_old) ? len_new : *len_old);
    mbedtls_zeroize_and_free(*buffer, *len_old);

    *buffer = resized_buffer;
    *len_old = len_new;

    return 0;
}

static void handle_buffer_resizing(mbedtls_ssl_context *ssl, int downsizing,
                                   size_t in_buf_new_len,
                                   size_t out_buf_new_len)
{
    int modified = 0;
    size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
    size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
    if (ssl->in_buf != NULL) {
        written_in = ssl->in_msg - ssl->in_buf;
        iv_offset_in = ssl->in_iv - ssl->in_buf;
        len_offset_in = ssl->in_len - ssl->in_buf;
        if (downsizing ?
            ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
            ssl->in_buf_len < in_buf_new_len) {
            if (resize_buffer(&ssl->in_buf, in_buf_new_len, &ssl->in_buf_len) != 0) {
                MBEDTLS_SSL_DEBUG_MSG(1, ("input buffer resizing failed - out of memory"));
            } else {
                MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating in_buf to %" MBEDTLS_PRINTF_SIZET,
                                          in_buf_new_len));
                modified = 1;
            }
        }
    }

    if (ssl->out_buf != NULL) {
        written_out = ssl->out_msg - ssl->out_buf;
        iv_offset_out = ssl->out_iv - ssl->out_buf;
        len_offset_out = ssl->out_len - ssl->out_buf;
        if (downsizing ?
            ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len :
            ssl->out_buf_len < out_buf_new_len) {
            if (resize_buffer(&ssl->out_buf, out_buf_new_len, &ssl->out_buf_len) != 0) {
                MBEDTLS_SSL_DEBUG_MSG(1, ("output buffer resizing failed - out of memory"));
            } else {
                MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating out_buf to %" MBEDTLS_PRINTF_SIZET,
                                          out_buf_new_len));
                modified = 1;
            }
        }
    }
    if (modified) {
        /* Update pointers here to avoid doing it twice. */
        mbedtls_ssl_reset_in_out_pointers(ssl);
        /* Fields below might not be properly updated with record
         * splitting or with CID, so they are manually updated here. */
        ssl->out_msg = ssl->out_buf + written_out;
        ssl->out_len = ssl->out_buf + len_offset_out;
        ssl->out_iv = ssl->out_buf + iv_offset_out;

        ssl->in_msg = ssl->in_buf + written_in;
        ssl->in_len = ssl->in_buf + len_offset_in;
        ssl->in_iv = ssl->in_buf + iv_offset_in;
    }
}
#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */

#if defined(MBEDTLS_SSL_PROTO_TLS1_2)

#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
tls_prf_fn;

static tls_prf_fn ssl_tls12prf_from_cs(int ciphersuite_id);

#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */

/* Type for the TLS PRF */
ssl_tls_prf_t;

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform,
                                        int ciphersuite,
                                        const unsigned char master[48],
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
                                        int encrypt_then_mac,
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
                                        ssl_tls_prf_t tls_prf,
                                        const unsigned char randbytes[64],
                                        mbedtls_ssl_protocol_version tls_version,
                                        unsigned endpoint,
                                        const mbedtls_ssl_context *ssl);

#if defined(MBEDTLS_MD_CAN_SHA256)
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_sha256(const unsigned char *secret, size_t slen,
                          const char *label,
                          const unsigned char *random, size_t rlen,
                          unsigned char *dstbuf, size_t dlen);
static int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *);
static int ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);

#endif /* MBEDTLS_MD_CAN_SHA256*/

#if defined(MBEDTLS_MD_CAN_SHA384)
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_sha384(const unsigned char *secret, size_t slen,
                          const char *label,
                          const unsigned char *random, size_t rlen,
                          unsigned char *dstbuf, size_t dlen);

static int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *);
static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
#endif /* MBEDTLS_MD_CAN_SHA384*/

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls12_session_load(mbedtls_ssl_session *session,
                                  const unsigned char *buf,
                                  size_t len);
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */

static int ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t);

#if defined(MBEDTLS_MD_CAN_SHA256)
static int ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t);
#endif /* MBEDTLS_MD_CAN_SHA256*/

#if defined(MBEDTLS_MD_CAN_SHA384)
static int ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t);
#endif /* MBEDTLS_MD_CAN_SHA384*/

int  mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf,
                         const unsigned char *secret, size_t slen,
                         const char *label,
                         const unsigned char *random, size_t rlen,
                         unsigned char *dstbuf, size_t dlen)
{}

#if defined(MBEDTLS_X509_CRT_PARSE_C)
static void ssl_clear_peer_cert(mbedtls_ssl_session *session)
{}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

uint32_t mbedtls_ssl_get_extension_id(unsigned int extension_type)
{}

uint32_t mbedtls_ssl_get_extension_mask(unsigned int extension_type)
{}

#if defined(MBEDTLS_DEBUG_C)
static const char *extension_name_table[] =;

static const unsigned int extension_type_table[] =;

const char *mbedtls_ssl_get_extension_name(unsigned int extension_type)
{}

static const char *ssl_tls13_get_hs_msg_name(int hs_msg_type)
{}

void mbedtls_ssl_print_extension(const mbedtls_ssl_context *ssl,
                                 int level, const char *file, int line,
                                 int hs_msg_type, unsigned int extension_type,
                                 const char *extra_msg0, const char *extra_msg1)
{}

void mbedtls_ssl_print_extensions(const mbedtls_ssl_context *ssl,
                                  int level, const char *file, int line,
                                  int hs_msg_type, uint32_t extensions_mask,
                                  const char *extra)
{}

#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
static const char *ticket_flag_name_table[] =;

void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
                                    int level, const char *file, int line,
                                    unsigned int flags)
{}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */

#endif /* MBEDTLS_DEBUG_C */

void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl,
                                   const mbedtls_ssl_ciphersuite_t *ciphersuite_info)
{}

int mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl,
                                       unsigned hs_type,
                                       size_t total_hs_len)
{}

int mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl,
                                       unsigned hs_type,
                                       unsigned char const *msg,
                                       size_t msg_len)
{}

int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl)
{}

static int ssl_update_checksum_start(mbedtls_ssl_context *ssl,
                                     const unsigned char *buf, size_t len)
{}

#if defined(MBEDTLS_MD_CAN_SHA256)
static int ssl_update_checksum_sha256(mbedtls_ssl_context *ssl,
                                      const unsigned char *buf, size_t len)
{}
#endif

#if defined(MBEDTLS_MD_CAN_SHA384)
static int ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
                                      const unsigned char *buf, size_t len)
{}
#endif

static void ssl_handshake_params_init(mbedtls_ssl_handshake_params *handshake)
{}

void mbedtls_ssl_transform_init(mbedtls_ssl_transform *transform)
{}

void mbedtls_ssl_session_init(mbedtls_ssl_session *session)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_handshake_init(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
/* Dummy cookie callbacks for defaults */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_cookie_write_dummy(void *ctx,
                                  unsigned char **p, unsigned char *end,
                                  const unsigned char *cli_id, size_t cli_id_len)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_cookie_check_dummy(void *ctx,
                                  const unsigned char *cookie, size_t cookie_len,
                                  const unsigned char *cli_id, size_t cli_id_len)
{}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */

/*
 * Initialize an SSL context
 */
void mbedtls_ssl_init(mbedtls_ssl_context *ssl)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_conf_version_check(const mbedtls_ssl_context *ssl)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_conf_check(const mbedtls_ssl_context *ssl)
{}

/*
 * Setup an SSL context
 */

int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
                      const mbedtls_ssl_config *conf)
{}

/*
 * Reset an initialized and used SSL context for re-use while retaining
 * all application-set variables, function pointers and data.
 *
 * If partial is non-zero, keep data in the input buffer and client ID.
 * (Use when a DTLS client reconnects from the same port.)
 */
void mbedtls_ssl_session_reset_msg_layer(mbedtls_ssl_context *ssl,
                                         int partial)
{}

int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial)
{}

/*
 * Reset an initialized and used SSL context for re-use while retaining
 * all application-set variables, function pointers and data.
 */
int mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl)
{}

/*
 * SSL set accessors
 */
void mbedtls_ssl_conf_endpoint(mbedtls_ssl_config *conf, int endpoint)
{}

void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport)
{}

#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
void mbedtls_ssl_conf_dtls_anti_replay(mbedtls_ssl_config *conf, char mode)
{}
#endif

void mbedtls_ssl_conf_dtls_badmac_limit(mbedtls_ssl_config *conf, unsigned limit)
{}

#if defined(MBEDTLS_SSL_PROTO_DTLS)

void mbedtls_ssl_set_datagram_packing(mbedtls_ssl_context *ssl,
                                      unsigned allow_packing)
{}

void mbedtls_ssl_conf_handshake_timeout(mbedtls_ssl_config *conf,
                                        uint32_t min, uint32_t max)
{}
#endif

void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode)
{}

#if defined(MBEDTLS_X509_CRT_PARSE_C)
void mbedtls_ssl_conf_verify(mbedtls_ssl_config *conf,
                             int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
                             void *p_vrfy)
{}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf,
                          int (*f_rng)(void *, unsigned char *, size_t),
                          void *p_rng)
{}

void mbedtls_ssl_conf_dbg(mbedtls_ssl_config *conf,
                          void (*f_dbg)(void *, int, const char *, int, const char *),
                          void  *p_dbg)
{}

void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl,
                         void *p_bio,
                         mbedtls_ssl_send_t *f_send,
                         mbedtls_ssl_recv_t *f_recv,
                         mbedtls_ssl_recv_timeout_t *f_recv_timeout)
{}

#if defined(MBEDTLS_SSL_PROTO_DTLS)
void mbedtls_ssl_set_mtu(mbedtls_ssl_context *ssl, uint16_t mtu)
{}
#endif

void mbedtls_ssl_conf_read_timeout(mbedtls_ssl_config *conf, uint32_t timeout)
{}

void mbedtls_ssl_set_timer_cb(mbedtls_ssl_context *ssl,
                              void *p_timer,
                              mbedtls_ssl_set_timer_t *f_set_timer,
                              mbedtls_ssl_get_timer_t *f_get_timer)
{}

#if defined(MBEDTLS_SSL_SRV_C)
void mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf,
                                    void *p_cache,
                                    mbedtls_ssl_cache_get_t *f_get_cache,
                                    mbedtls_ssl_cache_set_t *f_set_cache)
{}
#endif /* MBEDTLS_SSL_SRV_C */

#if defined(MBEDTLS_SSL_CLI_C)
int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session)
{}
#endif /* MBEDTLS_SSL_CLI_C */

void mbedtls_ssl_conf_ciphersuites(mbedtls_ssl_config *conf,
                                   const int *ciphersuites)
{}

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
void mbedtls_ssl_conf_tls13_key_exchange_modes(mbedtls_ssl_config *conf,
                                               const int kex_modes)
{}

#if defined(MBEDTLS_SSL_EARLY_DATA)
void mbedtls_ssl_conf_early_data(mbedtls_ssl_config *conf,
                                 int early_data_enabled)
{
    conf->early_data_enabled = early_data_enabled;
}

#if defined(MBEDTLS_SSL_SRV_C)
void mbedtls_ssl_conf_max_early_data_size(
    mbedtls_ssl_config *conf, uint32_t max_early_data_size)
{
    conf->max_early_data_size = max_early_data_size;
}
#endif /* MBEDTLS_SSL_SRV_C */

#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

#if defined(MBEDTLS_X509_CRT_PARSE_C)
void mbedtls_ssl_conf_cert_profile(mbedtls_ssl_config *conf,
                                   const mbedtls_x509_crt_profile *profile)
{}

static void ssl_key_cert_free(mbedtls_ssl_key_cert *key_cert)
{}

/* Append a new keycert entry to a (possibly empty) list */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_append_key_cert(mbedtls_ssl_key_cert **head,
                               mbedtls_x509_crt *cert,
                               mbedtls_pk_context *key)
{}

int mbedtls_ssl_conf_own_cert(mbedtls_ssl_config *conf,
                              mbedtls_x509_crt *own_cert,
                              mbedtls_pk_context *pk_key)
{}

void mbedtls_ssl_conf_ca_chain(mbedtls_ssl_config *conf,
                               mbedtls_x509_crt *ca_chain,
                               mbedtls_x509_crl *ca_crl)
{}

#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
void mbedtls_ssl_conf_ca_cb(mbedtls_ssl_config *conf,
                            mbedtls_x509_crt_ca_cb_t f_ca_cb,
                            void *p_ca_cb)
{
    conf->f_ca_cb = f_ca_cb;
    conf->p_ca_cb = p_ca_cb;

    /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
     * cannot be used together. */
    conf->ca_chain   = NULL;
    conf->ca_crl     = NULL;
}
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#endif /* MBEDTLS_X509_CRT_PARSE_C */

#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
const unsigned char *mbedtls_ssl_get_hs_sni(mbedtls_ssl_context *ssl,
                                            size_t *name_len)
{}

int mbedtls_ssl_set_hs_own_cert(mbedtls_ssl_context *ssl,
                                mbedtls_x509_crt *own_cert,
                                mbedtls_pk_context *pk_key)
{}

void mbedtls_ssl_set_hs_ca_chain(mbedtls_ssl_context *ssl,
                                 mbedtls_x509_crt *ca_chain,
                                 mbedtls_x509_crl *ca_crl)
{}

#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
void mbedtls_ssl_set_hs_dn_hints(mbedtls_ssl_context *ssl,
                                 const mbedtls_x509_crt *crt)
{}
#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */

void mbedtls_ssl_set_hs_authmode(mbedtls_ssl_context *ssl,
                                 int authmode)
{}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */

#if defined(MBEDTLS_X509_CRT_PARSE_C)
void mbedtls_ssl_set_verify(mbedtls_ssl_context *ssl,
                            int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
                            void *p_vrfy)
{}
#endif

#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)

#if defined(MBEDTLS_USE_PSA_CRYPTO)
static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };

static psa_status_t mbedtls_ssl_set_hs_ecjpake_password_common(
    mbedtls_ssl_context *ssl,
    mbedtls_svc_key_id_t pwd)
{
    psa_status_t status;
    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
    const uint8_t *user = NULL;
    size_t user_len = 0;
    const uint8_t *peer = NULL;
    size_t peer_len = 0;
    psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
    psa_pake_cs_set_primitive(&cipher_suite,
                              PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,
                                                 PSA_ECC_FAMILY_SECP_R1,
                                                 256));
    psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);

    status = psa_pake_setup(&ssl->handshake->psa_pake_ctx, &cipher_suite);
    if (status != PSA_SUCCESS) {
        return status;
    }

    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
        user = jpake_server_id;
        user_len = sizeof(jpake_server_id);
        peer = jpake_client_id;
        peer_len = sizeof(jpake_client_id);
    } else {
        user = jpake_client_id;
        user_len = sizeof(jpake_client_id);
        peer = jpake_server_id;
        peer_len = sizeof(jpake_server_id);
    }

    status = psa_pake_set_user(&ssl->handshake->psa_pake_ctx, user, user_len);
    if (status != PSA_SUCCESS) {
        return status;
    }

    status = psa_pake_set_peer(&ssl->handshake->psa_pake_ctx, peer, peer_len);
    if (status != PSA_SUCCESS) {
        return status;
    }

    status = psa_pake_set_password_key(&ssl->handshake->psa_pake_ctx, pwd);
    if (status != PSA_SUCCESS) {
        return status;
    }

    ssl->handshake->psa_pake_ctx_is_ok = 1;

    return PSA_SUCCESS;
}

int mbedtls_ssl_set_hs_ecjpake_password(mbedtls_ssl_context *ssl,
                                        const unsigned char *pw,
                                        size_t pw_len)
{
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_status_t status;

    if (ssl->handshake == NULL || ssl->conf == NULL) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    /* Empty password is not valid  */
    if ((pw == NULL) || (pw_len == 0)) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
    psa_set_key_algorithm(&attributes, PSA_ALG_JPAKE);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);

    status = psa_import_key(&attributes, pw, pw_len,
                            &ssl->handshake->psa_pake_password);
    if (status != PSA_SUCCESS) {
        return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
    }

    status = mbedtls_ssl_set_hs_ecjpake_password_common(ssl,
                                                        ssl->handshake->psa_pake_password);
    if (status != PSA_SUCCESS) {
        psa_destroy_key(ssl->handshake->psa_pake_password);
        psa_pake_abort(&ssl->handshake->psa_pake_ctx);
        return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
    }

    return 0;
}

int mbedtls_ssl_set_hs_ecjpake_password_opaque(mbedtls_ssl_context *ssl,
                                               mbedtls_svc_key_id_t pwd)
{
    psa_status_t status;

    if (ssl->handshake == NULL || ssl->conf == NULL) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    if (mbedtls_svc_key_id_is_null(pwd)) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    status = mbedtls_ssl_set_hs_ecjpake_password_common(ssl, pwd);
    if (status != PSA_SUCCESS) {
        psa_pake_abort(&ssl->handshake->psa_pake_ctx);
        return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
    }

    return 0;
}
#else /* MBEDTLS_USE_PSA_CRYPTO */
int mbedtls_ssl_set_hs_ecjpake_password(mbedtls_ssl_context *ssl,
                                        const unsigned char *pw,
                                        size_t pw_len)
{
    mbedtls_ecjpake_role role;

    if (ssl->handshake == NULL || ssl->conf == NULL) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    /* Empty password is not valid  */
    if ((pw == NULL) || (pw_len == 0)) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
        role = MBEDTLS_ECJPAKE_SERVER;
    } else {
        role = MBEDTLS_ECJPAKE_CLIENT;
    }

    return mbedtls_ecjpake_setup(&ssl->handshake->ecjpake_ctx,
                                 role,
                                 MBEDTLS_MD_SHA256,
                                 MBEDTLS_ECP_DP_SECP256R1,
                                 pw, pw_len);
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */

#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
int mbedtls_ssl_conf_has_static_psk(mbedtls_ssl_config const *conf)
{}

static void ssl_conf_remove_psk(mbedtls_ssl_config *conf)
{}

/* This function assumes that PSK identity in the SSL config is unset.
 * It checks that the provided identity is well-formed and attempts
 * to make a copy of it in the SSL config.
 * On failure, the PSK identity in the config remains unset. */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_conf_set_psk_identity(mbedtls_ssl_config *conf,
                                     unsigned char const *psk_identity,
                                     size_t psk_identity_len)
{}

int mbedtls_ssl_conf_psk(mbedtls_ssl_config *conf,
                         const unsigned char *psk, size_t psk_len,
                         const unsigned char *psk_identity, size_t psk_identity_len)
{}

static void ssl_remove_psk(mbedtls_ssl_context *ssl)
{}

int mbedtls_ssl_set_hs_psk(mbedtls_ssl_context *ssl,
                           const unsigned char *psk, size_t psk_len)
{}

#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ssl_conf_psk_opaque(mbedtls_ssl_config *conf,
                                mbedtls_svc_key_id_t psk,
                                const unsigned char *psk_identity,
                                size_t psk_identity_len)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    /* We currently only support one PSK, raw or opaque. */
    if (mbedtls_ssl_conf_has_static_psk(conf)) {
        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
    }

    /* Check and set opaque PSK */
    if (mbedtls_svc_key_id_is_null(psk)) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }
    conf->psk_opaque = psk;

    /* Check and set PSK Identity */
    ret = ssl_conf_set_psk_identity(conf, psk_identity,
                                    psk_identity_len);
    if (ret != 0) {
        ssl_conf_remove_psk(conf);
    }

    return ret;
}

int mbedtls_ssl_set_hs_psk_opaque(mbedtls_ssl_context *ssl,
                                  mbedtls_svc_key_id_t psk)
{
    if ((mbedtls_svc_key_id_is_null(psk)) ||
        (ssl->handshake == NULL)) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    ssl_remove_psk(ssl);
    ssl->handshake->psk_opaque = psk;
    return 0;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_SSL_SRV_C)
void mbedtls_ssl_conf_psk_cb(mbedtls_ssl_config *conf,
                             int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
                                          size_t),
                             void *p_psk)
{}
#endif /* MBEDTLS_SSL_SRV_C */

#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */

#if defined(MBEDTLS_USE_PSA_CRYPTO)
static mbedtls_ssl_mode_t mbedtls_ssl_get_base_mode(
    psa_algorithm_t alg)
{
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
    if (alg == PSA_ALG_CBC_NO_PADDING) {
        return MBEDTLS_SSL_MODE_CBC;
    }
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
    if (PSA_ALG_IS_AEAD(alg)) {
        return MBEDTLS_SSL_MODE_AEAD;
    }
    return MBEDTLS_SSL_MODE_STREAM;
}

#else /* MBEDTLS_USE_PSA_CRYPTO */

static mbedtls_ssl_mode_t mbedtls_ssl_get_base_mode(
    mbedtls_cipher_mode_t mode)
{}
#endif /* MBEDTLS_USE_PSA_CRYPTO */

static mbedtls_ssl_mode_t mbedtls_ssl_get_actual_mode(
    mbedtls_ssl_mode_t base_mode,
    int encrypt_then_mac)
{}

mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_transform(
    const mbedtls_ssl_transform *transform)
{}

mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite(
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
    int encrypt_then_mac,
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
    const mbedtls_ssl_ciphersuite_t *suite)
{}

#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)

psa_status_t mbedtls_ssl_cipher_to_psa(mbedtls_cipher_type_t mbedtls_cipher_type,
                                       size_t taglen,
                                       psa_algorithm_t *alg,
                                       psa_key_type_t *key_type,
                                       size_t *key_size)
{}
#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */

#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
int mbedtls_ssl_conf_dh_param_bin(mbedtls_ssl_config *conf,
                                  const unsigned char *dhm_P, size_t P_len,
                                  const unsigned char *dhm_G, size_t G_len)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    mbedtls_mpi_free(&conf->dhm_P);
    mbedtls_mpi_free(&conf->dhm_G);

    if ((ret = mbedtls_mpi_read_binary(&conf->dhm_P, dhm_P, P_len)) != 0 ||
        (ret = mbedtls_mpi_read_binary(&conf->dhm_G, dhm_G, G_len)) != 0) {
        mbedtls_mpi_free(&conf->dhm_P);
        mbedtls_mpi_free(&conf->dhm_G);
        return ret;
    }

    return 0;
}

int mbedtls_ssl_conf_dh_param_ctx(mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    mbedtls_mpi_free(&conf->dhm_P);
    mbedtls_mpi_free(&conf->dhm_G);

    if ((ret = mbedtls_dhm_get_value(dhm_ctx, MBEDTLS_DHM_PARAM_P,
                                     &conf->dhm_P)) != 0 ||
        (ret = mbedtls_dhm_get_value(dhm_ctx, MBEDTLS_DHM_PARAM_G,
                                     &conf->dhm_G)) != 0) {
        mbedtls_mpi_free(&conf->dhm_P);
        mbedtls_mpi_free(&conf->dhm_G);
        return ret;
    }

    return 0;
}
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */

#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
/*
 * Set the minimum length for Diffie-Hellman parameters
 */
void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
                                     unsigned int bitlen)
{
    conf->dhm_min_bitlen = bitlen;
}
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
/*
 * Set allowed/preferred hashes for handshake signatures
 */
void mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf,
                                 const int *hashes)
{
    conf->sig_hashes = hashes;
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED && MBEDTLS_SSL_PROTO_TLS1_2 */

/* Configure allowed signature algorithms for handshake */
void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf,
                               const uint16_t *sig_algs)
{}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */

#if defined(MBEDTLS_ECP_C)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/*
 * Set the allowed elliptic curves
 *
 * mbedtls_ssl_setup() takes the provided list
 * and translates it to a list of IANA TLS group identifiers,
 * stored in ssl->handshake->group_list.
 *
 */
void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
                             const mbedtls_ecp_group_id *curve_list)
{
    conf->curve_list = curve_list;
    conf->group_list = NULL;
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_ECP_C */

/*
 * Set the allowed groups
 */
void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf,
                             const uint16_t *group_list)
{}

#if defined(MBEDTLS_X509_CRT_PARSE_C)
int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
{}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
void mbedtls_ssl_conf_sni(mbedtls_ssl_config *conf,
                          int (*f_sni)(void *, mbedtls_ssl_context *,
                                       const unsigned char *, size_t),
                          void *p_sni)
{}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */

#if defined(MBEDTLS_SSL_ALPN)
int mbedtls_ssl_conf_alpn_protocols(mbedtls_ssl_config *conf, const char **protos)
{}

const char *mbedtls_ssl_get_alpn_protocol(const mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_ALPN */

#if defined(MBEDTLS_SSL_DTLS_SRTP)
void mbedtls_ssl_conf_srtp_mki_value_supported(mbedtls_ssl_config *conf,
                                               int support_mki_value)
{
    conf->dtls_srtp_mki_support = support_mki_value;
}

int mbedtls_ssl_dtls_srtp_set_mki_value(mbedtls_ssl_context *ssl,
                                        unsigned char *mki_value,
                                        uint16_t mki_len)
{
    if (mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED) {
        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
    }

    memcpy(ssl->dtls_srtp_info.mki_value, mki_value, mki_len);
    ssl->dtls_srtp_info.mki_len = mki_len;
    return 0;
}

int mbedtls_ssl_conf_dtls_srtp_protection_profiles(mbedtls_ssl_config *conf,
                                                   const mbedtls_ssl_srtp_profile *profiles)
{
    const mbedtls_ssl_srtp_profile *p;
    size_t list_size = 0;

    /* check the profiles list: all entry must be valid,
     * its size cannot be more than the total number of supported profiles, currently 4 */
    for (p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET &&
         list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
         p++) {
        if (mbedtls_ssl_check_srtp_profile_value(*p) != MBEDTLS_TLS_SRTP_UNSET) {
            list_size++;
        } else {
            /* unsupported value, stop parsing and set the size to an error value */
            list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
        }
    }

    if (list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH) {
        conf->dtls_srtp_profile_list = NULL;
        conf->dtls_srtp_profile_list_len = 0;
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    conf->dtls_srtp_profile_list = profiles;
    conf->dtls_srtp_profile_list_len = list_size;

    return 0;
}

void mbedtls_ssl_get_dtls_srtp_negotiation_result(const mbedtls_ssl_context *ssl,
                                                  mbedtls_dtls_srtp_info *dtls_srtp_info)
{
    dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
    /* do not copy the mki value if there is no chosen profile */
    if (dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) {
        dtls_srtp_info->mki_len = 0;
    } else {
        dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
        memcpy(dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value,
               ssl->dtls_srtp_info.mki_len);
    }
}
#endif /* MBEDTLS_SSL_DTLS_SRTP */

#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, int major, int minor)
{
    conf->max_tls_version = (mbedtls_ssl_protocol_version) ((major << 8) | minor);
}

void mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, int major, int minor)
{
    conf->min_tls_version = (mbedtls_ssl_protocol_version) ((major << 8) | minor);
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */

#if defined(MBEDTLS_SSL_SRV_C)
void mbedtls_ssl_conf_cert_req_ca_list(mbedtls_ssl_config *conf,
                                       char cert_req_ca_list)
{}
#endif

#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
void mbedtls_ssl_conf_encrypt_then_mac(mbedtls_ssl_config *conf, char etm)
{}
#endif

#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
void mbedtls_ssl_conf_extended_master_secret(mbedtls_ssl_config *conf, char ems)
{}
#endif

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
int mbedtls_ssl_conf_max_frag_len(mbedtls_ssl_config *conf, unsigned char mfl_code)
{}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */

void mbedtls_ssl_conf_legacy_renegotiation(mbedtls_ssl_config *conf, int allow_legacy)
{}

#if defined(MBEDTLS_SSL_RENEGOTIATION)
void mbedtls_ssl_conf_renegotiation(mbedtls_ssl_config *conf, int renegotiation)
{}

void mbedtls_ssl_conf_renegotiation_enforced(mbedtls_ssl_config *conf, int max_records)
{}

void mbedtls_ssl_conf_renegotiation_period(mbedtls_ssl_config *conf,
                                           const unsigned char period[8])
{}
#endif /* MBEDTLS_SSL_RENEGOTIATION */

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
#if defined(MBEDTLS_SSL_CLI_C)

void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets)
{}

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
    mbedtls_ssl_config *conf, int signal_new_session_tickets)
{}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_SRV_C)

#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
void mbedtls_ssl_conf_new_session_tickets(mbedtls_ssl_config *conf,
                                          uint16_t num_tickets)
{}
#endif

void mbedtls_ssl_conf_session_tickets_cb(mbedtls_ssl_config *conf,
                                         mbedtls_ssl_ticket_write_t *f_ticket_write,
                                         mbedtls_ssl_ticket_parse_t *f_ticket_parse,
                                         void *p_ticket)
{}
#endif
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

void mbedtls_ssl_set_export_keys_cb(mbedtls_ssl_context *ssl,
                                    mbedtls_ssl_export_keys_t *f_export_keys,
                                    void *p_export_keys)
{}

#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
void mbedtls_ssl_conf_async_private_cb(
    mbedtls_ssl_config *conf,
    mbedtls_ssl_async_sign_t *f_async_sign,
    mbedtls_ssl_async_decrypt_t *f_async_decrypt,
    mbedtls_ssl_async_resume_t *f_async_resume,
    mbedtls_ssl_async_cancel_t *f_async_cancel,
    void *async_config_data)
{
    conf->f_async_sign_start = f_async_sign;
    conf->f_async_decrypt_start = f_async_decrypt;
    conf->f_async_resume = f_async_resume;
    conf->f_async_cancel = f_async_cancel;
    conf->p_async_config_data = async_config_data;
}

void *mbedtls_ssl_conf_get_async_config_data(const mbedtls_ssl_config *conf)
{
    return conf->p_async_config_data;
}

void *mbedtls_ssl_get_async_operation_data(const mbedtls_ssl_context *ssl)
{
    if (ssl->handshake == NULL) {
        return NULL;
    } else {
        return ssl->handshake->user_async_ctx;
    }
}

void mbedtls_ssl_set_async_operation_data(mbedtls_ssl_context *ssl,
                                          void *ctx)
{
    if (ssl->handshake != NULL) {
        ssl->handshake->user_async_ctx = ctx;
    }
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */

/*
 * SSL get accessors
 */
uint32_t mbedtls_ssl_get_verify_result(const mbedtls_ssl_context *ssl)
{}

int mbedtls_ssl_get_ciphersuite_id_from_ssl(const mbedtls_ssl_context *ssl)
{}

const char *mbedtls_ssl_get_ciphersuite(const mbedtls_ssl_context *ssl)
{}

const char *mbedtls_ssl_get_version(const mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)

size_t mbedtls_ssl_get_output_record_size_limit(const mbedtls_ssl_context *ssl)
{
    const size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
    size_t record_size_limit = max_len;

    if (ssl->session != NULL &&
        ssl->session->record_size_limit >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN &&
        ssl->session->record_size_limit < max_len) {
        record_size_limit = ssl->session->record_size_limit;
    }

    // TODO: this is currently untested
    /* During a handshake, use the value being negotiated */
    if (ssl->session_negotiate != NULL &&
        ssl->session_negotiate->record_size_limit >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN &&
        ssl->session_negotiate->record_size_limit < max_len) {
        record_size_limit = ssl->session_negotiate->record_size_limit;
    }

    return record_size_limit;
}
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
size_t mbedtls_ssl_get_input_max_frag_len(const mbedtls_ssl_context *ssl)
{}

size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */

#if defined(MBEDTLS_SSL_PROTO_DTLS)
size_t mbedtls_ssl_get_current_mtu(const mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_PROTO_DTLS */

int mbedtls_ssl_get_max_out_record_payload(const mbedtls_ssl_context *ssl)
{}

int mbedtls_ssl_get_max_in_record_payload(const mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_X509_CRT_PARSE_C)
const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

#if defined(MBEDTLS_SSL_CLI_C)
int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
                            mbedtls_ssl_session *dst)
{}
#endif /* MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_PROTO_TLS1_2)

/* Serialization of TLS 1.2 sessions
 *
 * For more detail, see the description of ssl_session_save().
 */
static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
                                     unsigned char *buf,
                                     size_t buf_len)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls12_session_load(mbedtls_ssl_session *session,
                                  const unsigned char *buf,
                                  size_t len)
{}

#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/* Serialization of TLS 1.3 sessions:
 *
 * For more detail, see the description of ssl_session_save().
 */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
                                  unsigned char *buf,
                                  size_t buf_len,
                                  size_t *olen)
{}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_session_load(mbedtls_ssl_session *session,
                                  const unsigned char *buf,
                                  size_t len)
{}
#else /* MBEDTLS_SSL_SESSION_TICKETS */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
                                  unsigned char *buf,
                                  size_t buf_len,
                                  size_t *olen)
{
    ((void) session);
    ((void) buf);
    ((void) buf_len);
    *olen = 0;
    return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
}

static int ssl_tls13_session_load(const mbedtls_ssl_session *session,
                                  const unsigned char *buf,
                                  size_t buf_len)
{
    ((void) session);
    ((void) buf);
    ((void) buf_len);
    return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
}
#endif /* !MBEDTLS_SSL_SESSION_TICKETS */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

/*
 * Define ticket header determining Mbed TLS version
 * and structure of the ticket.
 */

/*
 * Define bitflag determining compile-time settings influencing
 * structure of serialized SSL sessions.
 */

#if defined(MBEDTLS_HAVE_TIME)
#define SSL_SERIALIZED_SESSION_CONFIG_TIME
#else
#define SSL_SERIALIZED_SESSION_CONFIG_TIME
#endif /* MBEDTLS_HAVE_TIME */

#if defined(MBEDTLS_X509_CRT_PARSE_C)
#define SSL_SERIALIZED_SESSION_CONFIG_CRT
#else
#define SSL_SERIALIZED_SESSION_CONFIG_CRT
#endif /* MBEDTLS_X509_CRT_PARSE_C */

#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT
#else
#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET
#else
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET
#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SESSION_TICKETS */

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
#define SSL_SERIALIZED_SESSION_CONFIG_MFL
#else
#define SSL_SERIALIZED_SESSION_CONFIG_MFL
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */

#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
#define SSL_SERIALIZED_SESSION_CONFIG_ETM
#else
#define SSL_SERIALIZED_SESSION_CONFIG_ETM
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET
#else
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
#define SSL_SERIALIZED_SESSION_CONFIG_SNI
#else
#define SSL_SERIALIZED_SESSION_CONFIG_SNI
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */

#if defined(MBEDTLS_SSL_EARLY_DATA)
#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA
#else
#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA
#endif /* MBEDTLS_SSL_EARLY_DATA */

#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE
#else
#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */

#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) && \
    defined(MBEDTLS_SSL_EARLY_DATA)
#define SSL_SERIALIZED_SESSION_CONFIG_ALPN
#else
#define SSL_SERIALIZED_SESSION_CONFIG_ALPN
#endif /* MBEDTLS_SSL_ALPN */

#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT
#define SSL_SERIALIZED_SESSION_CONFIG_ALPN_BIT

#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG

static const unsigned char ssl_serialized_session_header[] =;

/*
 * Serialize a session in the following format:
 * (in the presentation language of TLS, RFC 8446 section 3)
 *
 * TLS 1.2 session:
 *
 * struct {
 * #if defined(MBEDTLS_SSL_SESSION_TICKETS)
 *    opaque ticket<0..2^24-1>;       // length 0 means no ticket
 *    uint32 ticket_lifetime;
 * #endif
 * } ClientOnlyData;
 *
 * struct {
 * #if defined(MBEDTLS_HAVE_TIME)
 *    uint64 start_time;
 * #endif
 *     uint8 session_id_len;           // at most 32
 *     opaque session_id[32];
 *     opaque master[48];              // fixed length in the standard
 *     uint32 verify_result;
 * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
 *    opaque peer_cert<0..2^24-1>;    // length 0 means no peer cert
 * #else
 *    uint8 peer_cert_digest_type;
 *    opaque peer_cert_digest<0..2^8-1>
 * #endif
 *     select (endpoint) {
 *         case client: ClientOnlyData;
 *         case server: uint64 ticket_creation_time;
 *     };
 * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 *    uint8 mfl_code;                 // up to 255 according to standard
 * #endif
 * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
 *    uint8 encrypt_then_mac;         // 0 or 1
 * #endif
 * } serialized_session_tls12;
 *
 *
 * TLS 1.3 Session:
 *
 * struct {
 * #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
 *    opaque hostname<0..2^16-1>;
 * #endif
 * #if defined(MBEDTLS_HAVE_TIME)
 *    uint64 ticket_reception_time;
 * #endif
 *    uint32 ticket_lifetime;
 *    opaque ticket<1..2^16-1>;
 * } ClientOnlyData;
 *
 * struct {
 *    uint32 ticket_age_add;
 *    uint8 ticket_flags;
 *    opaque resumption_key<0..255>;
 * #if defined(MBEDTLS_SSL_EARLY_DATA)
 *    uint32 max_early_data_size;
 * #endif
 * #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
 *    uint16 record_size_limit;
 * #endif
 *    select ( endpoint ) {
 *         case client: ClientOnlyData;
 *         case server:
 * #if defined(MBEDTLS_HAVE_TIME)
 *                      uint64 ticket_creation_time;
 * #endif
 * #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
 *                      opaque ticket_alpn<0..256>;
 * #endif
 *     };
 * } serialized_session_tls13;
 *
 *
 * SSL session:
 *
 * struct {
 *
 *    opaque mbedtls_version[3];   // library version: major, minor, patch
 *    opaque session_format[2];    // library-version specific 16-bit field
 *                                 // determining the format of the remaining
 *                                 // serialized data.
 *
 *          Note: When updating the format, remember to keep
 *          these version+format bytes.
 *
 *                                 // In this version, `session_format` determines
 *                                 // the setting of those compile-time
 *                                 // configuration options which influence
 *                                 // the structure of mbedtls_ssl_session.
 *
 *    uint8_t minor_ver;           // Protocol minor version. Possible values:
 *                                 // - TLS 1.2 (0x0303)
 *                                 // - TLS 1.3 (0x0304)
 *    uint8_t endpoint;
 *    uint16_t ciphersuite;
 *
 *    select (serialized_session.tls_version) {
 *
 *      case MBEDTLS_SSL_VERSION_TLS1_2:
 *        serialized_session_tls12 data;
 *      case MBEDTLS_SSL_VERSION_TLS1_3:
 *        serialized_session_tls13 data;
 *
 *   };
 *
 * } serialized_session;
 *
 */

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_session_save(const mbedtls_ssl_session *session,
                            unsigned char omit_header,
                            unsigned char *buf,
                            size_t buf_len,
                            size_t *olen)
{}

/*
 * Public wrapper for ssl_session_save()
 */
int mbedtls_ssl_session_save(const mbedtls_ssl_session *session,
                             unsigned char *buf,
                             size_t buf_len,
                             size_t *olen)
{}

/*
 * Deserialize session, see mbedtls_ssl_session_save() for format.
 *
 * This internal version is wrapped by a public function that cleans up in
 * case of error, and has an extra option omit_header.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_session_load(mbedtls_ssl_session *session,
                            unsigned char omit_header,
                            const unsigned char *buf,
                            size_t len)
{}

/*
 * Deserialize session: public wrapper for error cleaning
 */
int mbedtls_ssl_session_load(mbedtls_ssl_session *session,
                             const unsigned char *buf,
                             size_t len)
{}

/*
 * Perform a single step of the SSL handshake
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_prepare_handshake_step(mbedtls_ssl_context *ssl)
{}

int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl)
{}

/*
 * Perform the SSL handshake
 */
int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_RENEGOTIATION)
#if defined(MBEDTLS_SSL_SRV_C)
/*
 * Write HelloRequest to request renegotiation on server
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_hello_request(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_SRV_C */

/*
 * Actually renegotiate current connection, triggered by either:
 * - any side: calling mbedtls_ssl_renegotiate(),
 * - client: receiving a HelloRequest during mbedtls_ssl_read(),
 * - server: receiving any handshake message on server during mbedtls_ssl_read() after
 *   the initial handshake is completed.
 * If the handshake doesn't complete due to waiting for I/O, it will continue
 * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
 */
int mbedtls_ssl_start_renegotiation(mbedtls_ssl_context *ssl)
{}

/*
 * Renegotiate current connection on client,
 * or request renegotiation on server
 */
int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_RENEGOTIATION */

void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
{}

void mbedtls_ssl_session_free(mbedtls_ssl_session *session)
{}

#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)

#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID
#else
#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */

#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT

#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY
#else
#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */

#if defined(MBEDTLS_SSL_ALPN)
#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN
#else
#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN
#endif /* MBEDTLS_SSL_ALPN */

#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT
#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT
#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT
#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT

#define SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG

static const unsigned char ssl_serialized_context_header[] =;

/*
 * Serialize a full SSL context
 *
 * The format of the serialized data is:
 * (in the presentation language of TLS, RFC 8446 section 3)
 *
 *  // header
 *  opaque mbedtls_version[3];   // major, minor, patch
 *  opaque context_format[5];    // version-specific field determining
 *                               // the format of the remaining
 *                               // serialized data.
 *  Note: When updating the format, remember to keep these
 *        version+format bytes. (We may make their size part of the API.)
 *
 *  // session sub-structure
 *  opaque session<1..2^32-1>;  // see mbedtls_ssl_session_save()
 *  // transform sub-structure
 *  uint8 random[64];           // ServerHello.random+ClientHello.random
 *  uint8 in_cid<0..2^8-1>      // Connection ID: expected incoming value
 *  uint8 out_cid<0..2^8-1>     // Connection ID: outgoing value to use
 *  // fields from ssl_context
 *  uint32 badmac_seen;         // DTLS: number of records with failing MAC
 *  uint64 in_window_top;       // DTLS: last validated record seq_num
 *  uint64 in_window;           // DTLS: bitmask for replay protection
 *  uint8 disable_datagram_packing; // DTLS: only one record per datagram
 *  uint64 cur_out_ctr;         // Record layer: outgoing sequence number
 *  uint16 mtu;                 // DTLS: path mtu (max outgoing fragment size)
 *  uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
 *
 * Note that many fields of the ssl_context or sub-structures are not
 * serialized, as they fall in one of the following categories:
 *
 *  1. forced value (eg in_left must be 0)
 *  2. pointer to dynamically-allocated memory (eg session, transform)
 *  3. value can be re-derived from other data (eg session keys from MS)
 *  4. value was temporary (eg content of input buffer)
 *  5. value will be provided by the user again (eg I/O callbacks and context)
 */
int mbedtls_ssl_context_save(mbedtls_ssl_context *ssl,
                             unsigned char *buf,
                             size_t buf_len,
                             size_t *olen)
{}

/*
 * Deserialize context, see mbedtls_ssl_context_save() for format.
 *
 * This internal version is wrapped by a public function that cleans up in
 * case of error.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_context_load(mbedtls_ssl_context *ssl,
                            const unsigned char *buf,
                            size_t len)
{}

/*
 * Deserialize context: public wrapper for error cleaning
 */
int mbedtls_ssl_context_load(mbedtls_ssl_context *context,
                             const unsigned char *buf,
                             size_t len)
{}
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */

/*
 * Free an SSL context
 */
void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
{}

/*
 * Initialize mbedtls_ssl_config
 */
void mbedtls_ssl_config_init(mbedtls_ssl_config *conf)
{}

/* The selection should be the same as mbedtls_x509_crt_profile_default in
 * x509_crt.c, plus Montgomery curves for ECDHE. Here, the order matters:
 * curves with a lower resource usage come first.
 * See the documentation of mbedtls_ssl_conf_curves() for what we promise
 * about this list.
 */
static const uint16_t ssl_preset_default_groups[] =;

static const int ssl_preset_suiteb_ciphersuites[] =;

#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)

/* NOTICE:
 *   For ssl_preset_*_sig_algs and ssl_tls12_preset_*_sig_algs, the following
 *   rules SHOULD be upheld.
 *   - No duplicate entries.
 *   - But if there is a good reason, do not change the order of the algorithms.
 *   - ssl_tls12_preset* is for TLS 1.2 use only.
 *   - ssl_preset_* is for TLS 1.3 only or hybrid TLS 1.3/1.2 handshakes.
 */
static const uint16_t ssl_preset_default_sig_algs[] =;

/* NOTICE: see above */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static uint16_t ssl_tls12_preset_default_sig_algs[] =;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */

/* NOTICE: see above */
static const uint16_t ssl_preset_suiteb_sig_algs[] =;

/* NOTICE: see above */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static uint16_t ssl_tls12_preset_suiteb_sig_algs[] =;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */

#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */

static const uint16_t ssl_preset_suiteb_groups[] =;

#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
/* Function for checking `ssl_preset_*_sig_algs` and `ssl_tls12_preset_*_sig_algs`
 * to make sure there are no duplicated signature algorithm entries. */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_no_sig_alg_duplication(const uint16_t *sig_algs)
{}

#endif /* MBEDTLS_DEBUG_C && MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */

/*
 * Load default in mbedtls_ssl_config
 */
int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
                                int endpoint, int transport, int preset)
{}

/*
 * Free mbedtls_ssl_config
 */
void mbedtls_ssl_config_free(mbedtls_ssl_config *conf)
{}

#if defined(MBEDTLS_PK_C) && \
    (defined(MBEDTLS_RSA_C) || defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED))
/*
 * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
 */
unsigned char mbedtls_ssl_sig_from_pk(mbedtls_pk_context *pk)
{}

unsigned char mbedtls_ssl_sig_from_pk_alg(mbedtls_pk_type_t type)
{}

mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig(unsigned char sig)
{}
#endif /* MBEDTLS_PK_C &&
          ( MBEDTLS_RSA_C || MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED ) */

/*
 * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
 */
mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash(unsigned char hash)
{}

/*
 * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX
 */
unsigned char mbedtls_ssl_hash_from_md_alg(int md)
{}

/*
 * Check if a curve proposed by the peer is in our list.
 * Return 0 if we're willing to use it, -1 otherwise.
 */
int mbedtls_ssl_check_curve_tls_id(const mbedtls_ssl_context *ssl, uint16_t tls_id)
{}

#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
/*
 * Same as mbedtls_ssl_check_curve_tls_id() but with a mbedtls_ecp_group_id.
 */
int mbedtls_ssl_check_curve(const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id)
{}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */

static const struct {} tls_id_match_table[] =;

int mbedtls_ssl_get_psa_curve_info_from_tls_id(uint16_t tls_id,
                                               psa_key_type_t *type,
                                               size_t *bits)
{}

mbedtls_ecp_group_id mbedtls_ssl_get_ecp_group_id_from_tls_id(uint16_t tls_id)
{}

uint16_t mbedtls_ssl_get_tls_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id)
{}

#if defined(MBEDTLS_DEBUG_C)
static const struct {} tls_id_curve_name_table[] =;

const char *mbedtls_ssl_get_curve_name_from_tls_id(uint16_t tls_id)
{}
#endif

#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ssl_get_handshake_transcript(mbedtls_ssl_context *ssl,
                                         const mbedtls_md_type_t md,
                                         unsigned char *dst,
                                         size_t dst_len,
                                         size_t *olen)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_hash_operation_t *hash_operation_to_clone;
    psa_hash_operation_t hash_operation = psa_hash_operation_init();

    *olen = 0;

    switch (md) {
#if defined(MBEDTLS_MD_CAN_SHA384)
        case MBEDTLS_MD_SHA384:
            hash_operation_to_clone = &ssl->handshake->fin_sha384_psa;
            break;
#endif

#if defined(MBEDTLS_MD_CAN_SHA256)
        case MBEDTLS_MD_SHA256:
            hash_operation_to_clone = &ssl->handshake->fin_sha256_psa;
            break;
#endif

        default:
            goto exit;
    }

    status = psa_hash_clone(hash_operation_to_clone, &hash_operation);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_finish(&hash_operation, dst, dst_len, olen);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

exit:
#if !defined(MBEDTLS_MD_CAN_SHA384) && \
    !defined(MBEDTLS_MD_CAN_SHA256)
    (void) ssl;
#endif
    return PSA_TO_MBEDTLS_ERR(status);
}
#else /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_MD_CAN_SHA384)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_handshake_transcript_sha384(mbedtls_ssl_context *ssl,
                                               unsigned char *dst,
                                               size_t dst_len,
                                               size_t *olen)
{}
#endif /* MBEDTLS_MD_CAN_SHA384 */

#if defined(MBEDTLS_MD_CAN_SHA256)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_handshake_transcript_sha256(mbedtls_ssl_context *ssl,
                                               unsigned char *dst,
                                               size_t dst_len,
                                               size_t *olen)
{}
#endif /* MBEDTLS_MD_CAN_SHA256 */

int mbedtls_ssl_get_handshake_transcript(mbedtls_ssl_context *ssl,
                                         const mbedtls_md_type_t md,
                                         unsigned char *dst,
                                         size_t dst_len,
                                         size_t *olen)
{}

#endif /* !MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
/* mbedtls_ssl_parse_sig_alg_ext()
 *
 * The `extension_data` field of signature algorithm contains  a `SignatureSchemeList`
 * value (TLS 1.3 RFC8446):
 *      enum {
 *         ....
 *        ecdsa_secp256r1_sha256( 0x0403 ),
 *        ecdsa_secp384r1_sha384( 0x0503 ),
 *        ecdsa_secp521r1_sha512( 0x0603 ),
 *         ....
 *      } SignatureScheme;
 *
 *      struct {
 *         SignatureScheme supported_signature_algorithms<2..2^16-2>;
 *      } SignatureSchemeList;
 *
 * The `extension_data` field of signature algorithm contains a `SignatureAndHashAlgorithm`
 * value (TLS 1.2 RFC5246):
 *      enum {
 *          none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
 *          sha512(6), (255)
 *      } HashAlgorithm;
 *
 *      enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
 *        SignatureAlgorithm;
 *
 *      struct {
 *          HashAlgorithm hash;
 *          SignatureAlgorithm signature;
 *      } SignatureAndHashAlgorithm;
 *
 *      SignatureAndHashAlgorithm
 *        supported_signature_algorithms<2..2^16-2>;
 *
 * The TLS 1.3 signature algorithm extension was defined to be a compatible
 * generalization of the TLS 1.2 signature algorithm extension.
 * `SignatureAndHashAlgorithm` field of TLS 1.2 can be represented by
 * `SignatureScheme` field of TLS 1.3
 *
 */
int mbedtls_ssl_parse_sig_alg_ext(mbedtls_ssl_context *ssl,
                                  const unsigned char *buf,
                                  const unsigned char *end)
{}

#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */

#if defined(MBEDTLS_SSL_PROTO_TLS1_2)

#if defined(MBEDTLS_USE_PSA_CRYPTO)

static psa_status_t setup_psa_key_derivation(psa_key_derivation_operation_t *derivation,
                                             mbedtls_svc_key_id_t key,
                                             psa_algorithm_t alg,
                                             const unsigned char *raw_psk, size_t raw_psk_length,
                                             const unsigned char *seed, size_t seed_length,
                                             const unsigned char *label, size_t label_length,
                                             const unsigned char *other_secret,
                                             size_t other_secret_length,
                                             size_t capacity)
{
    psa_status_t status;

    status = psa_key_derivation_setup(derivation, alg);
    if (status != PSA_SUCCESS) {
        return status;
    }

    if (PSA_ALG_IS_TLS12_PRF(alg) || PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
        status = psa_key_derivation_input_bytes(derivation,
                                                PSA_KEY_DERIVATION_INPUT_SEED,
                                                seed, seed_length);
        if (status != PSA_SUCCESS) {
            return status;
        }

        if (other_secret != NULL) {
            status = psa_key_derivation_input_bytes(derivation,
                                                    PSA_KEY_DERIVATION_INPUT_OTHER_SECRET,
                                                    other_secret, other_secret_length);
            if (status != PSA_SUCCESS) {
                return status;
            }
        }

        if (mbedtls_svc_key_id_is_null(key)) {
            status = psa_key_derivation_input_bytes(
                derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
                raw_psk, raw_psk_length);
        } else {
            status = psa_key_derivation_input_key(
                derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key);
        }
        if (status != PSA_SUCCESS) {
            return status;
        }

        status = psa_key_derivation_input_bytes(derivation,
                                                PSA_KEY_DERIVATION_INPUT_LABEL,
                                                label, label_length);
        if (status != PSA_SUCCESS) {
            return status;
        }
    } else {
        return PSA_ERROR_NOT_SUPPORTED;
    }

    status = psa_key_derivation_set_capacity(derivation, capacity);
    if (status != PSA_SUCCESS) {
        return status;
    }

    return PSA_SUCCESS;
}

#if defined(PSA_WANT_ALG_SHA_384) || \
    defined(PSA_WANT_ALG_SHA_256)
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_generic(mbedtls_md_type_t md_type,
                           const unsigned char *secret, size_t slen,
                           const char *label,
                           const unsigned char *random, size_t rlen,
                           unsigned char *dstbuf, size_t dlen)
{
    psa_status_t status;
    psa_algorithm_t alg;
    mbedtls_svc_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
    psa_key_derivation_operation_t derivation =
        PSA_KEY_DERIVATION_OPERATION_INIT;

    if (md_type == MBEDTLS_MD_SHA384) {
        alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
    } else {
        alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
    }

    /* Normally a "secret" should be long enough to be impossible to
     * find by brute force, and in particular should not be empty. But
     * this PRF is also used to derive an IV, in particular in EAP-TLS,
     * and for this use case it makes sense to have a 0-length "secret".
     * Since the key API doesn't allow importing a key of length 0,
     * keep master_key=0, which setup_psa_key_derivation() understands
     * to mean a 0-length "secret" input. */
    if (slen != 0) {
        psa_key_attributes_t key_attributes = psa_key_attributes_init();
        psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
        psa_set_key_algorithm(&key_attributes, alg);
        psa_set_key_type(&key_attributes, PSA_KEY_TYPE_DERIVE);

        status = psa_import_key(&key_attributes, secret, slen, &master_key);
        if (status != PSA_SUCCESS) {
            return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
        }
    }

    status = setup_psa_key_derivation(&derivation,
                                      master_key, alg,
                                      NULL, 0,
                                      random, rlen,
                                      (unsigned char const *) label,
                                      (size_t) strlen(label),
                                      NULL, 0,
                                      dlen);
    if (status != PSA_SUCCESS) {
        psa_key_derivation_abort(&derivation);
        psa_destroy_key(master_key);
        return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
    }

    status = psa_key_derivation_output_bytes(&derivation, dstbuf, dlen);
    if (status != PSA_SUCCESS) {
        psa_key_derivation_abort(&derivation);
        psa_destroy_key(master_key);
        return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
    }

    status = psa_key_derivation_abort(&derivation);
    if (status != PSA_SUCCESS) {
        psa_destroy_key(master_key);
        return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
    }

    if (!mbedtls_svc_key_id_is_null(master_key)) {
        status = psa_destroy_key(master_key);
    }
    if (status != PSA_SUCCESS) {
        return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
    }

    return 0;
}
#endif /* PSA_WANT_ALG_SHA_256 || PSA_WANT_ALG_SHA_384 */
#else /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_MD_C) &&       \
    (defined(MBEDTLS_MD_CAN_SHA256) || \
    defined(MBEDTLS_MD_CAN_SHA384))
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_generic(mbedtls_md_type_t md_type,
                           const unsigned char *secret, size_t slen,
                           const char *label,
                           const unsigned char *random, size_t rlen,
                           unsigned char *dstbuf, size_t dlen)
{}
#endif /* MBEDTLS_MD_C && ( MBEDTLS_MD_CAN_SHA256 || MBEDTLS_MD_CAN_SHA384 ) */
#endif /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_MD_CAN_SHA256)
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_sha256(const unsigned char *secret, size_t slen,
                          const char *label,
                          const unsigned char *random, size_t rlen,
                          unsigned char *dstbuf, size_t dlen)
{}
#endif /* MBEDTLS_MD_CAN_SHA256*/

#if defined(MBEDTLS_MD_CAN_SHA384)
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_sha384(const unsigned char *secret, size_t slen,
                          const char *label,
                          const unsigned char *random, size_t rlen,
                          unsigned char *dstbuf, size_t dlen)
{}
#endif /* MBEDTLS_MD_CAN_SHA384*/

/*
 * Set appropriate PRF function and other SSL / TLS1.2 functions
 *
 * Inputs:
 * - hash associated with the ciphersuite (only used by TLS 1.2)
 *
 * Outputs:
 * - the tls_prf, calc_verify and calc_finished members of handshake structure
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_set_handshake_prfs(mbedtls_ssl_handshake_params *handshake,
                                  mbedtls_md_type_t hash)
{}

/*
 * Compute master secret if needed
 *
 * Parameters:
 * [in/out] handshake
 *          [in] resume, premaster, extended_ms, calc_verify, tls_prf
 *               (PSA-PSK) ciphersuite_info, psk_opaque
 *          [out] premaster (cleared)
 * [out] master
 * [in] ssl: optionally used for debugging, EMS and PSA-PSK
 *      debug: conf->f_dbg, conf->p_dbg
 *      EMS: passed to calc_verify (debug + session_negotiate)
 *      PSA-PSA: conf
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake,
                              unsigned char *master,
                              const mbedtls_ssl_context *ssl)
{}

int mbedtls_ssl_derive_keys(mbedtls_ssl_context *ssl)
{}

int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md)
{}

#if defined(MBEDTLS_USE_PSA_CRYPTO)
static int ssl_calc_verify_tls_psa(const mbedtls_ssl_context *ssl,
                                   const psa_hash_operation_t *hs_op,
                                   size_t buffer_size,
                                   unsigned char *hash,
                                   size_t *hlen)
{
    psa_status_t status;
    psa_hash_operation_t cloned_op = psa_hash_operation_init();

#if !defined(MBEDTLS_DEBUG_C)
    (void) ssl;
#endif
    MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify"));
    status = psa_hash_clone(hs_op, &cloned_op);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_finish(&cloned_op, hash, buffer_size, hlen);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen);
    MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify"));

exit:
    psa_hash_abort(&cloned_op);
    return mbedtls_md_error_from_psa(status);
}
#else
static int ssl_calc_verify_tls_legacy(const mbedtls_ssl_context *ssl,
                                      const mbedtls_md_context_t *hs_ctx,
                                      unsigned char *hash,
                                      size_t *hlen)
{}
#endif /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_MD_CAN_SHA256)
int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
                               unsigned char *hash,
                               size_t *hlen)
{}
#endif /* MBEDTLS_MD_CAN_SHA256 */

#if defined(MBEDTLS_MD_CAN_SHA384)
int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
                               unsigned char *hash,
                               size_t *hlen)
{}
#endif /* MBEDTLS_MD_CAN_SHA384 */

#if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                      \
    defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
int mbedtls_ssl_psk_derive_premaster(mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex)
{}
#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */

#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_hello_request(mbedtls_ssl_context *ssl);

#if defined(MBEDTLS_SSL_PROTO_DTLS)
int mbedtls_ssl_resend_hello_request(mbedtls_ssl_context *ssl)
{}
#endif
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */

/*
 * Handshake functions
 */
#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* No certificate support -> dummy functions */
int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
{
    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
        ssl->handshake->ciphersuite_info;

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate"));

    if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
        MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
        ssl->state++;
        return 0;
    }

    MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
    return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}

int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
{
    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
        ssl->handshake->ciphersuite_info;

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate"));

    if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
        MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate"));
        ssl->state++;
        return 0;
    }

    MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
    return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}

#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/* Some certificate support -> implement write and parse */

int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)

#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl,
                                        unsigned char *crt_buf,
                                        size_t crt_buf_len)
{}
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl,
                                        unsigned char *crt_buf,
                                        size_t crt_buf_len)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char const * const peer_cert_digest =
        ssl->session->peer_cert_digest;
    mbedtls_md_type_t const peer_cert_digest_type =
        ssl->session->peer_cert_digest_type;
    mbedtls_md_info_t const * const digest_info =
        mbedtls_md_info_from_type(peer_cert_digest_type);
    unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
    size_t digest_len;

    if (peer_cert_digest == NULL || digest_info == NULL) {
        return -1;
    }

    digest_len = mbedtls_md_get_size(digest_info);
    if (digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN) {
        return -1;
    }

    ret = mbedtls_md(digest_info, crt_buf, crt_buf_len, tmp_digest);
    if (ret != 0) {
        return -1;
    }

    return memcmp(tmp_digest, peer_cert_digest, digest_len);
}
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */

/*
 * Once the certificate message is read, parse it into a cert chain and
 * perform basic checks, but leave actual verification to the caller
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_chain(mbedtls_ssl_context *ssl,
                                       mbedtls_x509_crt *chain)
{}

#if defined(MBEDTLS_SSL_SRV_C)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_srv_check_client_no_crt_notification(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_SSL_SRV_C */

/* Check if a certificate message is expected.
 * Return either
 * - SSL_CERTIFICATE_EXPECTED, or
 * - SSL_CERTIFICATE_SKIP
 * indicating whether a Certificate message is expected or not.
 */
#define SSL_CERTIFICATE_EXPECTED
#define SSL_CERTIFICATE_SKIP
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl,
                                            int authmode)
{}

#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_remember_peer_crt_digest(mbedtls_ssl_context *ssl,
                                        unsigned char *start, size_t len)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    /* Remember digest of the peer's end-CRT. */
    ssl->session_negotiate->peer_cert_digest =
        mbedtls_calloc(1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN);
    if (ssl->session_negotiate->peer_cert_digest == NULL) {
        MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%d bytes) failed",
                                  MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN));
        mbedtls_ssl_send_alert_message(ssl,
                                       MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                       MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);

        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
    }

    ret = mbedtls_md(mbedtls_md_info_from_type(
                         MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE),
                     start, len,
                     ssl->session_negotiate->peer_cert_digest);

    ssl->session_negotiate->peer_cert_digest_type =
        MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
    ssl->session_negotiate->peer_cert_digest_len =
        MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;

    return ret;
}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_remember_peer_pubkey(mbedtls_ssl_context *ssl,
                                    unsigned char *start, size_t len)
{
    unsigned char *end = start + len;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    /* Make a copy of the peer's raw public key. */
    mbedtls_pk_init(&ssl->handshake->peer_pubkey);
    ret = mbedtls_pk_parse_subpubkey(&start, end,
                                     &ssl->handshake->peer_pubkey);
    if (ret != 0) {
        /* We should have parsed the public key before. */
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    return 0;
}
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */

int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
{}
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */

static int ssl_calc_finished_tls_generic(mbedtls_ssl_context *ssl, void *ctx,
                                         unsigned char *padbuf, size_t hlen,
                                         unsigned char *buf, int from)
{}

#if defined(MBEDTLS_MD_CAN_SHA256)
static int ssl_calc_finished_tls_sha256(
    mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{}
#endif /* MBEDTLS_MD_CAN_SHA256*/


#if defined(MBEDTLS_MD_CAN_SHA384)
static int ssl_calc_finished_tls_sha384(
    mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{}
#endif /* MBEDTLS_MD_CAN_SHA384*/

void mbedtls_ssl_handshake_wrapup_free_hs_transform(mbedtls_ssl_context *ssl)
{}

void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl)
{}

int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
{}

#define SSL_MAX_HASH_LEN

int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
/*
 * Helper to get TLS 1.2 PRF from ciphersuite
 * (Duplicates bits of logic from ssl_set_handshake_prfs().)
 */
static tls_prf_fn ssl_tls12prf_from_cs(int ciphersuite_id)
{}
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */

static mbedtls_tls_prf_types tls_prf_get_type(mbedtls_ssl_tls_prf_cb *tls_prf)
{}

/*
 * Populate a transform structure with session keys and all the other
 * necessary information.
 *
 * Parameters:
 * - [in/out]: transform: structure to populate
 *      [in] must be just initialised with mbedtls_ssl_transform_init()
 *      [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf()
 * - [in] ciphersuite
 * - [in] master
 * - [in] encrypt_then_mac
 * - [in] tls_prf: pointer to PRF to use for key derivation
 * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
 * - [in] tls_version: TLS version
 * - [in] endpoint: client or server
 * - [in] ssl: used for:
 *        - ssl->conf->{f,p}_export_keys
 *      [in] optionally used for:
 *        - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform,
                                        int ciphersuite,
                                        const unsigned char master[48],
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
                                        int encrypt_then_mac,
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
                                        ssl_tls_prf_t tls_prf,
                                        const unsigned char randbytes[64],
                                        mbedtls_ssl_protocol_version tls_version,
                                        unsigned endpoint,
                                        const mbedtls_ssl_context *ssl)
{}

#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
    defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_psa_ecjpake_read_round(
    psa_pake_operation_t *pake_ctx,
    const unsigned char *buf,
    size_t len, mbedtls_ecjpake_rounds_t round)
{
    psa_status_t status;
    size_t input_offset = 0;
    /*
     * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice
     * At round two perform a single cycle
     */
    unsigned int remaining_steps = (round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1;

    for (; remaining_steps > 0; remaining_steps--) {
        for (psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE;
             step <= PSA_PAKE_STEP_ZK_PROOF;
             ++step) {
            /* Length is stored at the first byte */
            size_t length = buf[input_offset];
            input_offset += 1;

            if (input_offset + length > len) {
                return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
            }

            status = psa_pake_input(pake_ctx, step,
                                    buf + input_offset, length);
            if (status != PSA_SUCCESS) {
                return PSA_TO_MBEDTLS_ERR(status);
            }

            input_offset += length;
        }
    }

    if (input_offset != len) {
        return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
    }

    return 0;
}

int mbedtls_psa_ecjpake_write_round(
    psa_pake_operation_t *pake_ctx,
    unsigned char *buf,
    size_t len, size_t *olen,
    mbedtls_ecjpake_rounds_t round)
{
    psa_status_t status;
    size_t output_offset = 0;
    size_t output_len;
    /*
     * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice
     * At round two perform a single cycle
     */
    unsigned int remaining_steps = (round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1;

    for (; remaining_steps > 0; remaining_steps--) {
        for (psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE;
             step <= PSA_PAKE_STEP_ZK_PROOF;
             ++step) {
            /*
             * For each step, prepend 1 byte with the length of the data as
             * given by psa_pake_output().
             */
            status = psa_pake_output(pake_ctx, step,
                                     buf + output_offset + 1,
                                     len - output_offset - 1,
                                     &output_len);
            if (status != PSA_SUCCESS) {
                return PSA_TO_MBEDTLS_ERR(status);
            }

            *(buf + output_offset) = (uint8_t) output_len;

            output_offset += output_len + 1;
        }
    }

    *olen = output_offset;

    return 0;
}
#endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO

#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
                                           unsigned char *hash, size_t *hashlen,
                                           unsigned char *data, size_t data_len,
                                           mbedtls_md_type_t md_alg)
{
    psa_status_t status;
    psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
    psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(md_alg);

    MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based computation of digest of ServerKeyExchange"));

    if ((status = psa_hash_setup(&hash_operation,
                                 hash_alg)) != PSA_SUCCESS) {
        MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_setup", status);
        goto exit;
    }

    if ((status = psa_hash_update(&hash_operation, ssl->handshake->randbytes,
                                  64)) != PSA_SUCCESS) {
        MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status);
        goto exit;
    }

    if ((status = psa_hash_update(&hash_operation,
                                  data, data_len)) != PSA_SUCCESS) {
        MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status);
        goto exit;
    }

    if ((status = psa_hash_finish(&hash_operation, hash, PSA_HASH_MAX_SIZE,
                                  hashlen)) != PSA_SUCCESS) {
        MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_finish", status);
        goto exit;
    }

exit:
    if (status != PSA_SUCCESS) {
        mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                       MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
        switch (status) {
            case PSA_ERROR_NOT_SUPPORTED:
                return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
            case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
            case PSA_ERROR_BUFFER_TOO_SMALL:
                return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
            case PSA_ERROR_INSUFFICIENT_MEMORY:
                return MBEDTLS_ERR_MD_ALLOC_FAILED;
            default:
                return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
        }
    }
    return 0;
}

#else

int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
                                           unsigned char *hash, size_t *hashlen,
                                           unsigned char *data, size_t data_len,
                                           mbedtls_md_type_t md_alg)
{}
#endif /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)

/* Find the preferred hash for a given signature algorithm. */
unsigned int mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
    mbedtls_ssl_context *ssl,
    unsigned int sig_alg)
{}

#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */

#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */

int mbedtls_ssl_validate_ciphersuite(
    const mbedtls_ssl_context *ssl,
    const mbedtls_ssl_ciphersuite_t *suite_info,
    mbedtls_ssl_protocol_version min_tls_version,
    mbedtls_ssl_protocol_version max_tls_version)
{}

#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
/*
 * Function for writing a signature algorithm extension.
 *
 * The `extension_data` field of signature algorithm contains  a `SignatureSchemeList`
 * value (TLS 1.3 RFC8446):
 *      enum {
 *         ....
 *        ecdsa_secp256r1_sha256( 0x0403 ),
 *        ecdsa_secp384r1_sha384( 0x0503 ),
 *        ecdsa_secp521r1_sha512( 0x0603 ),
 *         ....
 *      } SignatureScheme;
 *
 *      struct {
 *         SignatureScheme supported_signature_algorithms<2..2^16-2>;
 *      } SignatureSchemeList;
 *
 * The `extension_data` field of signature algorithm contains a `SignatureAndHashAlgorithm`
 * value (TLS 1.2 RFC5246):
 *      enum {
 *          none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
 *          sha512(6), (255)
 *      } HashAlgorithm;
 *
 *      enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
 *        SignatureAlgorithm;
 *
 *      struct {
 *          HashAlgorithm hash;
 *          SignatureAlgorithm signature;
 *      } SignatureAndHashAlgorithm;
 *
 *      SignatureAndHashAlgorithm
 *        supported_signature_algorithms<2..2^16-2>;
 *
 * The TLS 1.3 signature algorithm extension was defined to be a compatible
 * generalization of the TLS 1.2 signature algorithm extension.
 * `SignatureAndHashAlgorithm` field of TLS 1.2 can be represented by
 * `SignatureScheme` field of TLS 1.3
 *
 */
int mbedtls_ssl_write_sig_alg_ext(mbedtls_ssl_context *ssl, unsigned char *buf,
                                  const unsigned char *end, size_t *out_len)
{}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */

#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/*
 * mbedtls_ssl_parse_server_name_ext
 *
 * Structure of server_name extension:
 *
 *  enum {
 *        host_name(0), (255)
 *     } NameType;
 *  opaque HostName<1..2^16-1>;
 *
 *  struct {
 *          NameType name_type;
 *          select (name_type) {
 *             case host_name: HostName;
 *           } name;
 *     } ServerName;
 *  struct {
 *          ServerName server_name_list<1..2^16-1>
 *     } ServerNameList;
 */
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_parse_server_name_ext(mbedtls_ssl_context *ssl,
                                      const unsigned char *buf,
                                      const unsigned char *end)
{}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */

#if defined(MBEDTLS_SSL_ALPN)
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_parse_alpn_ext(mbedtls_ssl_context *ssl,
                               const unsigned char *buf,
                               const unsigned char *end)
{}

int mbedtls_ssl_write_alpn_ext(mbedtls_ssl_context *ssl,
                               unsigned char *buf,
                               unsigned char *end,
                               size_t *out_len)
{}
#endif /* MBEDTLS_SSL_ALPN */

#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
    defined(MBEDTLS_SSL_SESSION_TICKETS) && \
    defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
    defined(MBEDTLS_SSL_CLI_C)
int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session,
                                     const char *hostname)
{}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
          MBEDTLS_SSL_SESSION_TICKETS &&
          MBEDTLS_SSL_SERVER_NAME_INDICATION &&
          MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \
    defined(MBEDTLS_SSL_ALPN)
int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session,
                                        const char *alpn)
{
    size_t alpn_len = 0;

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

        if (alpn_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) {
            return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
        }
    }

    if (session->ticket_alpn != NULL) {
        mbedtls_zeroize_and_free(session->ticket_alpn,
                                 strlen(session->ticket_alpn));
        session->ticket_alpn = NULL;
    }

    if (alpn != NULL) {
        session->ticket_alpn = mbedtls_calloc(alpn_len + 1, 1);
        if (session->ticket_alpn == NULL) {
            return MBEDTLS_ERR_SSL_ALLOC_FAILED;
        }
        memcpy(session->ticket_alpn, alpn, alpn_len);
    }

    return 0;
}
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */

/*
 * The following functions are used by 1.2 and 1.3, client and server.
 */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
                                 const mbedtls_ssl_ciphersuite_t *ciphersuite,
                                 int recv_endpoint,
                                 mbedtls_ssl_protocol_version tls_version,
                                 uint32_t *flags)
{}

int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
                                   int authmode,
                                   mbedtls_x509_crt *chain,
                                   const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
                                   void *rs_ctx)
{}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */

#endif /* MBEDTLS_SSL_TLS_C */