Spanify internal EVP_AEAD APIs.

Now all tags and nonces are bssl::Span.

Should prevent issues like I5ca6d7e331659afb4070b2388bab14c169d5865a
from reoccurring (and uncovered none others).

Bug: 383343306
Change-Id: I9024163fb0b65e5838507581f51a1f34aa65d7d3
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/85988
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Rudolf Polzer <rpolzer@google.com>
Auto-Submit: Rudolf Polzer <rpolzer@google.com>
diff --git a/crypto/cipher/e_aesctrhmac.cc b/crypto/cipher/e_aesctrhmac.cc
index 0714464..040b7ad 100644
--- a/crypto/cipher/e_aesctrhmac.cc
+++ b/crypto/cipher/e_aesctrhmac.cc
@@ -175,9 +175,8 @@
 
 static int aead_aes_ctr_hmac_sha256_sealv(
     const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-    uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len,
-    const uint8_t *nonce, size_t nonce_len,
-    bssl::Span<const CRYPTO_IVEC> aadvecs) {
+    bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+    bssl::Span<const uint8_t> nonce, bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx =
       (struct aead_aes_ctr_hmac_sha256_ctx *)&ctx->state;
   const uint64_t in_len_64 = bssl::iovec::TotalLength(iovecs);
@@ -188,23 +187,23 @@
     return 0;
   }
 
-  if (max_out_tag_len < ctx->tag_len) {
+  if (out_tag.size() < ctx->tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
+  if (nonce.size() != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
-  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, iovecs, nonce);
+  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, iovecs, nonce.data());
 
   uint8_t hmac_result[SHA256_DIGEST_LENGTH];
   hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
-                 &aes_ctx->outer_init_state, aadvecs, nonce, iovecs,
+                 &aes_ctx->outer_init_state, aadvecs, nonce.data(), iovecs,
                  /*encrypt=*/true);
-  OPENSSL_memcpy(out_tag, hmac_result, ctx->tag_len);
+  CopyToPrefix(bssl::Span(hmac_result).first(ctx->tag_len), out_tag);
   *out_tag_len = ctx->tag_len;
 
   return 1;
