external/boringssl: Sync to 348f0d8db9c2a0eca0503ba654020209c579d552.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/9bbdf5832de8a2d395303c669b594fc61c791f4d..348f0d8db9c2a0eca0503ba654020209c579d552

Test: BoringSSL CTS Presubmits.
Change-Id: I69a8590da0c89a0d66446775fd669e206a46308a
diff --git a/src/ssl/s3_both.cc b/src/ssl/s3_both.cc
index 4d53d53..9c4aa7f 100644
--- a/src/ssl/s3_both.cc
+++ b/src/ssl/s3_both.cc
@@ -187,12 +187,11 @@
 
 void ssl_handshake_free(SSL_HANDSHAKE *hs) { Delete(hs); }
 
-int ssl_check_message_type(SSL *ssl, int type) {
-  if (ssl->s3->tmp.message_type != type) {
+int ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) {
+  if (msg.type != type) {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
     OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
-    ERR_add_error_dataf("got type %d, wanted type %d",
-                        ssl->s3->tmp.message_type, type);
+    ERR_add_error_dataf("got type %d, wanted type %d", msg.type, type);
     return 0;
   }
 
@@ -422,12 +421,13 @@
 
 int ssl3_get_finished(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  int ret = ssl->method->ssl_get_message(ssl);
+  SSLMessage msg;
+  int ret = ssl_read_message(ssl, &msg);
   if (ret <= 0) {
     return ret;
   }
 
-  if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED)) {
+  if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED)) {
     return -1;
   }
 
@@ -437,12 +437,11 @@
   if (!hs->transcript.GetFinishedMAC(finished, &finished_len,
                                      SSL_get_session(ssl), !ssl->server,
                                      ssl3_protocol_version(ssl)) ||
-      !ssl_hash_current_message(hs)) {
+      !ssl_hash_message(hs, msg)) {
     return -1;
   }
 
-  int finished_ok = ssl->init_num == finished_len &&
-                    CRYPTO_memcmp(ssl->init_msg, finished, finished_len) == 0;
+  int finished_ok = CBS_mem_equal(&msg.body, finished, finished_len);
 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
   finished_ok = 1;
 #endif
@@ -469,6 +468,7 @@
     }
   }
 
+  ssl->method->next_message(ssl);
   return 1;
 }
 
@@ -515,6 +515,16 @@
   return kMaxMessageLen;
 }
 
+int ssl_read_message(SSL *ssl, SSLMessage *out) {
+  while (!ssl->method->get_message(ssl, out)) {
+    int ret = ssl->method->read_message(ssl);
+    if (ret <= 0) {
+      return ret;
+    }
+  }
+  return 1;
+}
+
 static int extend_handshake_buffer(SSL *ssl, size_t length) {
   if (!BUF_MEM_reserve(ssl->init_buf, length)) {
     return -1;
@@ -682,7 +692,62 @@
   return 1;
 }
 
-int ssl3_get_message(SSL *ssl) {
+/* TODO(davidben): Remove |out_bytes_needed| and inline into |ssl3_get_message|
+ * when the entire record is copied into |init_buf|. */
+static bool parse_message(SSL *ssl, SSLMessage *out, size_t *out_bytes_needed) {
+  if (ssl->init_buf == NULL) {
+    *out_bytes_needed = 4;
+    return false;
+  }
+
+  CBS cbs;
+  uint32_t len;
+  CBS_init(&cbs, reinterpret_cast<const uint8_t *>(ssl->init_buf->data),
+           ssl->init_buf->length);
+  if (!CBS_get_u8(&cbs, &out->type) ||
+      !CBS_get_u24(&cbs, &len)) {
+    *out_bytes_needed = 4;
+    return false;
+  }
+
+  if (!CBS_get_bytes(&cbs, &out->body, len)) {
+    *out_bytes_needed = 4 + len;
+    return false;
+  }
+
+  CBS_init(&out->raw, reinterpret_cast<const uint8_t *>(ssl->init_buf->data),
+           4 + len);
+  out->is_v2_hello = ssl->s3->is_v2_hello;
+  if (!ssl->s3->has_message) {
+    if (!out->is_v2_hello) {
+      ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE,
+                          CBS_data(&out->raw), CBS_len(&out->raw));
+    }
+    ssl->s3->has_message = 1;
+  }
+  return true;
+}
+
+bool ssl3_get_message(SSL *ssl, SSLMessage *out) {
+  size_t unused;
+  return parse_message(ssl, out, &unused);
+}
+
+int ssl3_read_message(SSL *ssl) {
+  SSLMessage msg;
+  size_t bytes_needed;
+  if (parse_message(ssl, &msg, &bytes_needed)) {
+    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+    return -1;
+  }
+
+  /* Enforce the limit so the peer cannot force us to buffer 16MB. */
+  if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) {
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+    OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+    return -1;
+  }
+
   /* Re-create the handshake buffer if needed. */
   if (ssl->init_buf == NULL) {
     ssl->init_buf = BUF_MEM_new();
@@ -691,85 +756,45 @@
     }
   }
 
