1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-29 11:41:15 +03:00

Merge remote-tracking branch 'development' into ecp-write-ext-3.6

Conflicts:
* library/pk.c: mbedtls_pk_wrap_as_opaque() changed in the feature branch
  and was removed in the target branch.
This commit is contained in:
Gilles Peskine
2024-03-04 08:52:08 +01:00
22 changed files with 1046 additions and 458 deletions

View File

@ -1182,9 +1182,32 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
}
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t psa_alg, psa_enrollment_alg, sign_alg;
psa_status_t status;
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
status = psa_get_key_attributes(ctx->priv_id, &key_attr);
if (status != PSA_SUCCESS) {
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
}
psa_alg = psa_get_key_algorithm(&key_attr);
psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
psa_reset_key_attributes(&key_attr);
/* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
* alg and enrollment alg should be of type RSA_PSS. */
if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
sign_alg = psa_alg;
} else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
sign_alg = psa_enrollment_alg;
} else {
/* The opaque key has no RSA PSS algorithm associated. */
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* Adjust the hashing algorithm. */
sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
status = psa_sign_hash(ctx->priv_id, sign_alg,
hash, hash_len,
sig, sig_size, sig_len);
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
@ -1351,123 +1374,4 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
return ctx->pk_info->type;
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* Load the key to a PSA key slot,
* then turn the PK context into a wrapper for that key slot.
*
* Currently only works for EC & RSA private keys.
*/
int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
mbedtls_svc_key_id_t *key,
psa_algorithm_t alg,
psa_key_usage_t usage,
psa_algorithm_t alg2)
{
#if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_RSA_C)
((void) pk);
((void) key);
((void) alg);
((void) usage);
((void) alg2);
#else /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
size_t d_len;
psa_ecc_family_t curve_id;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t key_type;
size_t bits;
psa_status_t status;
/* export the private key material in the format PSA wants */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len);
if (status != PSA_SUCCESS) {
return psa_pk_status_to_mbedtls(status);
}
curve_id = pk->ec_family;
bits = pk->ec_bits;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_ecp_write_key_ext(ec, &d_len, d, sizeof(d))) != 0) {
return ret;
}
curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
/* prepare the key attributes */
psa_set_key_type(&attributes, key_type);
psa_set_key_bits(&attributes, bits);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, alg);
if (alg2 != PSA_ALG_NONE) {
psa_set_key_enrollment_algorithm(&attributes, alg2);
}
/* import private key into PSA */
status = psa_import_key(&attributes, d, d_len, key);
mbedtls_platform_zeroize(d, sizeof(d));
if (status != PSA_SUCCESS) {
return PSA_PK_TO_MBEDTLS_ERR(status);
}
/* make PK context wrap the key slot */
mbedtls_pk_free(pk);
mbedtls_pk_init(pk);
return mbedtls_pk_setup_opaque(pk, *key);
} else
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) {
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
int key_len;
psa_status_t status;
/* export the private key material in the format PSA wants */
key_len = mbedtls_pk_write_key_der(pk, buf, sizeof(buf));
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* prepare the key attributes */
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
psa_set_key_bits(&attributes, mbedtls_pk_get_bitlen(pk));
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, alg);
if (alg2 != PSA_ALG_NONE) {
psa_set_key_enrollment_algorithm(&attributes, alg2);
}
/* import private key into PSA */
status = psa_import_key(&attributes,
buf + sizeof(buf) - key_len,
key_len, key);
mbedtls_platform_zeroize(buf, sizeof(buf));
if (status != PSA_SUCCESS) {
return PSA_PK_TO_MBEDTLS_ERR(status);
}
/* make PK context wrap the key slot */
mbedtls_pk_free(pk);
mbedtls_pk_init(pk);
return mbedtls_pk_setup_opaque(pk, *key);
} else
#endif /* MBEDTLS_RSA_C */
#endif /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PK_C */

View File

@ -21,6 +21,10 @@
const char *mbedtls_ssl_states_str(mbedtls_ssl_states in);
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
const char *mbedtls_ssl_early_data_status_str(mbedtls_ssl_early_data_status in);
#endif
const char *mbedtls_ssl_protocol_version_str(mbedtls_ssl_protocol_version in);
const char *mbedtls_tls_prf_types_str(mbedtls_tls_prf_types in);

View File