@@ -212,31 +211,31 @@
 
 static int aead_aes_ctr_hmac_sha256_openv_detached(
     const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-    const uint8_t *nonce, size_t nonce_len, const uint8_t *in_tag,
-    size_t in_tag_len, bssl::Span<const CRYPTO_IVEC> aadvecs) {
+    bssl::Span<const uint8_t> nonce, bssl::Span<const uint8_t> in_tag,
+    bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx =
       (struct aead_aes_ctr_hmac_sha256_ctx *)&ctx->state;
 
-  if (in_tag_len != ctx->tag_len) {
+  if (in_tag.size() != ctx->tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
+  if (nonce.size() != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
   uint8_t hmac_result[SHA256_DIGEST_LENGTH];
   hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
-                 &aes_ctx->outer_init_state, aadvecs, nonce, iovecs,
+                 &aes_ctx->outer_init_state, aadvecs, nonce.data(), iovecs,
                  /*encrypt=*/false);
-  if (CRYPTO_memcmp(hmac_result, in_tag, ctx->tag_len) != 0) {
+  if (CRYPTO_memcmp(hmac_result, in_tag.data(), ctx->tag_len) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
-  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, iovecs, nonce);
+  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, iovecs, nonce.data());
 
   return 1;
 }
diff --git a/crypto/cipher/e_aeseax.cc b/crypto/cipher/e_aeseax.cc
index 7f7e3f6..d6964b2 100644
--- a/crypto/cipher/e_aeseax.cc
+++ b/crypto/cipher/e_aeseax.cc
@@ -217,19 +217,18 @@
 
 static int aead_aes_eax_sealv(const EVP_AEAD_CTX *ctx,
                               bssl::Span<const CRYPTO_IOVEC> iovecs,
-                              uint8_t *out_tag, size_t *out_tag_len,
-                              size_t max_out_tag_len, const uint8_t *nonce,
-                              size_t nonce_len,
+                              bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+                              bssl::Span<const uint8_t> nonce,
                               bssl::Span<const CRYPTO_IVEC> aadvecs) {
   // We use the full 128 bits of the nonce as counter, so no need to check the
   // plaintext size.
 
-  if (max_out_tag_len < ctx->tag_len) {
+  if (out_tag.size() < ctx->tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (nonce_len != 12 && nonce_len != 16) {
+  if (nonce.size() != 12 && nonce.size() != 16) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
@@ -240,8 +239,8 @@
   // N <- OMAC(0 || nonce)
   uint8_t n[AES_BLOCK_SIZE];
   CRYPTO_IVEC noncevec[1];
-  noncevec[0].in = nonce;
-  noncevec[0].len = nonce_len;
+  noncevec[0].in = nonce.data();
+  noncevec[0].len = nonce.size();
   omac_with_tag(aes_ctx, n, bssl::Span<const CRYPTO_IVEC>(noncevec), /*tag=*/0);
   // H <- OMAC(1 || ad)
   uint8_t h[AES_BLOCK_SIZE];
@@ -251,10 +250,10 @@
   aes_ctr(aes_ctx, iovecs, n);
 
   // MAC <- OMAC(2 || C)
-  omac_with_tag_iovec_out(aes_ctx, out_tag, iovecs, /*tag=*/2);
+  omac_with_tag_iovec_out(aes_ctx, out_tag.data(), iovecs, /*tag=*/2);
   // MAC <- N ^ C ^ H
-  CRYPTO_xor16(out_tag, n, out_tag);
-  CRYPTO_xor16(out_tag, h, out_tag);
+  CRYPTO_xor16(out_tag.data(), n, out_tag.data());
+  CRYPTO_xor16(out_tag.data(), h, out_tag.data());
 
   *out_tag_len = ctx->tag_len;
   return 1;
@@ -262,8 +261,8 @@
 
 static int aead_aes_eax_openv_detached(const EVP_AEAD_CTX *ctx,
                                        bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                       const uint8_t *nonce, size_t nonce_len,
-                                       const uint8_t *in_tag, size_t in_tag_len,
+                                       bssl::Span<const uint8_t> nonce,
+                                       bssl::Span<const uint8_t> in_tag,
                                        bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const uint64_t ad_len_64 = bssl::iovec::TotalLength(aadvecs);
   if (ad_len_64 >= (UINT64_C(1) << 61)) {
@@ -272,13 +271,13 @@
   }
 
   const uint64_t in_len_64 = bssl::iovec::TotalLength(iovecs);
-  if (in_tag_len != EVP_AEAD_AES_EAX_TAG_LEN ||
+  if (in_tag.size() != EVP_AEAD_AES_EAX_TAG_LEN ||
       in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
-  if (nonce_len != 12 && nonce_len != 16) {
+  if (nonce.size() != 12 && nonce.size() != 16) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
@@ -289,8 +288,8 @@
   // N <- OMAC(0 || nonce)
   uint8_t n[AES_BLOCK_SIZE];
   CRYPTO_IVEC noncevec[1];
-  noncevec[0].in = nonce;
-  noncevec[0].len = nonce_len;
+  noncevec[0].in = nonce.data();
+  noncevec[0].len = nonce.size();
   omac_with_tag(aes_ctx, n, bssl::Span<const CRYPTO_IVEC>(noncevec),
                 /*tag=*/0);
   // H <- OMAC(1 || ad)
@@ -304,7 +303,7 @@
   CRYPTO_xor16(mac, n, mac);
   CRYPTO_xor16(mac, h, mac);
 
-  if (CRYPTO_memcmp(mac, in_tag, in_tag_len) != 0) {
+  if (CRYPTO_memcmp(mac, in_tag.data(), in_tag.size()) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
diff --git a/crypto/cipher/e_aesgcmsiv.cc b/crypto/cipher/e_aesgcmsiv.cc
index e8f2ace..2b56baf 100644
--- a/crypto/cipher/e_aesgcmsiv.cc
+++ b/crypto/cipher/e_aesgcmsiv.cc
@@ -342,9 +342,8 @@
 
 int aead_aes_gcm_siv_asm_sealv(const EVP_AEAD_CTX *ctx,
                                bssl::Span<const CRYPTO_IOVEC> iovecs,
-                               uint8_t *out_tag, size_t *out_tag_len,
-                               size_t max_out_tag_len, const uint8_t *nonce,
-                               size_t nonce_len,
+                               bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+                               bssl::Span<const uint8_t> nonce,
                                bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = asm_ctx_from_ctx(ctx);
   const size_t in_len = bssl::iovec::TotalLength(iovecs);
@@ -357,12 +356,12 @@
     return 0;
   }
 
-  if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
+  if (out_tag.size() < EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
+  if (nonce.size() != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
@@ -370,11 +369,11 @@
   alignas(16) uint64_t record_auth_key[2];
   alignas(16) uint64_t record_enc_key[4];
   aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key,
-                       record_enc_key, nonce);
+                       record_enc_key, nonce.data());
 
   alignas(16) uint8_t tag[16] = {0};
   gcm_siv_asm_polyval(tag, iovecs, aadvecs, (const uint8_t *)record_auth_key,
-                      nonce);
+                      nonce.data());
 
   struct aead_aes_gcm_siv_asm_ctx enc_key_expanded;
 
@@ -458,7 +457,7 @@
         });
   }
 
-  OPENSSL_memcpy(out_tag, tag, sizeof(tag));
+  CopyToPrefix(tag, out_tag);
   *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN;
 
   return 1;
@@ -466,9 +465,8 @@
 
 int aead_aes_gcm_siv_asm_openv_detached(const EVP_AEAD_CTX *ctx,
                                         bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                        const uint8_t *nonce, size_t nonce_len,
-                                        const uint8_t *in_tag,
-                                        size_t in_tag_len,
+                                        bssl::Span<const uint8_t> nonce,
+                                        bssl::Span<const uint8_t> in_tag,
                                         bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const size_t ad_len = bssl::iovec::TotalLength(aadvecs);
   const uint64_t ad_len_64 = ad_len;
@@ -480,12 +478,12 @@
   const size_t in_len = bssl::iovec::TotalLength(iovecs);
   const uint64_t in_len_64 = in_len;
   if (in_len_64 > UINT64_C(1) << 36 ||
-      in_tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
+      in_tag.size() != EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
+  if (nonce.size() != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
@@ -495,7 +493,7 @@
   alignas(16) uint64_t record_auth_key[2];
   alignas(16) uint64_t record_enc_key[4];
   aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key,
-                       record_enc_key, nonce);
+                       record_enc_key, nonce.data());
 
   struct aead_aes_gcm_siv_asm_ctx expanded_key;
   if (gcm_siv_ctx->is_128_bit) {
@@ -545,7 +543,7 @@
         // aes[128|256]gcmsiv_dec needs access to the claimed tag. So it's put
         // into its scratch space. The function may clobber the claimed tag, so
         // this is copied before each call.
-        OPENSSL_memcpy(calculated_tag + 16, in_tag,
+        OPENSSL_memcpy(calculated_tag + 16, in_tag.data(),
                        EVP_AEAD_AES_GCM_SIV_TAG_LEN);
         inc_counter(calculated_tag + 16, static_cast<uint32_t>(blocks));
         if (gcm_siv_ctx->is_128_bit) {
@@ -562,7 +560,7 @@
           // aes[128|256]gcmsiv_dec needs access to the claimed tag. So it's put
           // into its scratch space. The function may clobber the claimed tag,
           // so this is copied before each call.
-          OPENSSL_memcpy(calculated_tag + 16, in_tag,
+          OPENSSL_memcpy(calculated_tag + 16, in_tag.data(),
                          EVP_AEAD_AES_GCM_SIV_TAG_LEN);
           inc_counter(calculated_tag + 16, static_cast<uint32_t>(blocks));
           if (gcm_siv_ctx->is_128_bit) {
@@ -578,8 +576,8 @@
         }
         if (len != 0) {
           aead_aes_gcm_siv_asm_crypt_last_block(
-              gcm_siv_ctx->is_128_bit, /*last_block_out=*/out,
-              /*last_block_in=*/in, /*total_in_len=*/in_len, in_tag,
+              gcm_siv_ctx->is_128_bit, /*out_last_block=*/out,
+              /*in_last_block=*/in, /*total_in_len=*/in_len, in_tag.data(),
               &expanded_key);
           uint8_t pad_buf[AES_BLOCK_SIZE];
           OPENSSL_memcpy(pad_buf, out, len);
@@ -608,8 +606,8 @@
     aes256gcmsiv_ecb_enc_block(calculated_tag, calculated_tag, &expanded_key);
   }
 
-  if (CRYPTO_memcmp(calculated_tag, in_tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN) !=
-      0) {
+  if (CRYPTO_memcmp(calculated_tag, in_tag.data(),
+                    EVP_AEAD_AES_GCM_SIV_TAG_LEN) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
@@ -919,9 +917,8 @@
 
 int aead_aes_gcm_siv_sealv(const EVP_AEAD_CTX *ctx,
                            bssl::Span<const CRYPTO_IOVEC> iovecs,
-                           uint8_t *out_tag, size_t *out_tag_len,
-                           size_t max_out_tag_len, const uint8_t *nonce,
-                           size_t nonce_len,
+                           bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+                           bssl::Span<const uint8_t> nonce,
                            bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx =
       (struct aead_aes_gcm_siv_ctx *)&ctx->state;
@@ -936,26 +933,26 @@
     return 0;
   }
 
-  if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
+  if (out_tag.size() < EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
+  if (nonce.size() != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
   struct gcm_siv_record_keys keys;
-  gcm_siv_keys(gcm_siv_ctx, &keys, nonce);
+  gcm_siv_keys(gcm_siv_ctx, &keys, nonce.data());
 
-  uint8_t tag[16];
-  gcm_siv_polyval(tag, iovecs, true, aadvecs, keys.auth_key, nonce);
+  uint8_t tag[EVP_AEAD_AES_GCM_SIV_TAG_LEN];
+  gcm_siv_polyval(tag, iovecs, true, aadvecs, keys.auth_key, nonce.data());
   keys.enc_block(tag, tag, &keys.enc_key.ks);
 
   gcm_siv_crypt(iovecs, tag, keys.enc_block, &keys.enc_key.ks);
 
-  OPENSSL_memcpy(out_tag, tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN);
+  CopyToPrefix(tag, out_tag);
   *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN;
 
   return 1;
@@ -963,8 +960,8 @@
 
 int aead_aes_gcm_siv_openv_detached(const EVP_AEAD_CTX *ctx,
                                     bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                    const uint8_t *nonce, size_t nonce_len,
-                                    const uint8_t *in_tag, size_t in_tag_len,
+                                    bssl::Span<const uint8_t> nonce,
+                                    bssl::Span<const uint8_t> in_tag,
                                     bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const uint64_t ad_len_64 = bssl::iovec::TotalLength(aadvecs);
   if (ad_len_64 >= (UINT64_C(1) << 61)) {
@@ -973,13 +970,13 @@
   }
 
   const uint64_t in_len_64 = bssl::iovec::TotalLength(iovecs);
-  if (in_tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN ||
+  if (in_tag.size() != EVP_AEAD_AES_GCM_SIV_TAG_LEN ||
       in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
+  if (nonce.size() != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
@@ -988,15 +985,16 @@
       (struct aead_aes_gcm_siv_ctx *)&ctx->state;
 
   struct gcm_siv_record_keys keys;
-  gcm_siv_keys(gcm_siv_ctx, &keys, nonce);
+  gcm_siv_keys(gcm_siv_ctx, &keys, nonce.data());
 
-  gcm_siv_crypt(iovecs, in_tag, keys.enc_block, &keys.enc_key.ks);
+  gcm_siv_crypt(iovecs, in_tag.data(), keys.enc_block, &keys.enc_key.ks);
 
   uint8_t expected_tag[EVP_AEAD_AES_GCM_SIV_TAG_LEN];
-  gcm_siv_polyval(expected_tag, iovecs, false, aadvecs, keys.auth_key, nonce);
+  gcm_siv_polyval(expected_tag, iovecs, false, aadvecs, keys.auth_key,
+                  nonce.data());
   keys.enc_block(expected_tag, expected_tag, &keys.enc_key.ks);
 
-  if (CRYPTO_memcmp(expected_tag, in_tag, sizeof(expected_tag)) != 0) {
+  if (CRYPTO_memcmp(expected_tag, in_tag.data(), sizeof(expected_tag)) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
diff --git a/crypto/cipher/e_chacha20poly1305.cc b/crypto/cipher/e_chacha20poly1305.cc
index 9a8b200..0607707 100644
--- a/crypto/cipher/e_chacha20poly1305.cc
+++ b/crypto/cipher/e_chacha20poly1305.cc
@@ -112,15 +112,18 @@
   CRYPTO_poly1305_finish(ctx, tag);
 }
 
-static int chacha20_poly1305_sealv(
-    const uint8_t *key, bssl::Span<const CRYPTO_IOVEC> iovecs, uint8_t *out_tag,
-    size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce,
-    size_t nonce_len, bssl::Span<const CRYPTO_IVEC> aadvecs, size_t tag_len) {
-  if (max_out_tag_len < tag_len) {
+static int chacha20_poly1305_sealv(const uint8_t *key,
+                                   bssl::Span<const CRYPTO_IOVEC> iovecs,
+                                   bssl::Span<uint8_t> out_tag,
+                                   size_t *out_tag_len,
+                                   bssl::Span<const uint8_t> nonce,
+                                   bssl::Span<const CRYPTO_IVEC> aadvecs,
+                                   size_t tag_len) {
+  if (out_tag.size() < tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
-  if (nonce_len != 12) {
+  if (nonce.size() != 12) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
@@ -142,7 +145,7 @@
       aadvecs.size() <= 1) {
     OPENSSL_memcpy(data.in.key, key, 32);
     data.in.counter = 0;
-    OPENSSL_memcpy(data.in.nonce, nonce, 12);
+    CopySpan(nonce, data.in.nonce);
     if (iovecs.size() >= 2) {
       // |chacha20_poly1305_seal| only supports one extra input and expects it
       // to have been encrypted ahead of time. (Historically it was only used
@@ -155,7 +158,7 @@
       if (offset != 0) {
         uint8_t block[kChaChaBlockSize];
         memset(block, 0, sizeof(block));
-        CRYPTO_chacha_20(block, block, sizeof(block), key, nonce,
+        CRYPTO_chacha_20(block, block, sizeof(block), key, nonce.data(),
                          block_counter);
         for (size_t i = offset; i < sizeof(block) && done < iovecs[1].len;
              i++, done++) {
@@ -165,7 +168,8 @@
       }
       if (done < iovecs[1].len) {
         CRYPTO_chacha_20(iovecs[1].out + done, iovecs[1].in + done,
-                         iovecs[1].len - done, key, nonce, block_counter);
+                         iovecs[1].len - done, key, nonce.data(),
+                         block_counter);
       }
       // TODO(crbug.com/383343306): Support more than 1 extra ciphertext.
       data.in.extra_ciphertext = iovecs[1].out;
@@ -181,7 +185,7 @@
                            aadvecs.size() >= 1 ? aadvecs[0].len : 0, &data);
   } else {
     poly1305_state ctx;
-    size_t ad_len = calc_tag_pre(&ctx, key, nonce, aadvecs);
+    size_t ad_len = calc_tag_pre(&ctx, key, nonce.data(), aadvecs);
 
     size_t ciphertext_total = 0;
     size_t block = 1;
@@ -190,7 +194,7 @@
         [&](const uint8_t *in, uint8_t *out, size_t len) {
           // TODO(crbug.com/383343306): Maybe just provide asm version of this?
           // Here, len is always a multiple of 64.
-          CRYPTO_chacha_20(out, in, len, key, nonce, block);
+          CRYPTO_chacha_20(out, in, len, key, nonce.data(), block);
           CRYPTO_poly1305_update(&ctx, out, len);
           ciphertext_total += len;
           block += len / 64;
@@ -199,7 +203,7 @@
         [&](const uint8_t *in, uint8_t *out, size_t len) {
           // Here, len may be anything. If an asm version can't handle that,
           // it will be worth splitting off multiples of 64 here.
-          CRYPTO_chacha_20(out, in, len, key, nonce, block);
+          CRYPTO_chacha_20(out, in, len, key, nonce.data(), block);
           CRYPTO_poly1305_update(&ctx, out, len);
           ciphertext_total += len;
           return true;
@@ -208,59 +212,56 @@
     calc_tag_post(&ctx, data.out.tag, ciphertext_total, ad_len);
   }
 
-  OPENSSL_memcpy(out_tag, data.out.tag, tag_len);
+  CopyToPrefix(bssl::Span(data.out.tag).first(tag_len), out_tag);
   *out_tag_len = tag_len;
   return 1;
 }
 
 static int aead_chacha20_poly1305_sealv(const EVP_AEAD_CTX *ctx,
                                         bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                        uint8_t *out_tag, size_t *out_tag_len,
-                                        size_t max_out_tag_len,
-                                        const uint8_t *nonce, size_t nonce_len,
+                                        bssl::Span<uint8_t> out_tag,
+                                        size_t *out_tag_len,
+                                        bssl::Span<const uint8_t> nonce,
                                         bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_chacha20_poly1305_ctx *c20_ctx =
       (struct aead_chacha20_poly1305_ctx *)&ctx->state;
 
   return chacha20_poly1305_sealv(c20_ctx->key, iovecs, out_tag, out_tag_len,
-                                 max_out_tag_len, nonce, nonce_len, aadvecs,
-                                 ctx->tag_len);
+                                 nonce, aadvecs, ctx->tag_len);
 }
 
 static int aead_xchacha20_poly1305_sealv(
     const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-    uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len,
-    const uint8_t *nonce, size_t nonce_len,
-    bssl::Span<const CRYPTO_IVEC> aadvecs) {
+    bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+    bssl::Span<const uint8_t> nonce, bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_chacha20_poly1305_ctx *c20_ctx =
       (struct aead_chacha20_poly1305_ctx *)&ctx->state;
 
-  if (nonce_len != 24) {
+  if (nonce.size() != 24) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
   alignas(4) uint8_t derived_key[32];
   alignas(4) uint8_t derived_nonce[12];
-  CRYPTO_hchacha20(derived_key, c20_ctx->key, nonce);
+  CRYPTO_hchacha20(derived_key, c20_ctx->key, nonce.data());
   OPENSSL_memset(derived_nonce, 0, 4);
   OPENSSL_memcpy(&derived_nonce[4], &nonce[16], 8);
 
   return chacha20_poly1305_sealv(derived_key, iovecs, out_tag, out_tag_len,
-                                 max_out_tag_len, derived_nonce,
-                                 sizeof(derived_nonce), aadvecs, ctx->tag_len);
+                                 derived_nonce, aadvecs, ctx->tag_len);
 }
 
 static int chacha20_poly1305_openv_detached(
     const uint8_t *key, bssl::Span<const CRYPTO_IOVEC> iovecs,
-    const uint8_t *nonce, size_t nonce_len, const uint8_t *in_tag,
-    size_t in_tag_len, bssl::Span<const CRYPTO_IVEC> aadvecs, size_t tag_len) {
-  if (nonce_len != 12) {
+    bssl::Span<const uint8_t> nonce, bssl::Span<const uint8_t> in_tag,
+    bssl::Span<const CRYPTO_IVEC> aadvecs, size_t tag_len) {
+  if (nonce.size() != 12) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
-  if (in_tag_len != tag_len) {
+  if (in_tag.size() != tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
@@ -283,7 +284,7 @@
     // TODO(crbug.com/383343306): Support more than 1 ciphertext segment.
     OPENSSL_memcpy(data.in.key, key, 32);
     data.in.counter = 0;
-    OPENSSL_memcpy(data.in.nonce, nonce, 12);
+    CopySpan(nonce, data.in.nonce);
     chacha20_poly1305_open(iovecs.size() >= 1 ? iovecs[0].out : nullptr,
                            iovecs.size() >= 1 ? iovecs[0].in : nullptr,
                            iovecs.size() >= 1 ? iovecs[0].len : 0,
@@ -291,7 +292,7 @@
                            aadvecs.size() >= 1 ? aadvecs[0].len : 0, &data);
   } else {
     poly1305_state ctx;
-    size_t ad_len = calc_tag_pre(&ctx, key, nonce, aadvecs);
+    size_t ad_len = calc_tag_pre(&ctx, key, nonce.data(), aadvecs);
 
     size_t ciphertext_total = 0;
     size_t block = 1;
@@ -301,7 +302,7 @@
           // TODO(crbug.com/383343306): Maybe just provide asm version of this?
           // Here, len is always a multiple of 64.
           CRYPTO_poly1305_update(&ctx, in, len);
-          CRYPTO_chacha_20(out, in, len, key, nonce, block);
+          CRYPTO_chacha_20(out, in, len, key, nonce.data(), block);
           ciphertext_total += len;
           block += len / 64;
           return true;
@@ -310,7 +311,7 @@
           // Here, len may be anything. If an asm version can't handle that,
           // it will be worth splitting off multiples of 64 here.
           CRYPTO_poly1305_update(&ctx, in, len);
-          CRYPTO_chacha_20(out, in, len, key, nonce, block);
+          CRYPTO_chacha_20(out, in, len, key, nonce.data(), block);
           ciphertext_total += len;
           return true;
         });
@@ -318,7 +319,7 @@
     calc_tag_post(&ctx, data.out.tag, ciphertext_total, ad_len);
   }
 
-  if (CRYPTO_memcmp(data.out.tag, in_tag, tag_len) != 0) {
+  if (CRYPTO_memcmp(data.out.tag, in_tag.data(), tag_len) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
@@ -328,37 +329,35 @@
 
 static int aead_chacha20_poly1305_openv_detached(
     const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-    const uint8_t *nonce, size_t nonce_len, const uint8_t *in_tag,
-    size_t in_tag_len, bssl::Span<const CRYPTO_IVEC> aadvecs) {
+    bssl::Span<const uint8_t> nonce, bssl::Span<const uint8_t> in_tag,
+    bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_chacha20_poly1305_ctx *c20_ctx =
       (struct aead_chacha20_poly1305_ctx *)&ctx->state;
 
-  return chacha20_poly1305_openv_detached(c20_ctx->key, iovecs, nonce,
-                                          nonce_len, in_tag, in_tag_len,
+  return chacha20_poly1305_openv_detached(c20_ctx->key, iovecs, nonce, in_tag,
                                           aadvecs, ctx->tag_len);
 }
 
 static int aead_xchacha20_poly1305_openv_detached(
     const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-    const uint8_t *nonce, size_t nonce_len, const uint8_t *in_tag,
-    size_t in_tag_len, bssl::Span<const CRYPTO_IVEC> aadvecs) {
+    bssl::Span<const uint8_t> nonce, bssl::Span<const uint8_t> in_tag,
+    bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_chacha20_poly1305_ctx *c20_ctx =
       (struct aead_chacha20_poly1305_ctx *)&ctx->state;
 
-  if (nonce_len != 24) {
+  if (nonce.size() != 24) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
   alignas(4) uint8_t derived_key[32];
   alignas(4) uint8_t derived_nonce[12];
-  CRYPTO_hchacha20(derived_key, c20_ctx->key, nonce);
+  CRYPTO_hchacha20(derived_key, c20_ctx->key, nonce.data());
   OPENSSL_memset(derived_nonce, 0, 4);
   OPENSSL_memcpy(&derived_nonce[4], &nonce[16], 8);
 
   return chacha20_poly1305_openv_detached(derived_key, iovecs, derived_nonce,
-                                          sizeof(derived_nonce), in_tag,
-                                          in_tag_len, aadvecs, ctx->tag_len);
+                                          in_tag, aadvecs, ctx->tag_len);
 }
 
 static const EVP_AEAD aead_chacha20_poly1305 = {
diff --git a/crypto/cipher/e_tls.cc b/crypto/cipher/e_tls.cc
index 4142d8d..c037f04 100644
--- a/crypto/cipher/e_tls.cc
+++ b/crypto/cipher/e_tls.cc
@@ -115,9 +115,8 @@
 
 static int aead_tls_sealv(const EVP_AEAD_CTX *ctx,
                           bssl::Span<const CRYPTO_IOVEC> iovecs,
-                          uint8_t *out_tag, size_t *out_tag_len,
-                          const size_t max_out_tag_len, const uint8_t *nonce,
-                          const size_t nonce_len,
+                          bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+                          bssl::Span<const uint8_t> nonce,
                           bssl::Span<const CRYPTO_IVEC> aadvecs) {
   AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state;
 
@@ -128,12 +127,12 @@
   }
 
   size_t in_len = bssl::iovec::TotalLength(iovecs);
-  if (max_out_tag_len < aead_tls_tag_len(ctx, in_len)) {
+  if (out_tag.size() < aead_tls_tag_len(ctx, in_len)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
+  if (nonce.size() != EVP_AEAD_nonce_length(ctx->aead)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
@@ -177,7 +176,7 @@
   assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
   if (!tls_ctx->implicit_iv &&
       !EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, nullptr, nullptr, nullptr,
-                          nonce)) {
+                          nonce.data())) {
     return 0;
   }
 
@@ -228,15 +227,15 @@
             }
             assert(buf_len == block_size);
             OPENSSL_memcpy(out + out_len, buf, remaining);
-            OPENSSL_memcpy(out_tag, buf + remaining, early_mac_len);
+            OPENSSL_memcpy(out_tag.data(), buf + remaining, early_mac_len);
             tag_len = early_mac_len;
             return true;
           })) {
     return 0;
   }
 
-  if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
-                            max_out_tag_len - tag_len, mac + tag_len,
+  if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag.data() + tag_len,
+                            &len, out_tag.size() - tag_len, mac + tag_len,
                             mac_len - tag_len)) {
     return 0;
   }
@@ -246,14 +245,15 @@
   uint8_t padding[256];
   unsigned padding_len = block_size - ((in_len + mac_len) & (block_size - 1));
   OPENSSL_memset(padding, padding_len - 1, padding_len);
-  if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
-                            max_out_tag_len - tag_len, padding, padding_len)) {
+  if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag.data() + tag_len,
+                            &len, out_tag.size() - tag_len, padding,
+                            padding_len)) {
     return 0;
   }
   tag_len += len;
 
-  if (!EVP_EncryptFinal_ex2(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
-                            max_out_tag_len - tag_len)) {
+  if (!EVP_EncryptFinal_ex2(&tls_ctx->cipher_ctx, out_tag.data() + tag_len,
+                            &len, out_tag.size() - tag_len)) {
     return 0;
   }
   assert(len == 0);  // Padding is explicit.
@@ -265,8 +265,8 @@
 
 static int aead_tls_openv(const EVP_AEAD_CTX *ctx,
                           bssl::Span<const CRYPTO_IOVEC> iovecs,
-                          size_t *out_total_bytes, const uint8_t *nonce,
-                          size_t nonce_len,
+                          size_t *out_total_bytes,
+                          bssl::Span<const uint8_t> nonce,
                           bssl::Span<const CRYPTO_IVEC> aadvecs) {
   AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state;
 
@@ -282,7 +282,7 @@
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
+  if (nonce.size() != EVP_AEAD_nonce_length(ctx->aead)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
@@ -297,7 +297,7 @@
   assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
   if (!tls_ctx->implicit_iv &&
       !EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, nullptr, nullptr, nullptr,
-                          nonce)) {
+                          nonce.data())) {
     return 0;
   }
 
diff --git a/crypto/fipsmodule/cipher/aead.cc.inc b/crypto/fipsmodule/cipher/aead.cc.inc
index 91b89ee..188b024 100644
--- a/crypto/fipsmodule/cipher/aead.cc.inc
+++ b/crypto/fipsmodule/cipher/aead.cc.inc
@@ -341,8 +341,8 @@
     return 0;
   }
 
-  if (ctx->aead->sealv(ctx, iovecs, out_tag, out_tag_len, max_out_tag_len,
-                       nonce, nonce_len, aadvecs)) {
+  if (ctx->aead->sealv(ctx, iovecs, bssl::Span(out_tag, max_out_tag_len),
+                       out_tag_len, bssl::Span(nonce, nonce_len), aadvecs)) {
     ok = true;
     return 1;
   }
@@ -496,8 +496,9 @@
         return 0;
       }
 
-      if (ctx->aead->openv_detached(ctx, detached_iovecs, nonce, nonce_len,
-                                    tag->data(), tag->size(), aadvecs)) {
+      if (ctx->aead->openv_detached(ctx, detached_iovecs,
+                                    bssl::Span(nonce, nonce_len), *tag,
+                                    aadvecs)) {
         ok = true;
         *out_total_bytes =
             bssl::iovec::TotalLength(bssl::Span(detached_iovecs));
@@ -510,8 +511,8 @@
     return 0;
   }
 
-  if (ctx->aead->openv(ctx, iovecs, out_total_bytes, nonce, nonce_len,
-                       aadvecs)) {
+  if (ctx->aead->openv(ctx, iovecs, out_total_bytes,
+                       bssl::Span(nonce, nonce_len), aadvecs)) {
     ok = true;
     return 1;
   }
@@ -565,8 +566,8 @@
     return 0;
   }
 
-  if (ctx->aead->openv_detached(ctx, iovecs, nonce, nonce_len, in_tag,
-                                in_tag_len, aadvecs)) {
+  if (ctx->aead->openv_detached(ctx, iovecs, bssl::Span(nonce, nonce_len),
+                                bssl::Span(in_tag, in_tag_len), aadvecs)) {
     ok = true;
     return 1;
   }
diff --git a/crypto/fipsmodule/cipher/e_aes.cc.inc b/crypto/fipsmodule/cipher/e_aes.cc.inc
index 50cbce6..51ee73c 100644
--- a/crypto/fipsmodule/cipher/e_aes.cc.inc
+++ b/crypto/fipsmodule/cipher/e_aes.cc.inc
@@ -759,24 +759,24 @@
 
 static int aead_aes_gcm_sealv_impl(const struct aead_aes_gcm_ctx *gcm_ctx,
                                    bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                   uint8_t *out_tag, size_t *out_tag_len,
-                                   size_t max_out_tag_len, const uint8_t *nonce,
-                                   size_t nonce_len,
+                                   bssl::Span<uint8_t> out_tag,
+                                   size_t *out_tag_len,
+                                   bssl::Span<const uint8_t> nonce,
                                    bssl::Span<const CRYPTO_IVEC> aadvecs,
                                    size_t tag_len) {
-  if (max_out_tag_len < tag_len) {
+  if (out_tag.size() < tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (nonce_len == 0) {
+  if (nonce.size() == 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
   const GCM128_KEY *key = &gcm_ctx->key;
   GCM128_CONTEXT gcm;
-  CRYPTO_gcm128_init_ctx(key, &gcm, nonce, nonce_len);
+  CRYPTO_gcm128_init_ctx(key, &gcm, nonce.data(), nonce.size());
 
   for (const CRYPTO_IVEC &aadvec : aadvecs) {
     if (!CRYPTO_gcm128_aad(key, &gcm, aadvec.in, aadvec.len)) {
@@ -790,7 +790,7 @@
     }
   }
 
-  CRYPTO_gcm128_tag(key, &gcm, out_tag, tag_len);
+  CRYPTO_gcm128_tag(key, &gcm, out_tag.data(), tag_len);
   *out_tag_len = tag_len;
 
   return 1;
@@ -798,37 +798,35 @@
 
 static int aead_aes_gcm_sealv(const EVP_AEAD_CTX *ctx,
                               bssl::Span<const CRYPTO_IOVEC> iovecs,
-                              uint8_t *out_tag, size_t *out_tag_len,
-                              size_t max_out_tag_len, const uint8_t *nonce,
-                              size_t nonce_len,
+                              bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+                              bssl::Span<const uint8_t> nonce,
                               bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_aes_gcm_ctx *gcm_ctx =
       (const struct aead_aes_gcm_ctx *)&ctx->state;
-  return aead_aes_gcm_sealv_impl(gcm_ctx, iovecs, out_tag, out_tag_len,
-                                 max_out_tag_len, nonce, nonce_len, aadvecs,
-                                 ctx->tag_len);
+  return aead_aes_gcm_sealv_impl(gcm_ctx, iovecs, out_tag, out_tag_len, nonce,
+                                 aadvecs, ctx->tag_len);
 }
 
 static int aead_aes_gcm_openv_detached_impl(
     const struct aead_aes_gcm_ctx *gcm_ctx,
-    bssl::Span<const CRYPTO_IOVEC> iovecs, const uint8_t *nonce,
-    size_t nonce_len, const uint8_t *in_tag, size_t in_tag_len,
-    bssl::Span<const CRYPTO_IVEC> aadvecs, size_t tag_len) {
+    bssl::Span<const CRYPTO_IOVEC> iovecs, bssl::Span<const uint8_t> nonce,
+    bssl::Span<const uint8_t> in_tag, bssl::Span<const CRYPTO_IVEC> aadvecs,
+    size_t tag_len) {
   uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN];
 
-  if (nonce_len == 0) {
+  if (nonce.size() == 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
-  if (in_tag_len != tag_len) {
+  if (in_tag.size() != tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   const GCM128_KEY *key = &gcm_ctx->key;
   GCM128_CONTEXT gcm;
-  CRYPTO_gcm128_init_ctx(key, &gcm, nonce, nonce_len);
+  CRYPTO_gcm128_init_ctx(key, &gcm, nonce.data(), nonce.size());
 
   for (const CRYPTO_IVEC &aadvec : aadvecs) {
     if (!CRYPTO_gcm128_aad(key, &gcm, aadvec.in, aadvec.len)) {
@@ -843,7 +841,7 @@
   }
 
   CRYPTO_gcm128_tag(key, &gcm, tag, tag_len);
-  if (CRYPTO_memcmp(tag, in_tag, tag_len) != 0) {
+  if (CRYPTO_memcmp(tag, in_tag.data(), tag_len) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
@@ -853,12 +851,11 @@
 
 static int aead_aes_gcm_openv_detached(const EVP_AEAD_CTX *ctx,
                                        bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                       const uint8_t *nonce, size_t nonce_len,
-                                       const uint8_t *in_tag, size_t in_tag_len,
+                                       bssl::Span<const uint8_t> nonce,
+                                       bssl::Span<const uint8_t> in_tag,
                                        bssl::Span<const CRYPTO_IVEC> aadvecs) {
   struct aead_aes_gcm_ctx *gcm_ctx = (struct aead_aes_gcm_ctx *)&ctx->state;
-  if (!aead_aes_gcm_openv_detached_impl(gcm_ctx, iovecs, nonce, nonce_len,
-                                        in_tag, in_tag_len, aadvecs,
+  if (!aead_aes_gcm_openv_detached_impl(gcm_ctx, iovecs, nonce, in_tag, aadvecs,
                                         ctx->tag_len)) {
     return 0;
   }
@@ -928,20 +925,18 @@
   return 1;
 }
 
-static int aead_aes_gcm_sealv_randnonce(const EVP_AEAD_CTX *ctx,
-                                        bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                        uint8_t *out_tag, size_t *out_tag_len,
-                                        size_t max_out_tag_len,
-                                        const uint8_t *external_nonce,
-                                        size_t external_nonce_len,
-                                        bssl::Span<const CRYPTO_IVEC> aadvecs) {
-  if (external_nonce_len != 0) {
+static int aead_aes_gcm_sealv_randnonce(
+    const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
+    bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+    bssl::Span<const uint8_t> external_nonce,
+    bssl::Span<const CRYPTO_IVEC> aadvecs) {
+  if (external_nonce.size() != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
   uint8_t nonce[AES_GCM_NONCE_LENGTH];
-  if (max_out_tag_len < sizeof(nonce)) {
+  if (out_tag.size() < sizeof(nonce)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
@@ -955,15 +950,14 @@
 
   const struct aead_aes_gcm_ctx *gcm_ctx =
       (const struct aead_aes_gcm_ctx *)&ctx->state;
-  if (!aead_aes_gcm_sealv_impl(gcm_ctx, iovecs, out_tag, out_tag_len,
-                               max_out_tag_len - AES_GCM_NONCE_LENGTH, nonce,
-                               sizeof(nonce), aadvecs,
-                               ctx->tag_len - AES_GCM_NONCE_LENGTH)) {
+  if (!aead_aes_gcm_sealv_impl(
+          gcm_ctx, iovecs, out_tag.first(out_tag.size() - AES_GCM_NONCE_LENGTH),
+          out_tag_len, nonce, aadvecs, ctx->tag_len - AES_GCM_NONCE_LENGTH)) {
     return 0;
   }
 
-  assert(*out_tag_len + sizeof(nonce) <= max_out_tag_len);
-  memcpy(out_tag + *out_tag_len, nonce, sizeof(nonce));
+  assert(*out_tag_len + sizeof(nonce) <= out_tag.size());
+  CopyToPrefix(nonce, out_tag.subspan(*out_tag_len));
   *out_tag_len += sizeof(nonce);
 
   AEAD_GCM_verify_service_indicator(ctx);
@@ -972,25 +966,23 @@
 
 static int aead_aes_gcm_openv_detached_randnonce(
     const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-    const uint8_t *external_nonce, size_t external_nonce_len,
-    const uint8_t *in_tag, size_t in_tag_len,
+    bssl::Span<const uint8_t> external_nonce, bssl::Span<const uint8_t> in_tag,
     bssl::Span<const CRYPTO_IVEC> aadvecs) {
-  if (external_nonce_len != 0) {
+  if (external_nonce.size() != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
-  if (in_tag_len < AES_GCM_NONCE_LENGTH) {
+  if (in_tag.size() < AES_GCM_NONCE_LENGTH) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
-  const uint8_t *nonce = in_tag + in_tag_len - AES_GCM_NONCE_LENGTH;
 
   const struct aead_aes_gcm_ctx *gcm_ctx =
       (const struct aead_aes_gcm_ctx *)&ctx->state;
   if (!aead_aes_gcm_openv_detached_impl(
-          gcm_ctx, iovecs, nonce, AES_GCM_NONCE_LENGTH, in_tag,
-          in_tag_len - AES_GCM_NONCE_LENGTH, aadvecs,
+          gcm_ctx, iovecs, in_tag.last(AES_GCM_NONCE_LENGTH),
+          in_tag.first(in_tag.size() - AES_GCM_NONCE_LENGTH), aadvecs,
           ctx->tag_len - AES_GCM_NONCE_LENGTH)) {
     return 0;
   }
@@ -1060,21 +1052,21 @@
 
 static int aead_aes_gcm_tls12_sealv(const EVP_AEAD_CTX *ctx,
                                     bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                    uint8_t *out_tag, size_t *out_tag_len,
-                                    size_t max_out_tag_len,
-                                    const uint8_t *nonce, size_t nonce_len,
+                                    bssl::Span<uint8_t> out_tag,
+                                    size_t *out_tag_len,
+                                    bssl::Span<const uint8_t> nonce,
                                     bssl::Span<const CRYPTO_IVEC> aadvecs) {
   struct aead_aes_gcm_tls12_ctx *gcm_ctx =
       (struct aead_aes_gcm_tls12_ctx *)&ctx->state;
 
-  if (nonce_len != AES_GCM_NONCE_LENGTH) {
+  if (nonce.size() != AES_GCM_NONCE_LENGTH) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
 
   // The given nonces must be strictly monotonically increasing.
   uint64_t given_counter =
-      CRYPTO_load_u64_be(nonce + nonce_len - sizeof(uint64_t));
+      CRYPTO_load_u64_be(nonce.last(sizeof(uint64_t)).data());
   if (given_counter == UINT64_MAX || given_counter < gcm_ctx->min_next_nonce) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE);
     return 0;
@@ -1082,8 +1074,7 @@
 
   gcm_ctx->min_next_nonce = given_counter + 1;
 
-  if (!aead_aes_gcm_sealv(ctx, iovecs, out_tag, out_tag_len, max_out_tag_len,
-                          nonce, nonce_len, aadvecs)) {
+  if (!aead_aes_gcm_sealv(ctx, iovecs, out_tag, out_tag_len, nonce, aadvecs)) {
     return 0;
   }
 
@@ -1153,14 +1144,14 @@
 
 static int aead_aes_gcm_tls13_sealv(const EVP_AEAD_CTX *ctx,
                                     bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                    uint8_t *out_tag, size_t *out_tag_len,
-                                    size_t max_out_tag_len,
-                                    const uint8_t *nonce, size_t nonce_len,
+                                    bssl::Span<uint8_t> out_tag,
+                                    size_t *out_tag_len,
+                                    bssl::Span<const uint8_t> nonce,
                                     bssl::Span<const CRYPTO_IVEC> aadvecs) {
   struct aead_aes_gcm_tls13_ctx *gcm_ctx =
       (struct aead_aes_gcm_tls13_ctx *)&ctx->state;
 
-  if (nonce_len != AES_GCM_NONCE_LENGTH) {
+  if (nonce.size() != AES_GCM_NONCE_LENGTH) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
     return 0;
   }
@@ -1169,7 +1160,7 @@
   // https://tools.ietf.org/html/rfc8446#section-5.3 for details of the TLS 1.3
   // nonce construction.
   uint64_t given_counter =
-      CRYPTO_load_u64_be(nonce + nonce_len - sizeof(uint64_t));
+      CRYPTO_load_u64_be(nonce.last(sizeof(uint64_t)).data());
 
   if (gcm_ctx->min_next_nonce == 0) {
     // In the first call the sequence number will be zero and therefore the
@@ -1186,8 +1177,7 @@
     gcm_ctx->min_next_nonce = given_counter + 1;
   }
 
-  if (!aead_aes_gcm_sealv(ctx, iovecs, out_tag, out_tag_len, max_out_tag_len,
-                          nonce, nonce_len, aadvecs)) {
+  if (!aead_aes_gcm_sealv(ctx, iovecs, out_tag, out_tag_len, nonce, aadvecs)) {
     return 0;
   }
 
diff --git a/crypto/fipsmodule/cipher/e_aesccm.cc.inc b/crypto/fipsmodule/cipher/e_aesccm.cc.inc
index 7499610..4a6c603 100644
--- a/crypto/fipsmodule/cipher/e_aesccm.cc.inc
+++ b/crypto/fipsmodule/cipher/e_aesccm.cc.inc
@@ -58,7 +58,7 @@
 
 static int ccm128_init_state(const struct ccm128_context *ctx,
                              struct ccm128_state *state, const AES_KEY *key,
-                             const uint8_t *nonce, size_t nonce_len,
+                             bssl::Span<const uint8_t> nonce,
                              bssl::Span<const CRYPTO_IVEC> aadvecs,
                              size_t plaintext_len) {
   const block128_f block = ctx->block;
@@ -66,8 +66,12 @@
   const unsigned L = ctx->L;
 
   // |L| determines the expected |nonce_len| and the limit for |plaintext_len|.
-  if (plaintext_len > CRYPTO_ccm128_max_input(ctx)  //
-      || nonce_len != 15 - L) {
+  if (plaintext_len > CRYPTO_ccm128_max_input(ctx)) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
+    return 0;
+  }
+  if (nonce.size() != 15 - L) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
@@ -78,7 +82,7 @@
   if (aad_len != 0) {
     state->nonce[0] |= 0x40;  // Set AAD Flag
   }
-  OPENSSL_memcpy(&state->nonce[1], nonce, nonce_len);
+  OPENSSL_memcpy(&state->nonce[1], nonce.data(), nonce.size());
   for (unsigned i = 0; i < L; i++) {
     state->nonce[15 - i] = (uint8_t)(plaintext_len >> (8 * i));
   }
@@ -145,6 +149,7 @@
   if (plaintext_len + 15 < plaintext_len ||
       remaining_blocks + blocks < blocks ||
       (uint64_t)remaining_blocks + blocks > UINT64_C(1) << 61) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
 
@@ -175,11 +180,12 @@
 
 static int ccm128_compute_mac(const struct ccm128_context *ctx,
                               struct ccm128_state *state, const AES_KEY *key,
-                              uint8_t *out_tag, size_t tag_len,
+                              bssl::Span<uint8_t> out_tag,
                               bssl::Span<const CRYPTO_IOVEC> iovecs,
                               bool encrypt) {
   block128_f block = ctx->block;
-  if (tag_len != ctx->M) {
+  if (out_tag.size() != ctx->M) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
     return 0;
   }
 
@@ -214,20 +220,20 @@
   (*block)(state->nonce, tmp, key);
   CRYPTO_xor16(state->cmac, state->cmac, tmp);
 
-  OPENSSL_memcpy(out_tag, state->cmac, tag_len);
+  CopySpan(bssl::Span(state->cmac).first(out_tag.size()), out_tag);
   return 1;
 }
 
 static int CRYPTO_ccm128_encrypt(const struct ccm128_context *ctx,
                                  const AES_KEY *key,
                                  bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                 uint8_t *out_tag, size_t tag_len,
-                                 const uint8_t *nonce, size_t nonce_len,
+                                 bssl::Span<uint8_t> out_tag,
+                                 bssl::Span<const uint8_t> nonce,
                                  bssl::Span<const CRYPTO_IVEC> aadvecs) {
   struct ccm128_state state;
-  return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aadvecs,
+  return ccm128_init_state(ctx, &state, key, nonce, aadvecs,
                            bssl::iovec::TotalLength(iovecs)) &&
-         ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, iovecs,
+         ccm128_compute_mac(ctx, &state, key, out_tag, iovecs,
                             /*encrypt=*/true) &&
          ccm128_encrypt(ctx, &state, key, iovecs);
 }
@@ -235,14 +241,14 @@
 static int CRYPTO_ccm128_decrypt(const struct ccm128_context *ctx,
                                  const AES_KEY *key,
                                  bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                 uint8_t *out_tag, size_t tag_len,
-                                 const uint8_t *nonce, size_t nonce_len,
+                                 bssl::Span<uint8_t> out_tag,
+                                 bssl::Span<const uint8_t> nonce,
                                  bssl::Span<const CRYPTO_IVEC> aadvecs) {
   struct ccm128_state state;
-  return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aadvecs,
+  return ccm128_init_state(ctx, &state, key, nonce, aadvecs,
                            bssl::iovec::TotalLength(iovecs)) &&
          ccm128_encrypt(ctx, &state, key, iovecs) &&
-         ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, iovecs,
+         ccm128_compute_mac(ctx, &state, key, out_tag, iovecs,
                             /*encrypt=*/false);
 }
 
@@ -304,9 +310,8 @@
 
 static int aead_aes_ccm_sealv(const EVP_AEAD_CTX *ctx,
                               bssl::Span<const CRYPTO_IOVEC> iovecs,
-                              uint8_t *out_tag, size_t *out_tag_len,
-                              size_t max_out_tag_len, const uint8_t *nonce,
-                              size_t nonce_len,
+                              bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+                              bssl::Span<const uint8_t> nonce,
                               bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_aes_ccm_ctx *ccm_ctx =
       (struct aead_aes_ccm_ctx *)&ctx->state;
@@ -317,19 +322,18 @@
     return 0;
   }
 
-  if (max_out_tag_len < ctx->tag_len) {
+  if (out_tag.size() < ctx->tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
+  if (nonce.size() != EVP_AEAD_nonce_length(ctx->aead)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
-  if (!CRYPTO_ccm128_encrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, iovecs, out_tag,
-                             ctx->tag_len, nonce, nonce_len, aadvecs)) {
-    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
+  if (!CRYPTO_ccm128_encrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, iovecs,
+                             out_tag.first(ctx->tag_len), nonce, aadvecs)) {
     return 0;
   }
 
@@ -340,8 +344,8 @@
 
 static int aead_aes_ccm_openv_detached(const EVP_AEAD_CTX *ctx,
                                        bssl::Span<const CRYPTO_IOVEC> iovecs,
-                                       const uint8_t *nonce, size_t nonce_len,
-                                       const uint8_t *in_tag, size_t in_tag_len,
+                                       bssl::Span<const uint8_t> nonce,
+                                       bssl::Span<const uint8_t> in_tag,
                                        bssl::Span<const CRYPTO_IVEC> aadvecs) {
   const struct aead_aes_ccm_ctx *ccm_ctx =
       (struct aead_aes_ccm_ctx *)&ctx->state;
@@ -352,25 +356,24 @@
     return 0;
   }
 
-  if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
+  if (nonce.size() != EVP_AEAD_nonce_length(ctx->aead)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
     return 0;
   }
 
-  if (in_tag_len != ctx->tag_len) {
+  if (in_tag.size() != ctx->tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
 
   uint8_t tag[EVP_AEAD_AES_CCM_MAX_TAG_LEN];
-  assert(ctx->tag_len <= EVP_AEAD_AES_CCM_MAX_TAG_LEN);
-  if (!CRYPTO_ccm128_decrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, iovecs, tag,
-                             ctx->tag_len, nonce, nonce_len, aadvecs)) {
-    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
+  if (!CRYPTO_ccm128_decrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, iovecs,
+                             bssl::Span(tag).first(ctx->tag_len), nonce,
+                             aadvecs)) {
     return 0;
   }
 
-  if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) {
+  if (CRYPTO_memcmp(tag, in_tag.data(), ctx->tag_len) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
diff --git a/crypto/fipsmodule/cipher/internal.h b/crypto/fipsmodule/cipher/internal.h
index a0dde53..04647c9 100644
--- a/crypto/fipsmodule/cipher/internal.h
+++ b/crypto/fipsmodule/cipher/internal.h
@@ -57,18 +57,18 @@
   // - openv_detached + sealv: fixed tag length AEAD.
 
   int (*openv)(const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-               size_t *out_total_bytes, const uint8_t *nonce, size_t nonce_len,
+               size_t *out_total_bytes, bssl::Span<const uint8_t> nonce,
                bssl::Span<const CRYPTO_IVEC> aadvecs);
 
   int (*sealv)(const EVP_AEAD_CTX *ctx, bssl::Span<const CRYPTO_IOVEC> iovecs,
-               uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len,
-               const uint8_t *nonce, size_t nonce_len,
+               bssl::Span<uint8_t> out_tag, size_t *out_tag_len,
+               bssl::Span<const uint8_t> nonce,
                bssl::Span<const CRYPTO_IVEC> aadvecs);
 
   int (*openv_detached)(const EVP_AEAD_CTX *ctx,
                         bssl::Span<const CRYPTO_IOVEC> iovecs,
-                        const uint8_t *nonce, size_t nonce_len,
-                        const uint8_t *in_tag, size_t in_tag_len,
+                        bssl::Span<const uint8_t> nonce,
+                        bssl::Span<const uint8_t> in_tag,
                         bssl::Span<const CRYPTO_IVEC> aadvecs);
 
   int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,