external/boringssl: Sync to 14308731e5446a73ac2258688a9688b524483cb6.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/ee7aa02744a78bf4630913b1c83d0fe36aa45efc..14308731e5446a73ac2258688a9688b524483cb6

Test: BoringSSL CTS Presubmits.
Change-Id: I73bf80fa018c2a65ca9842f1c2f95d64586bdffc
diff --git a/src/crypto/cipher_extra/e_chacha20poly1305.c b/src/crypto/cipher_extra/e_chacha20poly1305.c
index 6cfc856..515b60f 100644
--- a/src/crypto/cipher_extra/e_chacha20poly1305.c
+++ b/src/crypto/cipher_extra/e_chacha20poly1305.c
@@ -124,33 +124,34 @@
   CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
 }
 
-static void poly1305_update_padded_16(poly1305_state *poly1305,
-                                      const uint8_t *data, size_t data_len) {
-  static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
-
-  CRYPTO_poly1305_update(poly1305, data, data_len);
-  if (data_len % 16 != 0) {
-    CRYPTO_poly1305_update(poly1305, padding,
-                           sizeof(padding) - (data_len % 16));
-  }
-}
-
 /* calc_tag fills |tag| with the authentication tag for the given inputs. */
 static void calc_tag(uint8_t tag[POLY1305_TAG_LEN],
                      const struct aead_chacha20_poly1305_ctx *c20_ctx,
                      const uint8_t nonce[12], const uint8_t *ad, size_t ad_len,
-                     const uint8_t *ciphertext, size_t ciphertext_len) {
+                     const uint8_t *ciphertext, size_t ciphertext_len,
+                     const uint8_t *ciphertext_extra,
+                     size_t ciphertext_extra_len) {
   alignas(16) uint8_t poly1305_key[32];
   OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key));
   CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
                    c20_ctx->key, nonce, 0);
 
+  static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
   poly1305_state ctx;
   CRYPTO_poly1305_init(&ctx, poly1305_key);
-  poly1305_update_padded_16(&ctx, ad, ad_len);
-  poly1305_update_padded_16(&ctx, ciphertext, ciphertext_len);
+  CRYPTO_poly1305_update(&ctx, ad, ad_len);
+  if (ad_len % 16 != 0) {
+    CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ad_len % 16));
+  }
+  CRYPTO_poly1305_update(&ctx, ciphertext, ciphertext_len);
+  CRYPTO_poly1305_update(&ctx, ciphertext_extra, ciphertext_extra_len);
+  const size_t ciphertext_total = ciphertext_len + ciphertext_extra_len;
+  if (ciphertext_total % 16 != 0) {
+    CRYPTO_poly1305_update(&ctx, padding,
+                           sizeof(padding) - (ciphertext_total % 16));
+  }
   poly1305_update_length(&ctx, ad_len);
-  poly1305_update_length(&ctx, ciphertext_len);
+  poly1305_update_length(&ctx, ciphertext_total);
   CRYPTO_poly1305_finish(&ctx, tag);
 }
 
@@ -161,6 +162,14 @@
     size_t extra_in_len, const uint8_t *ad, size_t ad_len) {
   const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
 
+  if (extra_in_len + ctx->tag_len < ctx->tag_len) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
+    return 0;
+  }
+  if (max_out_tag_len < ctx->tag_len + extra_in_len) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
+    return 0;
+  }
   if (nonce_len != 12) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
@@ -183,20 +192,43 @@
     return 0;
   }
 
-  alignas(16) uint8_t tag[48];
+  /* The the extra input is given, it is expected to be very short and so is
+   * encrypted byte-by-byte first. */
+  if (extra_in_len) {
+    static const size_t kChaChaBlockSize = 64;
+    uint32_t block_counter = 1 + (in_len / kChaChaBlockSize);
+    size_t offset = in_len % kChaChaBlockSize;
+    uint8_t block[64 /* kChaChaBlockSize */];
+
+    for (size_t done = 0; done < extra_in_len; block_counter++) {
+      memset(block, 0, sizeof(block));
+      CRYPTO_chacha_20(block, block, sizeof(block), c20_ctx->key, nonce,
+                       block_counter);
+      for (size_t i = offset; i < sizeof(block) && done < extra_in_len;
+           i++, done++) {
+        out_tag[done] = extra_in[done] ^ block[i];
+      }
+      offset = 0;
+    }
+  }
+
+  alignas(16) uint8_t tag[48 + 8 + 8];
 
   if (asm_capable()) {
     OPENSSL_memcpy(tag, c20_ctx->key, 32);
     OPENSSL_memset(tag + 32, 0, 4);
     OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
+    OPENSSL_memcpy(tag + 48, &out_tag, sizeof(out_tag));
+    OPENSSL_memcpy(tag + 56, &extra_in_len, sizeof(extra_in_len));
     chacha20_poly1305_seal(out, in, in_len, ad, ad_len, tag);
   } else {
     CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
-    calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len);
+    calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len,
+             out_tag, extra_in_len);
   }
 
-  OPENSSL_memcpy(out_tag, tag, ctx->tag_len);
-  *out_tag_len = ctx->tag_len;
+  OPENSSL_memcpy(out_tag + extra_in_len, tag, ctx->tag_len);
+  *out_tag_len = extra_in_len + ctx->tag_len;
   return 1;
 }
 
@@ -236,7 +268,7 @@
     OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
     chacha20_poly1305_open(out, in, in_len, ad, ad_len, tag);
   } else {
-    calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, in_len);
+    calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0);
     CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
   }
 
@@ -253,7 +285,7 @@
     12,               /* nonce len */
     POLY1305_TAG_LEN, /* overhead */
     POLY1305_TAG_LEN, /* max tag length */
-    0,                /* seal_scatter_supports_extra_in */
+    1,                /* seal_scatter_supports_extra_in */
 
     aead_chacha20_poly1305_init,
     NULL, /* init_with_direction */