mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-07-30 16:26:33 +08:00
Resume asynchronous TLS 1.3 handshake operations
Signed-off-by: Cal Abel <crabel@mac.com>
This commit is contained in:
parent
7816ed7e36
commit
7016e506de
@ -724,6 +724,8 @@ struct mbedtls_ssl_handshake_params {
|
||||
ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */
|
||||
ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */
|
||||
ssl_ecrs_ske_sign, /*!< ServerKeyExchange: pk_sign() */
|
||||
ssl_ecrs_tls13_server_hello_finalize, /*!< ServerHello: key schedule */
|
||||
ssl_ecrs_tls13_server_hello_postprocess, /*!< ServerHello: peer key schedule */
|
||||
ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */
|
||||
ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */
|
||||
} ecrs_state; /*!< current (or last) operation */
|
||||
|
||||
@ -970,12 +970,22 @@ int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl,
|
||||
size_t padding =
|
||||
ssl_compute_padding_length(rec->data_len,
|
||||
MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
|
||||
if (ssl_build_inner_plaintext(data,
|
||||
&rec->data_len,
|
||||
post_avail,
|
||||
rec->type,
|
||||
padding) != 0) {
|
||||
return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
if (transform->async_hardware_aead_pending != 0) {
|
||||
if (post_avail < padding + 1) {
|
||||
return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
|
||||
}
|
||||
rec->data_len += padding + 1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (ssl_build_inner_plaintext(data,
|
||||
&rec->data_len,
|
||||
post_avail,
|
||||
rec->type,
|
||||
padding) != 0) {
|
||||
return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
|
||||
}
|
||||
}
|
||||
|
||||
rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
|
||||
|
||||
@ -1859,6 +1859,13 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (handshake->ecrs_state ==
|
||||
ssl_ecrs_tls13_server_hello_postprocess) {
|
||||
goto compute_handshake_transform;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Determine the key exchange mode:
|
||||
* 1) If both the pre_shared_key and key_share extensions were received
|
||||
* then the key exchange mode is PSK with EPHEMERAL.
|
||||
@ -1932,7 +1939,16 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
}
|
||||
|
||||
compute_handshake_transform:
|
||||
ret = mbedtls_ssl_tls13_compute_handshake_transform(ssl);
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
|
||||
ssl->handshake->ecrs_state =
|
||||
ssl_ecrs_tls13_server_hello_postprocess;
|
||||
goto cleanup;
|
||||
}
|
||||
ssl->handshake->ecrs_state = ssl_ecrs_none;
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
"mbedtls_ssl_tls13_compute_handshake_transform",
|
||||
@ -1945,7 +1961,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
||||
ssl->session_in = ssl->session_negotiate;
|
||||
|
||||
cleanup:
|
||||
if (ret != 0) {
|
||||
if (ret != 0 && ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
@ -1997,6 +2013,18 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> %s", __func__));
|
||||
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (ssl->handshake->ecrs_state ==
|
||||
ssl_ecrs_tls13_server_hello_postprocess) {
|
||||
ret = ssl_tls13_postprocess_server_hello(ssl);
|
||||
if (ret == 0) {
|
||||
mbedtls_ssl_handshake_set_state(
|
||||
ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len));
|
||||
|
||||
@ -2628,18 +2656,46 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
|
||||
/*
|
||||
* Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE
|
||||
*/
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
static int ssl_tls13_resume_pending_record(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
if (ssl->transform_out == NULL ||
|
||||
ssl->transform_out->async_hardware_aead_pending == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = mbedtls_ssl_write_record(ssl, 1);
|
||||
return ret == 0 ? 1 : ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_write_client_certificate(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int non_empty_certificate_msg = 0;
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD) || \
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
("Switch to handshake traffic keys for outbound traffic"));
|
||||
mbedtls_ssl_set_outbound_transform(ssl, ssl->handshake->transform_handshake);
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
ret = ssl_tls13_resume_pending_record(ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret > 0) {
|
||||
non_empty_certificate_msg = mbedtls_ssl_own_cert(ssl) != NULL;
|
||||
goto client_certificate_written;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
if (ssl->handshake->client_auth) {
|
||||
int ret = mbedtls_ssl_tls13_write_certificate(ssl);
|
||||
ret = mbedtls_ssl_tls13_write_certificate(ssl);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -2652,6 +2708,9 @@ static int ssl_tls13_write_client_certificate(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
client_certificate_written:
|
||||
#endif
|
||||
if (non_empty_certificate_msg) {
|
||||
mbedtls_ssl_handshake_set_state(ssl,
|
||||
MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY);
|
||||
@ -2670,8 +2729,22 @@ static int ssl_tls13_write_client_certificate(mbedtls_ssl_context *ssl)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_write_client_certificate_verify(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret = mbedtls_ssl_tls13_write_certificate_verify(ssl);
|
||||
int ret;
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
ret = ssl_tls13_resume_pending_record(ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
goto client_certificate_verify_written;
|
||||
}
|
||||
#endif
|
||||
ret = mbedtls_ssl_tls13_write_certificate_verify(ssl);
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
client_certificate_verify_written:
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED);
|
||||
}
|
||||
@ -2688,11 +2761,25 @@ static int ssl_tls13_write_client_finished(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
ret = ssl_tls13_resume_pending_record(ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
goto client_finished_written;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = mbedtls_ssl_tls13_write_finished_message(ssl);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
client_finished_written:
|
||||
#endif
|
||||
ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
|
||||
@ -2410,6 +2410,12 @@ static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl)
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello"));
|
||||
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (ssl->handshake->ecrs_state == ssl_ecrs_tls13_server_hello_finalize) {
|
||||
goto finalize_server_hello;
|
||||
}
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_prepare_server_hello(ssl));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
@ -2426,7 +2432,20 @@ static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl)
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_finalize_server_hello(ssl));
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
finalize_server_hello:
|
||||
#endif
|
||||
ret = ssl_tls13_finalize_server_hello(ssl);
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
|
||||
ssl->handshake->ecrs_state = ssl_ecrs_tls13_server_hello_finalize;
|
||||
goto cleanup;
|
||||
}
|
||||
ssl->handshake->ecrs_state = ssl_ecrs_none;
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
|
||||
/* The server sends a dummy change_cipher_spec record immediately
|
||||
@ -2522,6 +2541,19 @@ cleanup:
|
||||
* Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
static int ssl_tls13_resume_pending_record(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
if (ssl->transform_out == NULL ||
|
||||
ssl->transform_out->async_hardware_aead_pending == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = mbedtls_ssl_write_record(ssl, 1);
|
||||
return ret == 0 ? 1 : ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* struct {
|
||||
* Extension extensions<0..2 ^ 16 - 1>;
|
||||
@ -2607,6 +2639,17 @@ static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl)
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write encrypted extensions"));
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
ret = ssl_tls13_resume_pending_record(ssl);
|
||||
if (ret < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
goto encrypted_extensions_written;
|
||||
}
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
&buf, &buf_len));
|
||||
@ -2621,6 +2664,9 @@ static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl)
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len));
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
encrypted_extensions_written:
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
|
||||
@ -2781,6 +2827,17 @@ static int ssl_tls13_write_server_certificate(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
ret = ssl_tls13_resume_pending_record(ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
goto server_certificate_written;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
if ((ssl_tls13_pick_key_cert(ssl) != 0) ||
|
||||
mbedtls_ssl_own_cert(ssl) == NULL) {
|
||||
@ -2795,6 +2852,9 @@ static int ssl_tls13_write_server_certificate(mbedtls_ssl_context *ssl)
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
server_certificate_written:
|
||||
#endif
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY);
|
||||
return 0;
|
||||
}
|
||||
@ -2805,10 +2865,24 @@ 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)
|
||||
{
|
||||
int ret = mbedtls_ssl_tls13_write_certificate_verify(ssl);
|
||||
int ret;
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
ret = ssl_tls13_resume_pending_record(ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
goto certificate_verify_written;
|
||||
}
|
||||
#endif
|
||||
ret = mbedtls_ssl_tls13_write_certificate_verify(ssl);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
certificate_verify_written:
|
||||
#endif
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
|
||||
return 0;
|
||||
}
|
||||
@ -2875,11 +2949,25 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
ret = ssl_tls13_resume_pending_record(ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
goto server_finished_written;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = mbedtls_ssl_tls13_write_finished_message(ssl);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
server_finished_written:
|
||||
#endif
|
||||
ret = mbedtls_ssl_tls13_compute_application_transform(ssl);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user