@ -665,21 +665,21 @@ struct mbedtls_ssl_handshake_params {
#if defined(MBEDTLS_SSL_CLI_C)
/** Minimum TLS version to be negotiated.
*
* It is set up in the ClientHello writing preparation stage and used
* throughout the ClientHello writing. Not relevant anymore as soon as
* the protocol version has been negotiated thus as soon as the
* ServerHello is received.
* For a fresh handshake not linked to any previous handshake, it is
* equal to the configured minimum minor version to be negotiated. When
* renegotiating or resuming a session, it is equal to the previously
* negotiated minor version.
* It is set up in the ClientHello writing preparation stage and used
* throughout the ClientHello writing. Not relevant anymore as soon as
* the protocol version has been negotiated thus as soon as the
* ServerHello is received.
* For a fresh handshake not linked to any previous handshake, it is
* equal to the configured minimum minor version to be negotiated. When
* renegotiating or resuming a session, it is equal to the previously
* negotiated minor version.
*
* There is no maximum TLS version field in this handshake context.
* From the start of the handshake, we need to define a current protocol
* version for the record layer which we define as the maximum TLS
* version to be negotiated. The `tls_version` field of the SSL context is
* used to store this maximum value until it contains the actual
* negotiated value.
* There is no maximum TLS version field in this handshake context.
* From the start of the handshake, we need to define a current protocol
* version for the record layer which we define as the maximum TLS
* version to be negotiated. The `tls_version` field of the SSL context is
* used to store this maximum value until it contains the actual
* negotiated value.
*/
mbedtls_ssl_protocol_version min_tls_version;
#endif
@ -730,16 +730,21 @@ struct mbedtls_ssl_handshake_params {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
uint8_t key_exchange_mode; /*!< Selected key exchange mode */
/** Number of HelloRetryRequest messages received/sent from/to the server. */
uint8_t hello_retry_request_count;
/**
* Flag indicating if, in the course of the current handshake, an
* HelloRetryRequest message has been sent by the server or received by
* the client (<> 0) or not (0).
*/
uint8_t hello_retry_request_flag;
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
/**
* Number of dummy change_cipher_spec (CCS) record sent. Used to send only
* one CCS per handshake without having to complicate the handshake state
* transitions.
* Flag indicating if, in the course of the current handshake, a dummy
* change_cipher_spec (CCS) record has already been sent. Used to send only
* one CCS per handshake while not complicating the handshake state
* transitions for that purpose.
*/
uint8_t ccs_count;
uint8_t ccs_sent;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
@ -2145,38 +2150,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len);
#if defined(MBEDTLS_SSL_CLI_C)
/*
* The client has not sent the first ClientHello yet, it is unknown if the
* client will send an early data indication extension or not.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0
/*
* The client has sent an early data indication extension in its first
* ClientHello, it has not received the response (ServerHello or
* HelloRetryRequest) from the server yet. The transform to protect early data
* is not set and early data cannot be sent yet.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SENT 4
/*
* The client has sent an early data indication extension in its first
* ClientHello, it has not received the response (ServerHello or
* HelloRetryRequest) from the server yet. The transform to protect early data
* has been set and early data can be written now.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE 5
/*
* The client has sent an early data indication extension in its first
* ClientHello, the server has accepted them and the client has received the
* server Finished message. It cannot send early data to the server anymore.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED 6
#endif /* MBEDTLS_SSL_CLI_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View File

@ -6058,6 +6058,94 @@ int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t
return ret;
}
#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;
int written_data_len = 0;
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 we are at the beginning of the handshake, the early data status being
* equal to MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN or
* MBEDTLS_SSL_EARLY_DATA_STATUS_SENT advance the handshake just
* enough to be able to send early data if possible. That way, we can
* guarantee that when starting the handshake with this function we will
* send at least one record of early data. Note that when the status is
* MBEDTLS_SSL_EARLY_DATA_STATUS_SENT and not yet
* MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE, we cannot send early data yet
* as the early data outbound transform has not been set as we may have to
* first send a dummy CCS in clear.
*/
if ((ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) ||
(ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT)) {
while ((ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) ||
(ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_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;
}
}
} else {
/*
* If we are past the point where we can send early data, return
* immediatly. Otherwise, progress the handshake as much as possible to
* not delay it too much. If we reach a point where we can still send
* early data, then we will send some.
*/
if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) &&
(ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) {
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_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) &&
(ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) {
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
}
written_data_len = ssl_write_real(ssl, buf, len);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, len=%d", written_data_len));
return written_data_len;
}
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
/*
* Notify the peer that the connection is being closed
*/

