Merge pull request #8692 from ronald-cron-arm/read-early-data

TLS 1.3: SRV: Implement mbedtls_ssl_read_early_data()
This commit is contained in:
Ronald Cron 2024-02-02 14:07:47 +00:00 committed by GitHub
commit b90e695e09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 251 additions and 158 deletions

View File

@ -90,8 +90,18 @@
#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00 #define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00
/** Not possible to read early data */ /** Not possible to read early data */
#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80 #define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80
/**
* Early data has been received as part of an on-going handshake.
* This error code can be returned only on server side if and only if early
* data has been enabled by means of the mbedtls_ssl_conf_early_data() API.
* This error code can then be returned by mbedtls_ssl_handshake(),
* mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write() if
* early data has been received as part of the handshake sequence they
* triggered. To read the early data, call mbedtls_ssl_read_early_data().
*/
#define MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA -0x7C00
/** Not possible to write early data */ /** Not possible to write early data */
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C00 #define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C80
/* Error space gap */ /* Error space gap */
/* Error space gap */ /* Error space gap */
/* Error space gap */ /* Error space gap */
@ -1644,6 +1654,18 @@ struct mbedtls_ssl_context {
*/ */
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version); mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
/**
* Status of the negotiation of the use of early data.
* See the documentation of mbedtls_ssl_get_early_data_status() for more
* information.
*
* Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT when the context is
* reset.
*/
int MBEDTLS_PRIVATE(early_data_status);
#endif
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -1841,10 +1863,6 @@ struct mbedtls_ssl_context {
* and #MBEDTLS_SSL_CID_DISABLED. */ * and #MBEDTLS_SSL_CID_DISABLED. */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int MBEDTLS_PRIVATE(early_data_status);
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
/** Callback to export key block and master secret */ /** Callback to export key block and master secret */
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */
@ -1993,7 +2011,7 @@ void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport);
*/ */
void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode); void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
/** /**
* \brief Set the early data mode * \brief Set the early data mode
* Default: disabled on server and client * Default: disabled on server and client
@ -2001,14 +2019,24 @@ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
* \param conf The SSL configuration to use. * \param conf The SSL configuration to use.
* \param early_data_enabled can be: * \param early_data_enabled can be:
* *
* MBEDTLS_SSL_EARLY_DATA_DISABLED: early data functionality is disabled * MBEDTLS_SSL_EARLY_DATA_DISABLED:
* This is the default on client and server. * Early data functionality is disabled. This is the default on client and
* server.
* *
* MBEDTLS_SSL_EARLY_DATA_ENABLED: early data functionality is enabled and * MBEDTLS_SSL_EARLY_DATA_ENABLED:
* may be negotiated in the handshake. Application using * Early data functionality is enabled and may be negotiated in the handshake.
* early data functionality needs to be aware of the * Application using early data functionality needs to be aware that the
* lack of replay protection of the early data application * security properties for early data (also refered to as 0-RTT data) are
* payloads. * weaker than those for other kinds of TLS data. See the documentation of
* mbedtls_ssl_write_early_data() and mbedtls_ssl_read_early_data() for more
* information.
* When early data functionality is enabled on server and only in that case,
* the call to one of the APIs that trigger or resume an handshake sequence,
* namely mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
* mbedtls_ssl_read() or mbedtls_ssl_write() may return with the error code
* MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have
* been received. To read the early data, call mbedtls_ssl_read_early_data()
* before calling the original function again.
* *
* \warning This interface is experimental and may change without notice. * \warning This interface is experimental and may change without notice.
* *
@ -2048,7 +2076,7 @@ void mbedtls_ssl_conf_max_early_data_size(
mbedtls_ssl_config *conf, uint32_t max_early_data_size); mbedtls_ssl_config *conf, uint32_t max_early_data_size);
#endif /* MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
/** /**
@ -4733,6 +4761,13 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
* and the client did not demonstrate reachability yet - in * and the client did not demonstrate reachability yet - in
* this case you must stop using the context (see below). * this case you must stop using the context (see below).
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using * \return Another SSL error code - in this case you must stop using
* the context (see below). * the context (see below).
* *
@ -4741,7 +4776,8 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* #MBEDTLS_ERR_SSL_WANT_READ, * #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE, * #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing, * you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset() * and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current * on it before re-using it for a new connection; the current
@ -4810,8 +4846,9 @@ static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl)
* *
* \warning If this function returns something other than \c 0, * \warning If this function returns something other than \c 0,
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using
* the SSL context for reading or writing, and either free it * the SSL context for reading or writing, and either free it
* or call \c mbedtls_ssl_session_reset() on it before * or call \c mbedtls_ssl_session_reset() on it before
* re-using it for a new connection; the current connection * re-using it for a new connection; the current connection
@ -4879,6 +4916,13 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
* side of a DTLS connection and the client is initiating a * side of a DTLS connection and the client is initiating a
* new connection using the same source port. See below. * new connection using the same source port. See below.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using * \return Another SSL error code - in this case you must stop using
* the context (see below). * the context (see below).
* *
@ -4887,8 +4931,9 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* #MBEDTLS_ERR_SSL_WANT_READ, * #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE, * #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT, * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing, * you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset() * and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current * on it before re-using it for a new connection; the current
@ -4953,6 +4998,13 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* operation is in progress (see mbedtls_ecp_set_max_ops()) - * operation is in progress (see mbedtls_ecp_set_max_ops()) -
* in this case you must call this function again to complete * in this case you must call this function again to complete
* the handshake when you're done attending other tasks. * the handshake when you're done attending other tasks.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using * \return Another SSL error code - in this case you must stop using
* the context (see below). * the context (see below).
* *
@ -4960,8 +5012,9 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* a non-negative value, * a non-negative value,
* #MBEDTLS_ERR_SSL_WANT_READ, * #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE, * #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing, * you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset() * and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current * on it before re-using it for a new connection; the current
@ -5029,48 +5082,46 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_SSL_SRV_C) #if defined(MBEDTLS_SSL_SRV_C)
/** /**
* \brief Read at most 'len' application data bytes while performing * \brief Read at most 'len' bytes of early data
* the handshake (early data).
* *
* \note This function behaves mainly as mbedtls_ssl_read(). The * \note This API is server specific.
* specification of mbedtls_ssl_read() relevant to TLS 1.3
* (thus not the parts specific to (D)TLS 1.2) applies to this
* function and the present documentation is restricted to the
* differences with mbedtls_ssl_read().
* *
* \param ssl SSL context * \warning Early data is defined in the TLS 1.3 specification, RFC 8446.
* IMPORTANT NOTE from section 2.3 of the specification:
*
* The security properties for 0-RTT data are weaker than
* those for other kinds of TLS data. Specifically:
* - This data is not forward secret, as it is encrypted
* solely under keys derived using the offered PSK.
* - There are no guarantees of non-replay between connections.
* Protection against replay for ordinary TLS 1.3 1-RTT data
* is provided via the server's Random value, but 0-RTT data
* does not depend on the ServerHello and therefore has
* weaker guarantees. This is especially relevant if the
* data is authenticated either with TLS client
* authentication or inside the application protocol. The
* same warnings apply to any use of the
* early_exporter_master_secret.
*
* \note This function is used in conjunction with
* mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
* mbedtls_ssl_read() and mbedtls_ssl_write() to read early
* data when these functions return
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
*
* \param ssl SSL context, it must have been initialized and set up.
* \param buf buffer that will hold the data * \param buf buffer that will hold the data
* \param len maximum number of bytes to read * \param len maximum number of bytes to read
* *
* \return One additional specific return value: * \return The (positive) number of bytes read if successful.
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA. * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
* * \return #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA if it is not
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it * possible to read early data for the SSL context \p ssl. Note
* is not possible to read early data for the SSL context * that this function is intended to be called for an SSL
* \p ssl. * context \p ssl only after a call to mbedtls_ssl_handshake(),
* * mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or
* It may have been possible and it is not possible * mbedtls_ssl_write() for \p ssl that has returned
* anymore because the server received the End of Early Data * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
* message or the maximum number of allowed early data for the
* PSK in use has been reached.
*
* It may never have been possible and will never be possible
* for the SSL context \p ssl because the use of early data
* is disabled for that context or more generally the context
* is not suitably configured to enable early data or the
* client does not use early data or the first call to the
* function was done while the handshake was already too
* advanced to gather and accept early data.
*
* It is not possible to read early data for the SSL context
* \p ssl but this does not preclude for using it with
* mbedtls_ssl_write(), mbedtls_ssl_read() or
* mbedtls_ssl_handshake().
*
* \note When a server wants to retrieve early data, it is expected
* that this function starts the handshake for the SSL context
* \p ssl. But this is not mandatory.
*
*/ */
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len); unsigned char *buf, size_t len);

