Add TLS 1.3 1-RTT.

This adds the machinery for doing TLS 1.3 1RTT.

Change-Id: I736921ffe9dc6f6e64a08a836df6bb166d20f504
Reviewed-on: https://boringssl-review.googlesource.com/8720
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/t1_lib.c b/ssl/t1_lib.c
index 9761dc9..9143ba8 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -808,6 +808,10 @@
 
 static int ext_ri_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
+  if (contents != NULL && ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 0;
+  }
+
   /* Servers may not switch between omitting the extension and supporting it.
    * See RFC 5746, sections 3.5 and 4.2. */
   if (ssl->s3->initial_handshake_complete &&
@@ -877,6 +881,10 @@
    * called after the initial handshake. */
   assert(!ssl->s3->initial_handshake_complete);
 
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 1;
+  }
+
   CBS fake_contents;
   static const uint8_t kFakeExtension[] = {0};
 
@@ -917,6 +925,10 @@
 }
 
 static int ext_ri_add_serverhello(SSL *ssl, CBB *out) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 1;
+  }
+
   CBB contents, prev_finished;
   if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
       !CBB_add_u16_length_prefixed(out, &contents) ||
@@ -960,7 +972,12 @@
     return 1;
   }
 
-  if (ssl->version == SSL3_VERSION || CBS_len(contents) != 0) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
+      ssl->version == SSL3_VERSION) {
+    return 0;
+  }
+
+  if (CBS_len(contents) != 0) {
     return 0;
   }
 
@@ -970,7 +987,12 @@
 
 static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
-  if (ssl->version == SSL3_VERSION || contents == NULL) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
+      ssl->version == SSL3_VERSION) {
+    return 1;
+  }
+
+  if (contents == NULL) {
     return 1;
   }
 
@@ -1038,6 +1060,10 @@
     return 1;
   }
 
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 0;
+  }
+
   /* If |SSL_OP_NO_TICKET| is set then no extension will have been sent and
    * this function should never be called, even if the server tries to send the
    * extension. */
@@ -1185,6 +1211,10 @@
 }
 
 static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 1;
+  }
+
   /* The extension shouldn't be sent when resuming sessions. */
   if (ssl->hit ||
       !ssl->s3->tmp.ocsp_stapling_requested ||
@@ -1229,6 +1259,10 @@
     return 1;
   }
 
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 0;
+  }
+
   /* If any of these are false then we should never have sent the NPN
    * extension in the ClientHello and thus this function should never have been
    * called. */
@@ -1279,6 +1313,10 @@
 
 static int ext_npn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 1;
+  }
+
   if (contents != NULL && CBS_len(contents) != 0) {
     return 0;
   }
@@ -1555,6 +1593,10 @@
     return 1;
   }
 
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 0;
+  }
+
   assert(!SSL_IS_DTLS(ssl));
   assert(ssl->tlsext_channel_id_enabled);
 
@@ -1583,6 +1625,10 @@
 }
 
 static int ext_channel_id_add_serverhello(SSL *ssl, CBB *out) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 1;
+  }
+
   if (!ssl->s3->tlsext_channel_id_valid) {
     return 1;
   }
@@ -1801,6 +1847,10 @@
     return 1;
   }
 
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 0;
+  }
+
   CBS ec_point_format_list;
   if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) ||
       CBS_len(contents) != 0) {
@@ -1820,10 +1870,18 @@
 
 static int ext_ec_point_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                           CBS *contents) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 1;
+  }
+
   return ext_ec_point_parse_serverhello(ssl, out_alert, contents);
 }
 
 static int ext_ec_point_add_serverhello(SSL *ssl, CBB *out) {
+  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+    return 1;
+  }
+
   const uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
   const uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
   const int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
@@ -1836,6 +1894,182 @@
 }
 
 