View File

@ -1180,7 +1180,15 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->handshake->hello_retry_request_count == 0) {
/* In the first ClientHello, write the early data indication extension if
* necessary and update the early data status.
* If an HRR has been received and thus we are currently writing the
* second ClientHello, the second ClientHello must not contain an early
* data extension and the early data status must stay as it is:
* MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT or
* MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED.
*/
if (!ssl->handshake->hello_retry_request_flag) {
if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
ssl_tls13_early_data_has_valid_ticket(ssl) &&
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
@ -1495,7 +1503,7 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
* to a HelloRetryRequest), it MUST abort the handshake with an
* "unexpected_message" alert.
*/
if (handshake->hello_retry_request_count > 0) {
if (handshake->hello_retry_request_flag) {
MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
@ -1517,7 +1525,7 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
handshake->hello_retry_request_count++;
handshake->hello_retry_request_flag = 1;
break;
}
@ -1672,7 +1680,7 @@ static int ssl_tls13_parse_server_hello(mbedtls_ssl_context *ssl,
* proposed in the HRR, we abort the handshake and send an
* "illegal_parameter" alert.
*/
else if ((!is_hrr) && (handshake->hello_retry_request_count > 0) &&
else if ((!is_hrr) && handshake->hello_retry_request_flag &&
(cipher_suite != ssl->session_negotiate->ciphersuite)) {
fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
}
@ -2270,6 +2278,7 @@ cleanup:
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
/*
* Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
*
@ -2308,6 +2317,32 @@ cleanup:
return ret;
}
int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl)
{
if ((ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) ||
(!mbedtls_ssl_is_handshake_over(ssl))) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
switch (ssl->early_data_status) {
case MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT:
return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
break;
case MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED:
return MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
break;
case MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED:
return MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
break;
default:
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
/*
* STATE HANDLING: CertificateRequest
@ -3030,9 +3065,11 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
ret = ssl_tls13_process_server_finished(ssl);
break;
#if defined(MBEDTLS_SSL_EARLY_DATA)
case MBEDTLS_SSL_END_OF_EARLY_DATA:
ret = ssl_tls13_write_end_of_early_data(ssl);
break;
#endif
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
ret = ssl_tls13_write_client_certificate(ssl);
@ -3061,23 +3098,17 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
*/
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
ret = 0;
if (ssl->handshake->ccs_count == 0) {
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
break;
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
ret = 0;
if (ssl->handshake->ccs_count == 0) {
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
break;

View File

@ -1379,6 +1379,12 @@ int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec"));
/* Only one CCS to send. */
if (ssl->handshake->ccs_sent) {
ret = 0;
goto cleanup;
}
/* Write CCS message */
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_change_cipher_spec_body(
ssl, ssl->out_msg,
@ -1390,7 +1396,7 @@ int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl)
/* Dispatch message */
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_record(ssl, 0));
ssl->handshake->ccs_count++;
ssl->handshake->ccs_sent = 1;
cleanup:

View File

@ -1531,7 +1531,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
const unsigned char *extension_data_end;
uint32_t allowed_exts = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH;
if (ssl->handshake->hello_retry_request_count > 0) {
if (ssl->handshake->hello_retry_request_flag) {
/* Do not accept early data extension in 2nd ClientHello */
allowed_exts &= ~MBEDTLS_SSL_EXT_MASK(EARLY_DATA);
}
@ -2427,7 +2427,7 @@ MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_prepare_hello_retry_request(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if (ssl->handshake->hello_retry_request_count > 0) {
if (ssl->handshake->hello_retry_request_flag) {
MBEDTLS_SSL_DEBUG_MSG(1, ("Too many HRRs"));
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
@ -2474,7 +2474,7 @@ static int ssl_tls13_write_hello_retry_request(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl, buf_len,
msg_len));
ssl->handshake->hello_retry_request_count++;
ssl->handshake->hello_retry_request_flag = 1;
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
/* The server sends a dummy change_cipher_spec record immediately
@ -3477,12 +3477,9 @@ int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl)
break;
case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO:
ret = 0;
if (ssl->handshake->ccs_count == 0) {
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
break;