+  /* Bypass the record layer for the first message to handle V2ClientHello. */
   if (ssl->server && !ssl->s3->v2_hello_done) {
-    /* Bypass the record layer for the first message to handle V2ClientHello. */
     int ret = read_v2_client_hello(ssl);
-    if (ret <= 0) {
-      return ret;
+    if (ret > 0) {
+      ssl->s3->v2_hello_done = 1;
     }
-    ssl->s3->v2_hello_done = 1;
-  }
-
-  if (ssl->s3->tmp.reuse_message) {
-    /* There must be a current message. */
-    assert(ssl->init_msg != NULL);
-    ssl->s3->tmp.reuse_message = 0;
-  } else {
-    ssl3_release_current_message(ssl, 0 /* don't free buffer */);
-  }
-
-  /* Read the message header, if we haven't yet. */
-  int ret = extend_handshake_buffer(ssl, SSL3_HM_HEADER_LENGTH);
-  if (ret <= 0) {
     return ret;
   }
 
-  /* Parse out the length. Cap it so the peer cannot force us to buffer up to
-   * 2^24 bytes. */
-  const uint8_t *p = (uint8_t *)ssl->init_buf->data;
-  size_t msg_len = (((uint32_t)p[1]) << 16) | (((uint32_t)p[2]) << 8) | p[3];
-  if (msg_len > ssl_max_handshake_message_len(ssl)) {
-    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
-    OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
-    return -1;
-  }
-
-  /* Read the message body, if we haven't yet. */
-  ret = extend_handshake_buffer(ssl, SSL3_HM_HEADER_LENGTH + msg_len);
-  if (ret <= 0) {
-    return ret;
-  }
-
-  /* We have now received a complete message. */
-  if (ssl->init_msg == NULL && !ssl->s3->is_v2_hello) {
-    ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE,
-                        ssl->init_buf->data, ssl->init_buf->length);
-  }
-
-  ssl->s3->tmp.message_type = ((const uint8_t *)ssl->init_buf->data)[0];
-  ssl->init_msg = (uint8_t*)ssl->init_buf->data + SSL3_HM_HEADER_LENGTH;
-  ssl->init_num = ssl->init_buf->length - SSL3_HM_HEADER_LENGTH;
-  return 1;
+  return extend_handshake_buffer(ssl, bytes_needed);
 }
 
-void ssl3_get_current_message(const SSL *ssl, CBS *out) {
-  CBS_init(out, (uint8_t *)ssl->init_buf->data, ssl->init_buf->length);
-}
-
-int ssl_hash_current_message(SSL_HANDSHAKE *hs) {
-  /* V2ClientHellos are hashed implicitly. */
-  if (hs->ssl->s3->is_v2_hello) {
-    return 1;
+bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
+  /* V2ClientHello messages are pre-hashed. */
+  if (msg.is_v2_hello) {
+    return true;
   }
 
-  CBS cbs;
-  hs->ssl->method->get_current_message(hs->ssl, &cbs);
-  return hs->transcript.Update(CBS_data(&cbs), CBS_len(&cbs));
+  return hs->transcript.Update(CBS_data(&msg.raw), CBS_len(&msg.raw));
 }
 
-void ssl3_release_current_message(SSL *ssl, int free_buffer) {
-  if (ssl->init_msg != NULL) {
-    /* |init_buf| never contains data beyond the current message. */
-    assert(SSL3_HM_HEADER_LENGTH + ssl->init_num == ssl->init_buf->length);
-
-    /* Clear the current message. */
-    ssl->init_msg = NULL;
-    ssl->init_num = 0;
-    ssl->init_buf->length = 0;
-    ssl->s3->is_v2_hello = 0;
+void ssl3_next_message(SSL *ssl) {
+  SSLMessage msg;
+  if (!ssl3_get_message(ssl, &msg) ||
+      ssl->init_buf == NULL ||
+      ssl->init_buf->length < CBS_len(&msg.raw)) {
+    assert(0);
+    return;
   }
 
-  if (free_buffer) {
+  OPENSSL_memmove(ssl->init_buf->data, ssl->init_buf->data + CBS_len(&msg.raw),
+                  ssl->init_buf->length - CBS_len(&msg.raw));
+  ssl->init_buf->length -= CBS_len(&msg.raw);
+  ssl->s3->is_v2_hello = 0;
+  ssl->s3->has_message = 0;
+
+  /* Post-handshake messages are rare, so release the buffer after every
+   * message. During the handshake, |on_handshake_complete| will release it. */
+  if (!SSL_in_init(ssl) && ssl->init_buf->length == 0) {
     BUF_MEM_free(ssl->init_buf);
     ssl->init_buf = NULL;
   }