Skip to content

Commit b90e695

Browse files
Merge pull request #8692 from ronald-cron-arm/read-early-data
TLS 1.3: SRV: Implement mbedtls_ssl_read_early_data()
2 parents 11cc412 + 38dbab9 commit b90e695

File tree

9 files changed

+251
-158
lines changed

9 files changed

+251
-158
lines changed

include/mbedtls/ssl.h

Lines changed: 112 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,18 @@
9090
#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00
9191
/** Not possible to read early data */
9292
#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80
93+
/**
94+
* Early data has been received as part of an on-going handshake.
95+
* This error code can be returned only on server side if and only if early
96+
* data has been enabled by means of the mbedtls_ssl_conf_early_data() API.
97+
* This error code can then be returned by mbedtls_ssl_handshake(),
98+
* mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write() if
99+
* early data has been received as part of the handshake sequence they
100+
* triggered. To read the early data, call mbedtls_ssl_read_early_data().
101+
*/
102+
#define MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA -0x7C00
93103
/** Not possible to write early data */
94-
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C00
104+
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C80
95105
/* Error space gap */
96106
/* Error space gap */
97107
/* Error space gap */
@@ -1644,6 +1654,18 @@ struct mbedtls_ssl_context {
16441654
*/
16451655
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
16461656

1657+
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
1658+
/**
1659+
* Status of the negotiation of the use of early data.
1660+
* See the documentation of mbedtls_ssl_get_early_data_status() for more
1661+
* information.
1662+
*
1663+
* Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT when the context is
1664+
* reset.
1665+
*/
1666+
int MBEDTLS_PRIVATE(early_data_status);
1667+
#endif
1668+
16471669
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
16481670

16491671
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -1841,10 +1863,6 @@ struct mbedtls_ssl_context {
18411863
* and #MBEDTLS_SSL_CID_DISABLED. */
18421864
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
18431865

1844-
#if defined(MBEDTLS_SSL_EARLY_DATA)
1845-
int MBEDTLS_PRIVATE(early_data_status);
1846-
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
1847-
18481866
/** Callback to export key block and master secret */
18491867
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
18501868
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */
@@ -1993,22 +2011,32 @@ void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport);
19932011
*/
19942012
void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
19952013

1996-
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_EARLY_DATA)
2014+
#if defined(MBEDTLS_SSL_EARLY_DATA)
19972015
/**
19982016
* \brief Set the early data mode
19992017
* Default: disabled on server and client
20002018
*
20012019
* \param conf The SSL configuration to use.
20022020
* \param early_data_enabled can be:
20032021
*
2004-
* MBEDTLS_SSL_EARLY_DATA_DISABLED: early data functionality is disabled
2005-
* This is the default on client and server.
2006-
*
2007-
* MBEDTLS_SSL_EARLY_DATA_ENABLED: early data functionality is enabled and
2008-
* may be negotiated in the handshake. Application using
2009-
* early data functionality needs to be aware of the
2010-
* lack of replay protection of the early data application
2011-
* payloads.
2022+
* MBEDTLS_SSL_EARLY_DATA_DISABLED:
2023+
* Early data functionality is disabled. This is the default on client and
2024+
* server.
2025+
*
2026+
* MBEDTLS_SSL_EARLY_DATA_ENABLED:
2027+
* Early data functionality is enabled and may be negotiated in the handshake.
2028+
* Application using early data functionality needs to be aware that the
2029+
* security properties for early data (also refered to as 0-RTT data) are
2030+
* weaker than those for other kinds of TLS data. See the documentation of
2031+
* mbedtls_ssl_write_early_data() and mbedtls_ssl_read_early_data() for more
2032+
* information.
2033+
* When early data functionality is enabled on server and only in that case,
2034+
* the call to one of the APIs that trigger or resume an handshake sequence,
2035+
* namely mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
2036+
* mbedtls_ssl_read() or mbedtls_ssl_write() may return with the error code
2037+
* MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have
2038+
* been received. To read the early data, call mbedtls_ssl_read_early_data()
2039+
* before calling the original function again.
20122040
*
20132041
* \warning This interface is experimental and may change without notice.
20142042
*
@@ -2048,7 +2076,7 @@ void mbedtls_ssl_conf_max_early_data_size(
20482076
mbedtls_ssl_config *conf, uint32_t max_early_data_size);
20492077
#endif /* MBEDTLS_SSL_SRV_C */
20502078

