#include "common.h"
#if defined(MBEDTLS_SSL_TLS_C)
#include "mbedtls/platform.h"
#include "mbedtls/ssl.h"
#include "ssl_misc.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/version.h"
#include "constant_time_internal.h"
#include "mbedtls/constant_time.h"
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#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)
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_SSL_SOME_SUITES_USE_MAC)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_SHA_384)
#define MAX_HASH_BLOCK_LENGTH …
#elif defined(PSA_WANT_ALG_SHA_256)
#define MAX_HASH_BLOCK_LENGTH …
#else
#define MAX_HASH_BLOCK_LENGTH …
#endif
MBEDTLS_STATIC_TESTABLE
int mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
psa_algorithm_t mac_alg,
const unsigned char *add_data,
size_t add_data_len,
const unsigned char *data,
size_t data_len_secret,
size_t min_data_len,
size_t max_data_len,
unsigned char *output)
{
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(mac_alg);
const size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
unsigned char key_buf[MAX_HASH_BLOCK_LENGTH];
const size_t hash_size = PSA_HASH_LENGTH(hash_alg);
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
size_t hash_length;
unsigned char aux_out[PSA_HASH_MAX_SIZE];
psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT;
size_t offset;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t mac_key_length;
size_t i;
#define PSA_CHK …
PSA_CHK(psa_export_key(key, key_buf, block_size, &mac_key_length));
for (i = 0; i < mac_key_length; i++) {
key_buf[i] = (unsigned char) (key_buf[i] ^ 0x36);
}
for (; i < block_size; ++i) {
key_buf[i] = 0x36;
}
PSA_CHK(psa_hash_setup(&operation, hash_alg));
PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
PSA_CHK(psa_hash_update(&operation, add_data, add_data_len));
PSA_CHK(psa_hash_update(&operation, data, min_data_len));
memset(output, '!', hash_size);
for (offset = min_data_len; offset <= max_data_len; offset++) {
PSA_CHK(psa_hash_clone(&operation, &aux_operation));
PSA_CHK(psa_hash_finish(&aux_operation, aux_out,
PSA_HASH_MAX_SIZE, &hash_length));
mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
output, aux_out, NULL, hash_size);
if (offset < max_data_len) {
PSA_CHK(psa_hash_update(&operation, data + offset, 1));
}
}
PSA_CHK(psa_hash_abort(&operation));
for (i = 0; i < mac_key_length; i++) {
key_buf[i] = (unsigned char) ((key_buf[i] ^ 0x36) ^ 0x5C);
}
for (; i < block_size; ++i) {
key_buf[i] = 0x5C;
}
PSA_CHK(psa_hash_setup(&operation, hash_alg));
PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
PSA_CHK(psa_hash_update(&operation, output, hash_size));
PSA_CHK(psa_hash_finish(&operation, output, hash_size, &hash_length));
#undef PSA_CHK
cleanup:
mbedtls_platform_zeroize(key_buf, MAX_HASH_BLOCK_LENGTH);
mbedtls_platform_zeroize(aux_out, PSA_HASH_MAX_SIZE);
psa_hash_abort(&operation);
psa_hash_abort(&aux_operation);
return PSA_TO_MBEDTLS_ERR(status);
}
#undef MAX_HASH_BLOCK_LENGTH
#else
MBEDTLS_STATIC_TESTABLE
int mbedtls_ct_hmac(mbedtls_md_context_t *ctx,
const unsigned char *add_data,
size_t add_data_len,
const unsigned char *data,
size_t data_len_secret,
size_t min_data_len,
size_t max_data_len,
unsigned char *output)
{ … }
#endif
#endif
static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl);
void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs)
{ … }
int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t len,
mbedtls_record *rec);
int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t buflen)
{ … }
#define SSL_DONT_FORCE_FLUSH …
#define SSL_FORCE_FLUSH …
#if defined(MBEDTLS_SSL_PROTO_DTLS)
static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
uint8_t slot);
static void ssl_free_buffered_record(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_message(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_record(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_message(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
mbedtls_record const *rec);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl);
static size_t ssl_get_maximum_datagram_size(mbedtls_ssl_context const *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_double_retransmit_timeout(mbedtls_ssl_context *ssl)
{ … }
static void ssl_reset_retransmit_timeout(mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
static size_t ssl_compute_padding_length(size_t len,
size_t granularity)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_build_inner_plaintext(unsigned char *content,
size_t *content_size,
size_t remaining,
uint8_t rec_type,
size_t pad)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_inner_plaintext(unsigned char const *content,
size_t *content_size,
uint8_t *rec_type)
{ … }
#endif
static void ssl_extract_add_data_from_record(unsigned char *add_data,
size_t *add_data_len,
mbedtls_record *rec,
mbedtls_ssl_protocol_version
tls_version,
size_t taglen)
{ … }
#if defined(MBEDTLS_SSL_HAVE_AEAD)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_transform_aead_dynamic_iv_is_explicit(
mbedtls_ssl_transform const *transform)
{ … }
static void ssl_build_record_nonce(unsigned char *dst_iv,
size_t dst_iv_len,
unsigned char const *fixed_iv,
size_t fixed_iv_len,
unsigned char const *dynamic_iv,
size_t dynamic_iv_len)
{ … }
#endif
int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform,
mbedtls_record *rec,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{ … }
int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl,
mbedtls_ssl_transform *transform,
mbedtls_record *rec)
{ … }
#undef MAC_NONE
#undef MAC_PLAINTEXT
#undef MAC_CIPHERTEXT
int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want)
{ … }
int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_flight_append(mbedtls_ssl_context *ssl)
{ … }
void mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_swap_epochs(mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_resend(mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl)
{ … }
void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl)
{ … }
void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl)
{ … }
#endif
int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type,
unsigned char **buf, size_t *buf_len)
{ … }
int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl,
int update_checksum,
int force_flush)
{ … }
int mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context *ssl,
size_t buf_len, size_t msg_len)
{ … }
int mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, int force_flush)
{ … }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_hs_is_proper_fragment(mbedtls_ssl_context *ssl)
{ … }
static uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl)
{ … }
static uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_hs_header(mbedtls_ssl_context const *ssl)
{ … }
static void ssl_bitmask_set(unsigned char *mask, size_t offset, size_t len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_bitmask_check(unsigned char *mask, size_t len)
{ … }
static size_t ssl_get_reassembly_buffer_size(size_t msg_len,
unsigned add_bitmap)
{ … }
#endif
static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
{ … }
int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
void mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl)
{ … }
static inline uint64_t ssl_load_six_bytes(unsigned char *buf)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context *ssl, uint8_t *record_in_ctr)
{ … }
int mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl)
{ … }
void mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
MBEDTLS_CHECK_RETURN_CRITICAL
MBEDTLS_STATIC_TESTABLE
int mbedtls_ssl_check_dtls_clihlo_cookie(
mbedtls_ssl_context *ssl,
const unsigned char *cli_id, size_t cli_id_len,
const unsigned char *in, size_t in_len,
unsigned char *obuf, size_t buf_len, size_t *olen)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_handle_possible_reconnect(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_record_type(uint8_t record_type)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t len,
mbedtls_record *rec)
{ … }
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_client_reconnect(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
mbedtls_record *rec)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_consume_current_message(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_next_record(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl);
int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl,
unsigned update_hs_digest)
{ … }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_message(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_make_space(mbedtls_ssl_context *ssl,
size_t desired)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_message(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
static void ssl_free_buffered_record(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_record(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
mbedtls_record const *rec)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_next_record(mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl,
unsigned char level,
unsigned char message)
{ … }
int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl)
{ … }
static size_t ssl_transform_get_explicit_iv_len(
mbedtls_ssl_transform const *transform)
{ … }
void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform)
{ … }
void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
{ … }
void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl)
{ … }
size_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl)
{ … }
int mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_SSL_RENEGOTIATION)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_SSL_CLI_C)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_is_new_session_ticket(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
{ … }
static int ssl_read_application_data(
mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{ … }
int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{ … }
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len)
{
if (ssl == NULL || (ssl->conf == NULL)) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
(ssl->in_offt == NULL)) {
return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
}
return ssl_read_application_data(ssl, buf, len);
}
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_real(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{ … }
int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len)
{ … }
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const struct mbedtls_ssl_config *conf;
uint32_t remaining;
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data"));
if (ssl == NULL || (conf = ssl->conf) == NULL) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
if (conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) ||
(conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
(conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) {
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
}
if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
}
if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
(ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
(ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
ret = mbedtls_ssl_handshake_step(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret);
return ret;
}
ret = mbedtls_ssl_flush_output(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
return ret;
}
}
remaining = ssl->session_negotiate->max_early_data_size;
} else {
if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
(ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) {
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
}
remaining = ssl->session_negotiate->max_early_data_size -
ssl->total_early_data_size;
if (remaining == 0) {
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
}
ret = mbedtls_ssl_handshake(ssl);
if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
return ret;
}
}
if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
(ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED))
|| (remaining == 0)) {
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
}
if (len > remaining) {
len = remaining;
}
ret = ssl_write_real(ssl, buf, len);
if (ret >= 0) {
ssl->total_early_data_size += ret;
}
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret));
return ret;
}
#endif
int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl)
{ … }
void mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform)
{ … }
void mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform)
{ … }
void mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform)
{ … }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
void mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl)
{ … }
static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
uint8_t slot)
{ … }
#endif
void mbedtls_ssl_write_version(unsigned char version[2], int transport,
mbedtls_ssl_protocol_version tls_version)
{ … }
uint16_t mbedtls_ssl_read_version(const unsigned char version[2],
int transport)
{ … }
int mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context *ssl)
{ … }
void mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context *ssl,
unsigned char alert_type,
int alert_reason)
{ … }
#endif