+/* Draft Version Extension */
+
+static int ext_draft_version_add_clienthello(SSL *ssl, CBB *out) {
+  uint16_t min_version, max_version;
+  if (!ssl_get_version_range(ssl, &min_version, &max_version) ||
+      max_version >= TLS1_3_VERSION) {
+    return 1;
+  }
+
+  CBB contents;
+  if (!CBB_add_u16(out, TLSEXT_TYPE_draft_version) ||
+      !CBB_add_u16_length_prefixed(out, &contents) ||
+      !CBB_add_u16(&contents, TLS1_3_DRAFT_VERSION)) {
+    return 0;
+  }
+
+  return CBB_flush(out);
+}
+
+
+/* Key Share
+ *
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-12 */
+
+static int ext_key_share_add_clienthello(SSL *ssl, CBB *out) {
+  uint16_t min_version, max_version;
+  if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+    return 0;
+  }
+
+  if (max_version < TLS1_3_VERSION || !ssl_any_ec_cipher_suites_enabled(ssl)) {
+    return 1;
+  }
+
+  CBB contents, kse_bytes;
+  if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) ||
+      !CBB_add_u16_length_prefixed(out, &contents) ||
+      !CBB_add_u16_length_prefixed(&contents, &kse_bytes)) {
+    return 0;
+  }
+
+  const uint16_t *groups;
+  size_t groups_len;
+  tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
+
+  ssl->s3->hs->groups = OPENSSL_malloc(groups_len * sizeof(SSL_ECDH_CTX));
+  if (ssl->s3->hs->groups == NULL) {
+    return 0;
+  }
+  memset(ssl->s3->hs->groups, 0, groups_len * sizeof(SSL_ECDH_CTX));
+  ssl->s3->hs->groups_len = groups_len;
+
+  for (size_t i = 0; i < groups_len; i++) {
+    if (!CBB_add_u16(&kse_bytes, groups[i])) {
+      return 0;
+    }
+
+    CBB key_exchange;
+    if (!CBB_add_u16_length_prefixed(&kse_bytes, &key_exchange) ||
+        !SSL_ECDH_CTX_init(&ssl->s3->hs->groups[i], groups[i]) ||
+        !SSL_ECDH_CTX_offer(&ssl->s3->hs->groups[i], &key_exchange) ||
+        !CBB_flush(&kse_bytes)) {
+      return 0;
+    }
+  }
+
+  return CBB_flush(out);
+}
+
+int ext_key_share_parse_serverhello(SSL *ssl, uint8_t **out_secret,
+                                    size_t *out_secret_len, uint8_t *out_alert,
+                                    CBS *contents) {
+  CBS peer_key;
+  uint16_t group;
+  if (!CBS_get_u16(contents, &group) ||
+      !CBS_get_u16_length_prefixed(contents, &peer_key)) {
+    *out_alert = SSL_AD_DECODE_ERROR;
+    return 0;
+  }
+
+  SSL_ECDH_CTX *group_ctx = NULL;
+  for (size_t i = 0; i < ssl->s3->hs->groups_len; i++) {
+    if (SSL_ECDH_CTX_get_id(&ssl->s3->hs->groups[i]) == group) {
+      group_ctx = &ssl->s3->hs->groups[i];
+      break;
+    }
+  }
+
+  if (group_ctx == NULL) {
+    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
+    return 0;
+  }
+
+  if (!SSL_ECDH_CTX_finish(group_ctx, out_secret, out_secret_len, out_alert,
+                           CBS_data(&peer_key), CBS_len(&peer_key))) {
+    *out_alert = SSL_AD_INTERNAL_ERROR;
+    return 0;
+  }
+
+  for (size_t i = 0; i < ssl->s3->hs->groups_len; i++) {
+    SSL_ECDH_CTX_cleanup(&ssl->s3->hs->groups[i]);
+  }
+  OPENSSL_free(ssl->s3->hs->groups);
+  ssl->s3->hs->groups = NULL;
+
+  return 1;
+}
+
+int ext_key_share_parse_clienthello(SSL *ssl, uint8_t **out_secret,
+                                    size_t *out_secret_len, uint8_t *out_alert,
+                                    CBS *contents) {
+  uint16_t group_id;
+  CBS key_shares;
+  if (!tls1_get_shared_group(ssl, &group_id) ||
+      !CBS_get_u16_length_prefixed(contents, &key_shares)) {
+    return 0;
+  }
+
+  int found = 0;
+  while (CBS_len(&key_shares) > 0) {
+    uint16_t id;
+    CBS peer_key;
+    if (!CBS_get_u16(&key_shares, &id) ||
+        !CBS_get_u16_length_prefixed(&key_shares, &peer_key)) {
+      return 0;
+    }
+
+    if (id != group_id || found) {
+      continue;
+    }
+
+    SSL_ECDH_CTX group;
+    memset(&group, 0, sizeof(SSL_ECDH_CTX));
+    CBB public_key;
+    if (!CBB_init(&public_key, 0) ||
+        !SSL_ECDH_CTX_init(&group, group_id) ||
+        !SSL_ECDH_CTX_accept(&group, &public_key, out_secret, out_secret_len,
+                             out_alert, CBS_data(&peer_key),
+                             CBS_len(&peer_key)) ||
+        !CBB_finish(&public_key, &ssl->s3->hs->public_key,
+                    &ssl->s3->hs->public_key_len)) {
+      SSL_ECDH_CTX_cleanup(&group);
+      CBB_cleanup(&public_key);
+      return 0;
+    }
+    SSL_ECDH_CTX_cleanup(&group);
+
+    found = 1;
+  }
+
+  return found;
+}
+
+int ext_key_share_add_serverhello(SSL *ssl, CBB *out) {
+  if (ssl->s3->tmp.new_cipher->algorithm_mkey != SSL_kECDHE) {
+    return 1;
+  }
+
+  uint16_t group_id;
+  CBB kse_bytes, public_key;
+  if (!tls1_get_shared_group(ssl, &group_id) ||
+      !CBB_add_u16(out, TLSEXT_TYPE_key_share) ||
+      !CBB_add_u16_length_prefixed(out, &kse_bytes) ||
+      !CBB_add_u16(&kse_bytes, group_id) ||
+      !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) ||
+      !CBB_add_bytes(&public_key, ssl->s3->hs->public_key,
+                     ssl->s3->hs->public_key_len) ||
+      !CBB_flush(out)) {
+    return 0;
+  }
+
+  return 1;
+}
+
+
 /* Negotiated Groups
  *
  * https://tools.ietf.org/html/rfc4492#section-5.1.2
@@ -2029,6 +2263,22 @@
     ext_ec_point_parse_clienthello,
     ext_ec_point_add_serverhello,
   },
+  {
+    TLSEXT_TYPE_draft_version,
+    NULL,
+    ext_draft_version_add_clienthello,
+    forbid_parse_serverhello,
+    ignore_parse_clienthello,
+    dont_add_serverhello,
+  },
+  {
+    TLSEXT_TYPE_key_share,
+    NULL,
+    ext_key_share_add_clienthello,
+    forbid_parse_serverhello,
+    ignore_parse_clienthello,
+    dont_add_serverhello,
+  },
   /* The final extension must be non-empty. WebSphere Application Server 7.0 is
    * intolerant to the last extension being zero-length. See
    * https://crbug.com/363583. */
