Splitting handshake traffic derivation from key change.

This is in preparation for implementing 0-RTT where, like
with client_traffic_secret_0, client_handshake_secret must
be derived slightly earlier than it is used. (The secret is
derived at ServerHello, but used at server Finished.)

Change-Id: I6a186b84829800704a62fda412992ac730422110
Reviewed-on: https://boringssl-review.googlesource.com/12920
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/internal.h b/ssl/internal.h
index 2688bc7..a4ae83a 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -833,10 +833,9 @@
                           const uint8_t *traffic_secret,
                           size_t traffic_secret_len);
 
-/* tls13_set_handshake_traffic derives the handshake traffic secret and
- * switches both read and write traffic to it. It returns one on success and
- * zero on error. */
-int tls13_set_handshake_traffic(SSL_HANDSHAKE *hs);
+/* tls13_derive_handshake_secrets derives the handshake traffic secret. It
+ * returns one on success and zero on error. */
+int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs);
 
 /* tls13_rotate_traffic_key derives the next read or write traffic secret. It
  * returns one on success and zero on error. */
@@ -914,6 +913,8 @@
 
   size_t hash_len;
   uint8_t secret[EVP_MAX_MD_SIZE];
+  uint8_t client_handshake_secret[EVP_MAX_MD_SIZE];
+  uint8_t server_handshake_secret[EVP_MAX_MD_SIZE];
   uint8_t client_traffic_secret_0[EVP_MAX_MD_SIZE];
   uint8_t server_traffic_secret_0[EVP_MAX_MD_SIZE];
 
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 4800f92..3a96abc 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -149,6 +149,10 @@
   }
 
   OPENSSL_cleanse(hs->secret, sizeof(hs->secret));
+  OPENSSL_cleanse(hs->client_handshake_secret,
+                  sizeof(hs->client_handshake_secret));
+  OPENSSL_cleanse(hs->server_handshake_secret,
+                  sizeof(hs->server_handshake_secret));
   OPENSSL_cleanse(hs->client_traffic_secret_0,
                   sizeof(hs->client_traffic_secret_0));
   OPENSSL_cleanse(hs->server_traffic_secret_0,
diff --git a/ssl/tls13_client.c b/ssl/tls13_client.c
index 4a202d7..ea241c1 100644
--- a/ssl/tls13_client.c
+++ b/ssl/tls13_client.c
@@ -311,7 +311,11 @@
     return ssl_hs_error;
   }
 
-  if (!tls13_set_handshake_traffic(hs)) {
+  if (!tls13_derive_handshake_secrets(hs) ||
+      !tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
+                             hs->hash_len) ||
+      !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
+                             hs->hash_len)) {
     return ssl_hs_error;
   }
 
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index 4fca65b..b431b75 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -185,39 +185,18 @@
 static const char kTLS13LabelServerApplicationTraffic[] =
     "server application traffic secret";
 
-int tls13_set_handshake_traffic(SSL_HANDSHAKE *hs) {
+int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  uint8_t client_traffic_secret[EVP_MAX_MD_SIZE];
-  uint8_t server_traffic_secret[EVP_MAX_MD_SIZE];
-  if (!derive_secret(hs, client_traffic_secret, hs->hash_len,
-                     (const uint8_t *)kTLS13LabelClientHandshakeTraffic,
-                     strlen(kTLS13LabelClientHandshakeTraffic)) ||
-      !ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
-                      client_traffic_secret, hs->hash_len) ||
-      !derive_secret(hs, server_traffic_secret, hs->hash_len,
-                     (const uint8_t *)kTLS13LabelServerHandshakeTraffic,
-                     strlen(kTLS13LabelServerHandshakeTraffic)) ||
-      !ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
-                      server_traffic_secret, hs->hash_len)) {
-    return 0;
-  }
-
-  if (ssl->server) {
-    if (!tls13_set_traffic_key(ssl, evp_aead_open, client_traffic_secret,
-                               hs->hash_len) ||
-        !tls13_set_traffic_key(ssl, evp_aead_seal, server_traffic_secret,
-                               hs->hash_len)) {
-      return 0;
-    }
-  } else {
-    if (!tls13_set_traffic_key(ssl, evp_aead_open, server_traffic_secret,
-                               hs->hash_len) ||
-        !tls13_set_traffic_key(ssl, evp_aead_seal, client_traffic_secret,
-                               hs->hash_len)) {
-      return 0;
-    }
-  }
-  return 1;
+  return derive_secret(hs, hs->client_handshake_secret, hs->hash_len,
+                       (const uint8_t *)kTLS13LabelClientHandshakeTraffic,
+                       strlen(kTLS13LabelClientHandshakeTraffic)) &&
+         ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
+                        hs->client_handshake_secret, hs->hash_len) &&
+         derive_secret(hs, hs->server_handshake_secret, hs->hash_len,
+                       (const uint8_t *)kTLS13LabelServerHandshakeTraffic,
+                       strlen(kTLS13LabelServerHandshakeTraffic)) &&
+         ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
+                        hs->server_handshake_secret, hs->hash_len);
 }
 
 static const char kTLS13LabelExporter[] = "exporter master secret";
diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c
index 1aca634..7181f46 100644
--- a/ssl/tls13_server.c
+++ b/ssl/tls13_server.c
@@ -404,7 +404,11 @@
 
 static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (!tls13_set_handshake_traffic(hs)) {
+  if (!tls13_derive_handshake_secrets(hs) ||
+      !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
+                             hs->hash_len) ||
+      !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
+                             hs->hash_len)) {
     return ssl_hs_error;
   }