2051-
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA */
2079+
#endif /* MBEDTLS_SSL_EARLY_DATA */
20522080

20532081
#if defined(MBEDTLS_X509_CRT_PARSE_C)
20542082
/**
@@ -4733,6 +4761,13 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
47334761
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
47344762
* and the client did not demonstrate reachability yet - in
47354763
* this case you must stop using the context (see below).
4764+
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
4765+
* defined in RFC 8446 (TLS 1.3 specification), has been
4766+
* received as part of the handshake. This is server specific
4767+
* and may occur only if the early data feature has been
4768+
* enabled on server (see mbedtls_ssl_conf_early_data()
4769+
* documentation). You must call mbedtls_ssl_read_early_data()
4770+
* to read the early data before resuming the handshake.
47364771
* \return Another SSL error code - in this case you must stop using
47374772
* the context (see below).
47384773
*
@@ -4741,7 +4776,8 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
47414776
* #MBEDTLS_ERR_SSL_WANT_READ,
47424777
* #MBEDTLS_ERR_SSL_WANT_WRITE,
47434778
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
4744-
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
4779+
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
4780+
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
47454781
* you must stop using the SSL context for reading or writing,
47464782
* and either free it or call \c mbedtls_ssl_session_reset()
47474783
* 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)
48104846
*
48114847
* \warning If this function returns something other than \c 0,
48124848
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
4813-
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
4814-
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
4849+
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
4850+
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
4851+
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using
48154852
* the SSL context for reading or writing, and either free it
48164853
* or call \c mbedtls_ssl_session_reset() on it before
48174854
* re-using it for a new connection; the current connection
@@ -4879,6 +4916,13 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
48794916
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
48804917
* side of a DTLS connection and the client is initiating a
48814918
* new connection using the same source port. See below.
4919+
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
4920+
* defined in RFC 8446 (TLS 1.3 specification), has been
4921+
* received as part of the handshake. This is server specific
4922+
* and may occur only if the early data feature has been
4923+
* enabled on server (see mbedtls_ssl_conf_early_data()
4924+
* documentation). You must call mbedtls_ssl_read_early_data()
4925+
* to read the early data before resuming the handshake.
48824926
* \return Another SSL error code - in this case you must stop using
48834927
* the context (see below).
48844928
*
@@ -4887,8 +4931,9 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
48874931
* #MBEDTLS_ERR_SSL_WANT_READ,
48884932
* #MBEDTLS_ERR_SSL_WANT_WRITE,
48894933
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
4890-
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
4891-
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
4934+
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
4935+
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or
4936+
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
48924937
* you must stop using the SSL context for reading or writing,
48934938
* and either free it or call \c mbedtls_ssl_session_reset()
48944939
* on it before re-using it for a new connection; the current
@@ -4953,15 +4998,23 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
49534998
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
49544999
* in this case you must call this function again to complete
49555000
* the handshake when you're done attending other tasks.
5001+
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
5002+
* defined in RFC 8446 (TLS 1.3 specification), has been
5003+
* received as part of the handshake. This is server specific
5004+
* and may occur only if the early data feature has been
5005+
* enabled on server (see mbedtls_ssl_conf_early_data()
5006+
* documentation). You must call mbedtls_ssl_read_early_data()
5007+
* to read the early data before resuming the handshake.
49565008
* \return Another SSL error code - in this case you must stop using
49575009
* the context (see below).
49585010
*
49595011
* \warning If this function returns something other than
49605012
* a non-negative value,
49615013
* #MBEDTLS_ERR_SSL_WANT_READ,
49625014
* #MBEDTLS_ERR_SSL_WANT_WRITE,
4963-
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
4964-
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
5015+
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
5016+
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
5017+
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
49655018
* you must stop using the SSL context for reading or writing,
49665019
* and either free it or call \c mbedtls_ssl_session_reset()
49675020
* 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);
50295082

50305083
#if defined(MBEDTLS_SSL_SRV_C)
50315084
/**
5032-
* \brief Read at most 'len' application data bytes while performing
5033-
* the handshake (early data).
5034-
*
5035-
* \note This function behaves mainly as mbedtls_ssl_read(). The
5036-
* specification of mbedtls_ssl_read() relevant to TLS 1.3
5037-
* (thus not the parts specific to (D)TLS 1.2) applies to this
5038-
* function and the present documentation is restricted to the
5039-
* differences with mbedtls_ssl_read().
5040-
*
5041-
* \param ssl SSL context
5085+
* \brief Read at most 'len' bytes of early data
5086+
*
5087+
* \note This API is server specific.
5088+
*
5089+
* \warning Early data is defined in the TLS 1.3 specification, RFC 8446.
5090+
* IMPORTANT NOTE from section 2.3 of the specification:
5091+
*
5092+
* The security properties for 0-RTT data are weaker than
5093+
* those for other kinds of TLS data. Specifically:
5094+
* - This data is not forward secret, as it is encrypted
5095+
* solely under keys derived using the offered PSK.
5096+
* - There are no guarantees of non-replay between connections.
5097+
* Protection against replay for ordinary TLS 1.3 1-RTT data
5098+
* is provided via the server's Random value, but 0-RTT data
5099+
* does not depend on the ServerHello and therefore has
5100+
* weaker guarantees. This is especially relevant if the
5101+
* data is authenticated either with TLS client
5102+
* authentication or inside the application protocol. The
5103+
* same warnings apply to any use of the
5104+
* early_exporter_master_secret.
5105+
*
5106+
* \note This function is used in conjunction with
5107+
* mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
5108+
* mbedtls_ssl_read() and mbedtls_ssl_write() to read early
5109+
* data when these functions return
5110+
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
5111+
*
5112+
* \param ssl SSL context, it must have been initialized and set up.
50425113
* \param buf buffer that will hold the data
50435114
* \param len maximum number of bytes to read
50445115
*
5045-
* \return One additional specific return value:
5046-
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA.
5047-
*
5048-
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it
5049-
* is not possible to read early data for the SSL context
5050-
* \p ssl.
5051-
*
5052-
* It may have been possible and it is not possible
5053-
* anymore because the server received the End of Early Data
5054-
* message or the maximum number of allowed early data for the
5055-
* PSK in use has been reached.
5056-
*
5057-
* It may never have been possible and will never be possible
5058-
* for the SSL context \p ssl because the use of early data
5059-
* is disabled for that context or more generally the context
5060-
* is not suitably configured to enable early data or the
5061-
* client does not use early data or the first call to the
5062-
* function was done while the handshake was already too
5063-
* advanced to gather and accept early data.
5064-
*
5065-
* It is not possible to read early data for the SSL context
5066-
* \p ssl but this does not preclude for using it with
5067-
* mbedtls_ssl_write(), mbedtls_ssl_read() or
5068-
* mbedtls_ssl_handshake().
5069-
*
5070-
* \note When a server wants to retrieve early data, it is expected
5071-
* that this function starts the handshake for the SSL context
5072-
* \p ssl. But this is not mandatory.
5073-
*
5116+
* \return The (positive) number of bytes read if successful.
5117+
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
5118+
* \return #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA if it is not
5119+
* possible to read early data for the SSL context \p ssl. Note
5120+
* that this function is intended to be called for an SSL
5121+
* context \p ssl only after a call to mbedtls_ssl_handshake(),
5122+
* mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or
5123+
* mbedtls_ssl_write() for \p ssl that has returned
5124+
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
50745125
*/
50755126
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
50765127
unsigned char *buf, size_t len);

library/ssl_misc.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,10 @@ struct mbedtls_ssl_handshake_params {
650650
/* Flag indicating if a CertificateRequest message has been sent
651651
* to the client or not. */
652652
uint8_t certificate_request_sent;
653+
#if defined(MBEDTLS_SSL_EARLY_DATA)
654+
/* Flag indicating if the server has accepted early data or not. */
655+
uint8_t early_data_accepted;
656+
#endif
653657
#endif /* MBEDTLS_SSL_SRV_C */
654658

655659
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -2130,12 +2134,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
21302134
unsigned char *buf,
21312135
const unsigned char *end,
21322136
size_t *out_len);
2133-
2134-
#if defined(MBEDTLS_SSL_SRV_C)
2135-
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED \
2136-
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT
2137-
#endif /* MBEDTLS_SSL_SRV_C */
2138-
21392137
#endif /* MBEDTLS_SSL_EARLY_DATA */
21402138

21412139
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

0 commit comments

Comments
 (0)