@@ -2175,8 +2425,9 @@
     goto err;
   }
 
-  /* Discard empty extensions blocks. */
-  if (CBB_len(&extensions) == 0) {
+  /* Discard empty extensions blocks before TLS 1.3. */
+  if (ssl3_protocol_version(ssl) < TLS1_3_VERSION &&
+      CBB_len(&extensions) == 0) {
     CBB_discard_child(out);
   }
 
@@ -2287,57 +2538,58 @@
 OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(uint32_t) * 8, too_many_bits);
 
 static int ssl_scan_serverhello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
-  uint32_t received = 0;
+  /* Before TLS 1.3, ServerHello extensions blocks may be omitted if empty. */
+  if (CBS_len(cbs) == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
+    return 1;
+  }
 
-  if (CBS_len(cbs) != 0) {
-    /* Decode the extensions block and check it is valid. */
-    CBS extensions;
-    if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
-        !tls1_check_duplicate_extensions(&extensions)) {
+  /* Decode the extensions block and check it is valid. */
+  CBS extensions;
+  if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
+      !tls1_check_duplicate_extensions(&extensions)) {
+    *out_alert = SSL_AD_DECODE_ERROR;
+    return 0;
+  }
+
+  uint32_t received = 0;
+  while (CBS_len(&extensions) != 0) {
+    uint16_t type;
+    CBS extension;
+
+    /* Decode the next extension. */
+    if (!CBS_get_u16(&extensions, &type) ||
+        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
       *out_alert = SSL_AD_DECODE_ERROR;
       return 0;
     }
 
+    unsigned ext_index;
+    const struct tls_extension *const ext =
+        tls_extension_find(&ext_index, type);
 
-    while (CBS_len(&extensions) != 0) {
-      uint16_t type;
-      CBS extension;
-
-      /* Decode the next extension. */
-      if (!CBS_get_u16(&extensions, &type) ||
-          !CBS_get_u16_length_prefixed(&extensions, &extension)) {
-        *out_alert = SSL_AD_DECODE_ERROR;
+    if (ext == NULL) {
+      if (!custom_ext_parse_serverhello(ssl, out_alert, type, &extension)) {
         return 0;
       }
+      continue;
+    }
 
-      unsigned ext_index;
-      const struct tls_extension *const ext =
-          tls_extension_find(&ext_index, type);
+    if (!(ssl->s3->tmp.extensions.sent & (1u << ext_index))) {
+      /* If the extension was never sent then it is illegal. */
+      OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+      ERR_add_error_dataf("extension :%u", (unsigned)type);
+      *out_alert = SSL_AD_DECODE_ERROR;
+      return 0;
+    }
 
-      if (ext == NULL) {
-        if (!custom_ext_parse_serverhello(ssl, out_alert, type, &extension)) {
-          return 0;
-        }
-        continue;
-      }
+    received |= (1u << ext_index);
 
-      if (!(ssl->s3->tmp.extensions.sent & (1u << ext_index))) {
-        /* If the extension was never sent then it is illegal. */
-        OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
-        ERR_add_error_dataf("extension :%u", (unsigned)type);
-        *out_alert = SSL_AD_DECODE_ERROR;
-        return 0;
-      }
-
-      received |= (1u << ext_index);
-
-      uint8_t alert = SSL_AD_DECODE_ERROR;
-      if (!ext->parse_serverhello(ssl, &alert, &extension)) {
-        OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
-        ERR_add_error_dataf("extension: %u", (unsigned)type);
-        *out_alert = alert;
-        return 0;
-      }
+    uint8_t alert = SSL_AD_DECODE_ERROR;
+    if (!ext->parse_serverhello(ssl, &alert, &extension)) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
+      ERR_add_error_dataf("extension: %u", (unsigned)type);
+      *out_alert = alert;
+      return 0;
     }
   }