#include "common.h"
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
#include "mbedtls/oid.h"
#include "mbedtls/psa_util.h"
#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
#include "ssl_debug_helpers.h"
static const mbedtls_ssl_ciphersuite_t *ssl_tls13_validate_peer_ciphersuite(
mbedtls_ssl_context *ssl,
unsigned int cipher_suite)
{ … }
static void ssl_tls13_select_ciphersuite(
mbedtls_ssl_context *ssl,
const unsigned char *cipher_suites,
const unsigned char *cipher_suites_end,
int psk_ciphersuite_id,
psa_algorithm_t psk_hash_alg,
const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
{ … }
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end)
{ … }
#define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH …
#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE …
#define SSL_TLS1_3_PSK_IDENTITY_MATCH …
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_identity_match_ticket(
mbedtls_ssl_context *ssl,
const unsigned char *identity,
size_t identity_len,
uint32_t obfuscated_ticket_age,
mbedtls_ssl_session *session)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_identity_match(
mbedtls_ssl_context *ssl,
const unsigned char *identity,
size_t identity_len,
uint32_t obfuscated_ticket_age,
int *psk_type,
mbedtls_ssl_session *session)
{ … }
#define SSL_TLS1_3_BINDER_DOES_NOT_MATCH …
#define SSL_TLS1_3_BINDER_MATCH …
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_binder_match(
mbedtls_ssl_context *ssl,
const unsigned char *binder, size_t binder_len,
int psk_type, psa_algorithm_t psk_hash_alg)
{ … }
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst,
const mbedtls_ssl_session *src)
{ … }
#endif
struct psk_attributes { … };
#define PSK_ATTRIBUTES_INIT …
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_pre_shared_key_ext(
mbedtls_ssl_context *ssl,
const unsigned char *pre_shared_key_ext,
const unsigned char *pre_shared_key_ext_end,
const unsigned char *ciphersuites,
const unsigned char *ciphersuites_end,
struct psk_attributes *psk)
{ … }
static int ssl_tls13_write_server_pre_shared_key_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *olen)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end)
{ … }
#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end)
{ … }
#endif
#define SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH …
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts(mbedtls_ssl_context *ssl,
int exts_mask)
{ … }
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(
mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_key_exchange(
mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(
mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_exchange_is_ephemeral_available(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
static psa_algorithm_t ssl_tls13_iana_sig_alg_to_psa_alg(uint16_t sig_alg)
{
switch (sig_alg) {
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
return PSA_ALG_ECDSA(PSA_ALG_SHA_256);
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
return PSA_ALG_ECDSA(PSA_ALG_SHA_384);
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
return PSA_ALG_ECDSA(PSA_ALG_SHA_512);
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
return PSA_ALG_RSA_PSS(PSA_ALG_SHA_256);
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
return PSA_ALG_RSA_PSS(PSA_ALG_SHA_384);
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
return PSA_ALG_RSA_PSS(PSA_ALG_SHA_512);
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256);
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_384);
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512);
default:
return PSA_ALG_NONE;
}
}
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_pick_key_cert(mbedtls_ssl_context *ssl)
{ … }
#endif
#define SSL_CLIENT_HELLO_OK …
#define SSL_CLIENT_HELLO_HRR_REQUIRED …
#define SSL_CLIENT_HELLO_TLS1_2 …
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end)
{ … }
#if defined(MBEDTLS_SSL_EARLY_DATA)
static int ssl_tls13_check_early_data_requirements(mbedtls_ssl_context *ssl)
{
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG(
1,
("EarlyData: rejected, feature disabled in server configuration."));
return -1;
}
if (!handshake->resume) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, not a session resumption."));
return -1;
}
if (handshake->selected_identity != 0) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected key in "
"`pre_shared_key` is not the first one."));
return -1;
}
if (handshake->ciphersuite_info->id !=
ssl->session_negotiate->ciphersuite) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected ciphersuite is not the one "
"of the selected pre-shared key."));
return -1;
}
if (!mbedtls_ssl_tls13_session_ticket_allow_early_data(ssl->session_negotiate)) {
MBEDTLS_SSL_DEBUG_MSG(
1,
("EarlyData: rejected, early_data not allowed in ticket "
"permission bits."));
return -1;
}
#if defined(MBEDTLS_SSL_ALPN)
const char *alpn = mbedtls_ssl_get_alpn_protocol(ssl);
size_t alpn_len;
if (alpn == NULL && ssl->session_negotiate->ticket_alpn == NULL) {
return 0;
}
if (alpn != NULL) {
alpn_len = strlen(alpn);
}
if (alpn == NULL ||
ssl->session_negotiate->ticket_alpn == NULL ||
alpn_len != strlen(ssl->session_negotiate->ticket_alpn) ||
(memcmp(alpn, ssl->session_negotiate->ticket_alpn, alpn_len) != 0)) {
MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, the selected ALPN is different "
"from the one associated with the pre-shared key."));
return -1;
}
#endif
return 0;
}
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
int hrr_required)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_prepare_server_hello(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_hello_supported_versions_ext(
mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *out_len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_generate_and_write_key_share(mbedtls_ssl_context *ssl,
uint16_t named_group,
unsigned char *buf,
unsigned char *end,
size_t *out_len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *out_len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_hrr_key_share_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *out_len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_hello_body(mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *out_len,
int is_hrr)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_finalize_server_hello(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_prepare_hello_retry_request(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_hello_retry_request(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *out_len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
#define SSL_CERTIFICATE_REQUEST_SEND_REQUEST …
#define SSL_CERTIFICATE_REQUEST_SKIP …
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_certificate_request_coordinate(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_certificate_request_body(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_certificate_request(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_certificate(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl)
{ … }
#endif
static void ssl_tls13_prepare_for_handshake_second_flight(
mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define SSL_GOT_END_OF_EARLY_DATA …
#define SSL_GOT_EARLY_DATA …
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
return ret;
}
ssl->keep_current_message = 1;
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
ssl->in_msg[0] == MBEDTLS_SSL_HS_END_OF_EARLY_DATA) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Received an end_of_early_data message."));
return SSL_GOT_END_OF_EARLY_DATA;
}
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
if (ssl->in_offt == NULL) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
ssl->in_offt = ssl->in_msg;
ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen);
if (ret != 0) {
return ret;
}
}
return SSL_GOT_EARLY_DATA;
}
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end)
{
if (buf != end) {
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
MBEDTLS_ERR_SSL_DECODE_ERROR);
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
return 0;
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_process_end_of_early_data"));
MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_end_of_early_data_coordinate(ssl));
if (ret == SSL_GOT_END_OF_EARLY_DATA) {
unsigned char *buf;
size_t buf_len;
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA,
&buf, &buf_len));
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data(
ssl, buf, buf + buf_len));
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to handshake keys for inbound traffic"
"( K_recv = handshake )"));
mbedtls_ssl_set_inbound_transform(
ssl, ssl->handshake->transform_handshake);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA,
buf, buf_len));
ssl_tls13_prepare_for_handshake_second_flight(ssl);
} else if (ret == SSL_GOT_EARLY_DATA) {
ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA;
goto cleanup;
} else {
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto cleanup;
}
cleanup:
MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_process_end_of_early_data"));
return ret;
}
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_client_finished(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
#define SSL_NEW_SESSION_TICKET_SKIP …
#define SSL_NEW_SESSION_TICKET_WRITE …
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_new_session_ticket_coordinate(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
unsigned char *ticket_nonce,
size_t ticket_nonce_size)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *out_len,
unsigned char *ticket_nonce,
size_t ticket_nonce_size)
{ … }
static int ssl_tls13_write_new_session_ticket(mbedtls_ssl_context *ssl)
{ … }
#endif
int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl)
{ … }
#endif