Add Data-less Zero-RTT support.
This adds support on the server and client to accept data-less early
data. The server will still fail to parse early data with any
contents, so this should remain disabled.
BUG=76
Change-Id: Id85d192d8e0360b8de4b6971511b5e8a0e8012f7
Reviewed-on: https://boringssl-review.googlesource.com/12921
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index 412705d..16efd85 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -28,22 +28,43 @@
#include "internal.h"
-int tls13_init_key_schedule(SSL_HANDSHAKE *hs) {
- if (!SSL_TRANSCRIPT_init_hash(&hs->transcript, ssl3_protocol_version(hs->ssl),
- hs->new_cipher->algorithm_prf)) {
+static int init_key_schedule(SSL_HANDSHAKE *hs, uint16_t version,
+ int algorithm_prf) {
+ if (!SSL_TRANSCRIPT_init_hash(&hs->transcript, version, algorithm_prf)) {
return 0;
}
-
hs->hash_len = SSL_TRANSCRIPT_digest_len(&hs->transcript);
/* Initialize the secret to the zero key. */
OPENSSL_memset(hs->secret, 0, hs->hash_len);
+ return 1;
+}
+
+int tls13_init_key_schedule(SSL_HANDSHAKE *hs) {
+ if (!init_key_schedule(hs, ssl3_protocol_version(hs->ssl),
+ hs->new_cipher->algorithm_prf)) {
+ return 0;
+ }
+
SSL_TRANSCRIPT_free_buffer(&hs->transcript);
return 1;
}
+int tls13_init_early_key_schedule(SSL_HANDSHAKE *hs) {
+ SSL *const ssl = hs->ssl;
+ uint16_t session_version;
+ if (!ssl->method->version_from_wire(&session_version,
+ ssl->session->ssl_version) ||
+ !init_key_schedule(hs, session_version,
+ ssl->session->cipher->algorithm_prf)) {
+ return 0;
+ }
+
+ return 1;
+}
+
int tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in,
size_t len) {
return HKDF_extract(hs->secret, &hs->hash_len,
@@ -100,6 +121,13 @@
int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction,
const uint8_t *traffic_secret,
size_t traffic_secret_len) {
+ const SSL_SESSION *session = SSL_get_session(ssl);
+ uint16_t version;
+ if (!ssl->method->version_from_wire(&version, session->ssl_version)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
if (traffic_secret_len > 0xff) {
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return 0;
@@ -108,14 +136,13 @@
/* Look up cipher suite properties. */
const EVP_AEAD *aead;
size_t discard;
- if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard,
- SSL_get_session(ssl)->cipher,
- ssl3_protocol_version(ssl))) {
+ if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, session->cipher,
+ version)) {
return 0;
}
const EVP_MD *digest = ssl_get_handshake_digest(
- SSL_get_session(ssl)->cipher->algorithm_prf, ssl3_protocol_version(ssl));
+ session->cipher->algorithm_prf, version);
/* Derive the key. */
size_t key_len = EVP_AEAD_key_length(aead);
@@ -134,8 +161,7 @@
}
SSL_AEAD_CTX *traffic_aead = SSL_AEAD_CTX_new(
- direction, ssl3_protocol_version(ssl), SSL_get_session(ssl)->cipher, key,
- key_len, NULL, 0, iv, iv_len);
+ direction, version, session->cipher, key, key_len, NULL, 0, iv, iv_len);
if (traffic_aead == NULL) {
return 0;
}
@@ -164,6 +190,11 @@
return 1;
}
+static const char kTLS13LabelExporter[] = "exporter master secret";
+static const char kTLS13LabelEarlyExporter[] = "early exporter master secret";
+
+static const char kTLS13LabelClientEarlyTraffic[] =
+ "client early traffic secret";
static const char kTLS13LabelClientHandshakeTraffic[] =
"client handshake traffic secret";
static const char kTLS13LabelServerHandshakeTraffic[] =
@@ -173,6 +204,18 @@
static const char kTLS13LabelServerApplicationTraffic[] =
"server application traffic secret";
+int tls13_derive_early_secrets(SSL_HANDSHAKE *hs) {
+ SSL *const ssl = hs->ssl;
+ return derive_secret(hs, hs->early_traffic_secret, hs->hash_len,
+ (const uint8_t *)kTLS13LabelClientEarlyTraffic,
+ strlen(kTLS13LabelClientEarlyTraffic)) &&
+ ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET",
+ hs->early_traffic_secret, hs->hash_len) &&
+ derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len,
+ (const uint8_t *)kTLS13LabelEarlyExporter,
+ strlen(kTLS13LabelEarlyExporter));
+}
+
int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
return derive_secret(hs, hs->client_handshake_secret, hs->hash_len,
@@ -187,8 +230,6 @@
hs->server_handshake_secret, hs->hash_len);
}
-static const char kTLS13LabelExporter[] = "exporter master secret";
-
int tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
ssl->s3->exporter_secret_len = hs->hash_len;