View File

@ -650,6 +650,10 @@ struct mbedtls_ssl_handshake_params {
/* Flag indicating if a CertificateRequest message has been sent /* Flag indicating if a CertificateRequest message has been sent
* to the client or not. */ * to the client or not. */
uint8_t certificate_request_sent; uint8_t certificate_request_sent;
#if defined(MBEDTLS_SSL_EARLY_DATA)
/* Flag indicating if the server has accepted early data or not. */
uint8_t early_data_accepted;
#endif
#endif /* MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -2130,12 +2134,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
const unsigned char *end, const unsigned char *end,
size_t *out_len); size_t *out_len);
#if defined(MBEDTLS_SSL_SRV_C)
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED \
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT
#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View File

@ -5647,13 +5647,54 @@ static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_INTERNAL_ERROR; return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
} }
/*
* brief Read at most 'len' application data bytes from the input
* buffer.
*
* param ssl SSL context:
* - First byte of application data not read yet in the input
* buffer located at address `in_offt`.
* - The number of bytes of data not read yet is `in_msglen`.
* param buf buffer that will hold the data
* param len maximum number of bytes to read
*
* note The function updates the fields `in_offt` and `in_msglen`
* according to the number of bytes read.
*
* return The number of bytes read.
*/
static int ssl_read_application_data(
mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
return (int) n;
}
/* /*
* Receive application data decrypted from the SSL layer * Receive application data decrypted from the SSL layer
*/ */
int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
if (ssl == NULL || ssl->conf == NULL) { if (ssl == NULL || ssl->conf == NULL) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
@ -5817,32 +5858,34 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
} }
n = (len < ssl->in_msglen) ret = ssl_read_application_data(ssl, buf, len);
? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
MBEDTLS_SSL_DEBUG_MSG(2, ("<= read")); MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
return (int) n; return ret;
} }
#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;
}
/*
* The server may receive early data only while waiting for the End of
* Early Data handshake message.
*/
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_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */
/* /*
* Send application data to be encrypted by the SSL layer, taking care of max * Send application data to be encrypted by the SSL layer, taking care of max
* fragment length and buffer size. * fragment length and buffer size.

View File

@ -1098,6 +1098,10 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_ALLOC_FAILED; return MBEDTLS_ERR_SSL_ALLOC_FAILED;
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
#endif
/* Initialize structures */ /* Initialize structures */
mbedtls_ssl_session_init(ssl->session_negotiate); mbedtls_ssl_session_init(ssl->session_negotiate);
ssl_handshake_params_init(ssl->handshake); ssl_handshake_params_init(ssl->handshake);

View File

@ -1780,7 +1780,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl) static int ssl_tls13_is_early_data_accepted(mbedtls_ssl_context *ssl,
int hrr_required)
{ {
mbedtls_ssl_handshake_params *handshake = ssl->handshake; mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@ -1788,17 +1789,19 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) { MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) {
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: no early data extension received.")); 1, ("EarlyData: no early data extension received."));
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED; return 0;
return;
} }
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) { if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, 1,
("EarlyData: rejected, feature disabled in server configuration.")); ("EarlyData: rejected, feature disabled in server configuration."));
return; return 0;
}
if (hrr_required) {
MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, HRR required."));
return 0;
} }
if (!handshake->resume) { if (!handshake->resume) {
@ -1807,7 +1810,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
resumption. */ resumption. */
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, not a session resumption.")); 1, ("EarlyData: rejected, not a session resumption."));
return; return 0;
} }
/* RFC 8446 4.2.10 /* RFC 8446 4.2.10
@ -1830,7 +1833,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected key in " 1, ("EarlyData: rejected, the selected key in "
"`pre_shared_key` is not the first one.")); "`pre_shared_key` is not the first one."));
return; return 0;
} }
if (handshake->ciphersuite_info->id != if (handshake->ciphersuite_info->id !=
@ -1838,7 +1841,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected ciphersuite is not the one " 1, ("EarlyData: rejected, the selected ciphersuite is not the one "
"of the selected pre-shared key.")); "of the selected pre-shared key."));
return; return 0;
} }
@ -1847,18 +1850,18 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
1, 1,
("EarlyData: rejected, early_data not allowed in ticket " ("EarlyData: rejected, early_data not allowed in ticket "
"permission bits.")); "permission bits."));
return; return 0;
} }
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; return 1;
} }
#endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_EARLY_DATA */
/* Update the handshake state machine */ /* Update the handshake state machine */
MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl) static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
int hrr_required)
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -1882,10 +1885,10 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
/* There is enough information, update early data state. */ ssl->handshake->early_data_accepted =
ssl_tls13_update_early_data_status(ssl); ssl_tls13_is_early_data_accepted(ssl, hrr_required);
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_compute_early_transform(ssl); ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) { if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET( MBEDTLS_SSL_DEBUG_RET(
@ -1893,6 +1896,8 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
return ret; return ret;
} }
} }
#else
((void) hrr_required);
#endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_EARLY_DATA */
return 0; return 0;
@ -1947,7 +1952,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
return 0; return 0;
} }
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_client_hello(ssl)); MBEDTLS_SSL_PROC_CHK(
ssl_tls13_postprocess_client_hello(ssl, parse_client_hello_ret ==
SSL_CLIENT_HELLO_HRR_REQUIRED));
if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) { if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO); mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
@ -2530,7 +2537,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */ #endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_write_early_data_ext( ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &output_len); ssl, 0, p, end, &output_len);
if (ret != 0) { if (ret != 0) {
@ -2857,7 +2864,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { if (ssl->handshake->early_data_accepted) {
/* See RFC 8446 section A.2 for more information */ /* See RFC 8446 section A.2 for more information */
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early keys for inbound traffic. " 1, ("Switch to early keys for inbound traffic. "
@ -2911,6 +2918,17 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) { if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data")); MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/
if (ssl->in_offt == NULL) {
/* Set the reading pointer */
ssl->in_offt = ssl->in_msg;
}
return SSL_GOT_EARLY_DATA; return SSL_GOT_EARLY_DATA;
} }
@ -2936,37 +2954,6 @@ static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl,
return 0; return 0;
} }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_early_application_data(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;
}
/*
* Output early data
*
* For the time being, we print received data via debug message.
*
* TODO: Remove it when `mbedtls_ssl_read_early_data` is ready.
*/
ssl->in_msg[ssl->in_msglen] = 0;
MBEDTLS_SSL_DEBUG_MSG(3, ("\n%s", ssl->in_msg));
/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/
return 0;
}
/* /*
* RFC 8446 section A.2 * RFC 8446 section A.2
* *
@ -3037,7 +3024,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
ssl_tls13_prepare_for_handshake_second_flight(ssl); ssl_tls13_prepare_for_handshake_second_flight(ssl);
} else if (ret == SSL_GOT_EARLY_DATA) { } else if (ret == SSL_GOT_EARLY_DATA) {
MBEDTLS_SSL_PROC_CHK(ssl_tls13_process_early_application_data(ssl)); ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA;
goto cleanup;
} else { } else {
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;

View File

@ -1612,6 +1612,7 @@ int main(int argc, char *argv[])
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED; int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED;
#endif #endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf)); mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf));
#if defined(MBEDTLS_MEMORY_DEBUG) #if defined(MBEDTLS_MEMORY_DEBUG)
@ -3450,6 +3451,19 @@ handshake:
fflush(stdout); fflush(stdout);
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) {
memset(buf, 0, opt.buffer_size);
ret = mbedtls_ssl_read_early_data(&ssl, buf, opt.buffer_size);
if (ret > 0) {
buf[ret] = '\0';
mbedtls_printf(" %d early data bytes read\n\n%s\n",
ret, (char *) buf);
}
continue;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS && if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS &&
ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL) { ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL) {

View File

@ -1,3 +1,4 @@
EarlyData context: line 0 lf EarlyData context: line 0 lf
EarlyData context: line 1 lf EarlyData context: line 1 lf
EarlyData context: line 2 lf
EarlyData context: If it appears, that means early_data received. EarlyData context: If it appears, that means early_data received.

View File

@ -506,4 +506,7 @@ run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \
-s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \
-s "ClientHello: early_data(42) extension exists." \ -s "ClientHello: early_data(42) extension exists." \
-s "EncryptedExtensions: early_data(42) extension exists." \ -s "EncryptedExtensions: early_data(42) extension exists." \
-s "$( tail -1 $EARLY_DATA_INPUT )" -s "$( head -1 $EARLY_DATA_INPUT )" \
-s "$( tail -1 $EARLY_DATA_INPUT )" \
-s "200 early data bytes read" \
-s "106 early data bytes read"

View File

@ -12,8 +12,7 @@
#define SSL_MESSAGE_QUEUE_INIT { NULL, 0, 0, 0 } #define SSL_MESSAGE_QUEUE_INIT { NULL, 0, 0, 0 }
#if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \
defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \
defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \
defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \ defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \ defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \
@ -3662,12 +3661,7 @@ exit:
} }
/* END_CASE */ /* END_CASE */
/* /* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
* The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is
* a temporary workaround to not run the test in Windows-2013 where there is
* an issue with mbedtls_vsnprintf().
*/
/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
void tls13_early_data() void tls13_early_data()
{ {
int ret = -1; int ret = -1;
@ -3678,7 +3672,6 @@ void tls13_early_data()
mbedtls_test_handshake_test_options client_options; mbedtls_test_handshake_test_options client_options;
mbedtls_test_handshake_test_options server_options; mbedtls_test_handshake_test_options server_options;
mbedtls_ssl_session saved_session; mbedtls_ssl_session saved_session;
mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 };
/* /*
* Test set-up * Test set-up
@ -3699,9 +3692,6 @@ void tls13_early_data()
mbedtls_ssl_conf_early_data(&client_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED); mbedtls_ssl_conf_early_data(&client_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED);
server_options.pk_alg = MBEDTLS_PK_ECDSA; server_options.pk_alg = MBEDTLS_PK_ECDSA;
server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
server_options.srv_log_obj = &server_pattern;
server_pattern.pattern = early_data;
ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
&server_options, NULL, NULL, NULL, &server_options, NULL, NULL, NULL,
NULL); NULL);
@ -3750,15 +3740,12 @@ void tls13_early_data()
ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
TEST_EQUAL(ret, 0); TEST_EQUAL(ret, 0);
mbedtls_debug_set_threshold(3);
TEST_EQUAL(mbedtls_test_move_handshake_to_state( TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(client_ep.ssl), &(server_ep.ssl), &(client_ep.ssl), &(server_ep.ssl),
MBEDTLS_SSL_SERVER_HELLO), 0); MBEDTLS_SSL_SERVER_HELLO), 0);
TEST_ASSERT(client_ep.ssl.early_data_status != TEST_ASSERT(client_ep.ssl.early_data_status !=
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
TEST_EQUAL(server_pattern.counter, 0);
ret = write_early_data(&(client_ep.ssl), (unsigned char *) early_data, ret = write_early_data(&(client_ep.ssl), (unsigned char *) early_data,
early_data_len); early_data_len);
@ -3766,11 +3753,16 @@ void tls13_early_data()
TEST_EQUAL(mbedtls_test_move_handshake_to_state( TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl), &(server_ep.ssl), &(client_ep.ssl),
MBEDTLS_SSL_CLIENT_FINISHED), 0); MBEDTLS_SSL_CLIENT_FINISHED), MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
TEST_EQUAL(server_ep.ssl.early_data_status, TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 1);
MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED); TEST_EQUAL(mbedtls_ssl_read_early_data(&(server_ep.ssl), buf, sizeof(buf)),
TEST_EQUAL(server_pattern.counter, 1); early_data_len);
TEST_MEMORY_COMPARE(buf, early_data_len, early_data, early_data_len);
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl),
MBEDTLS_SSL_HANDSHAKE_OVER), 0);
exit: exit:
mbedtls_test_ssl_endpoint_free(&client_ep, NULL); mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
@ -3778,7 +3770,6 @@ exit:
mbedtls_test_free_handshake_options(&client_options); mbedtls_test_free_handshake_options(&client_options);
mbedtls_test_free_handshake_options(&server_options); mbedtls_test_free_handshake_options(&server_options);
mbedtls_ssl_session_free(&saved_session); mbedtls_ssl_session_free(&saved_session);
mbedtls_debug_set_threshold(0);
PSA_DONE(); PSA_DONE();
} }
/* END_CASE */ /* END_CASE */