SSL_READ_EARLY_DATA(3)
π SSL_READ_EARLY_DATA(3) β like, the early data girlies (Library Functions Manual)
okay so bestie, buckle up, because this one is a whole situation. This page lives in the Library Functions Manual and it's about that one TLS feature everybody wants to talk about at parties: sending your app data during the handshake. Yes. Before you're even, like, properly introduced. π
β¨ NAME β¨
So the whole squad of functions is:
SSL_CTX_set_max_early_dataSSL_set_max_early_dataSSL_SESSION_set_max_early_dataSSL_CTX_get_max_early_dataSSL_get_max_early_dataSSL_SESSION_get_max_early_dataSSL_write_early_dataSSL_read_early_dataSSL_get_early_data_status
β¦and what they claim to do is transmit application data during the handshake. That's the vibe. That's the whole pitch. π
πΈ SYNOPSIS πΈ
library βlibsslβ libcrypto #include <openssl/ssl.h>
int
SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_bytes);
int
SSL_set_max_early_data(SSL *ssl, uint32_t max_bytes);
int
SSL_SESSION_set_max_early_data(SSL_SESSION *session,
uint32_t max_bytes);
uint32_t
SSL_CTX_get_max_early_data(const SSL_CTX *ctx);
uint32_t
SSL_get_max_early_data(const SSL *ssl);
uint32_t
SSL_SESSION_get_max_early_data(const SSL_SESSION *session);
int
SSL_write_early_data(SSL *ssl, const void *buf, size_t len,
size_t *written);
int
SSL_read_early_data(SSL *ssl, void *buf, size_t maxlen,
size_t *readbytes);
int
SSL_get_early_data_status(const SSL *ssl);
π¦ DESCRIPTION π¦
okay. deep breath. In LibreSSL, these functions have no effect. Like, none. Zero. They exist purely because some applications out there expect the API to be available when TLSv1.3 is supported β so LibreSSL keeps the door open and the lights on, but nobody's home. π
And honestly? Using them is strongly discouraged, and the reasons are giving very much "do not". Specifically:
- they provide, at best, marginal benefit even when they're fully implemented and used exactly as designed,
- they have absurdly complicated semantics (their words, not mine, but like⦠accurate),
- and when you do use them, the tiniest inconspicuous oversight is likely to cause serious security vulnerabilities. π
bestie, that's not a "read the docs later" warning, that's a "put it down and walk away" warning.
If these functions are used, other TLS implementations may allow the transfer of application data during the initial handshake. And even when everything is used exactly as designed, security of the connection is compromised β specifically:
- application data gets exchanged with unauthenticated peers,
- and there is no forward secrecy.
Other downsides include an increased risk of replay attacks. so like, the villain arc. π«
the setter girlies
SSL_CTX_set_max_early_data(), SSL_set_max_early_data(), and SSL_SESSION_set_max_early_data() are intended to configure the maximum number of bytes per session that can be transmitted during the handshake.
With LibreSSL, all arguments are ignored. iconic honestly. π
the writer
An endpoint can attempt to send application data with SSL_write_early_data() during the handshake.
With LibreSSL, such attempts always fail and set *written to 0. π
the reader
A server can attempt to read application data from the client using SSL_read_early_data() during the handshake.
With LibreSSL, no such data is ever accepted and *readbytes is always set to 0. π
π RETURN VALUES π
SSL_CTX_set_max_early_data(),SSL_set_max_early_data(),SSL_SESSION_set_max_early_data()β return1for success or0for failure. With LibreSSL, they always succeed.SSL_CTX_get_max_early_data(),SSL_get_max_early_data(),SSL_SESSION_get_max_early_data()β return the maximum number of bytes of application data that will be accepted from the peer during the handshake. With LibreSSL, they always return0.SSL_write_early_data()β returns1for success or0for failure. With LibreSSL, it always fails.SSL_read_early_data()β with LibreSSL, it always returnsSSL_READ_EARLY_DATA_FINISHon the server side andSSL_READ_EARLY_DATA_ERRORon the client side.SSL_READ_EARLY_DATA_SUCCESScan occur with other implementations, but not with LibreSSL.SSL_get_early_data_status()β with LibreSSL, it always returnsSSL_EARLY_DATA_REJECTED. With other implementations, it might also returnSSL_EARLY_DATA_NOT_SENTorSSL_EARLY_DATA_ACCEPTED.
π SEE ALSO π
go read those, they're the well-adjusted siblings. π«Ά
π STANDARDS π
RFC 9846: The Transport Layer Security (TLS) Protocol Version 1.3:
Section 2.3β 0-RTT dataSection 4.3.10β Early Data IndicationSection 8β 0-RTT and Anti-ReplayAppendix F.5β Replay Attacks on 0-RTT
like, the receipt is right there in Appendix F.5 and it says replay attacks. β
π HISTORY π
These functions first appeared in OpenSSL 1.1.1 and have been available since OpenBSD 7.0.
kisses bestie, that's the whole page π this drop was from Debian, dated August 21, 2026, and yes the page name at the very bottom is SSL_READ_EARLY_DATA(3) β mwah πβ¨
π¦ where this page comes from
- arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
- Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms