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;