external/boringssl: Sync to c9827e073f64e353c4891ecc2c73721882543ee0.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/387b07b78dac785a341eeb2ff86e29393ffe8627..c9827e073f64e353c4891ecc2c73721882543ee0

Test: atest CtsLibcoreTestCases (TODO)
Change-Id: Ie7c2899ac4ea374113e0fe3b76f9a4dce36ea8de
diff --git a/src/crypto/base64/base64_test.cc b/src/crypto/base64/base64_test.cc
index 28b5c8e..9122dee 100644
--- a/src/crypto/base64/base64_test.cc
+++ b/src/crypto/base64/base64_test.cc
@@ -105,7 +105,7 @@
 
 class Base64Test : public testing::TestWithParam<TestVector> {};
 
-INSTANTIATE_TEST_CASE_P(, Base64Test, testing::ValuesIn(kTestVectors));
+INSTANTIATE_TEST_SUITE_P(, Base64Test, testing::ValuesIn(kTestVectors));
 
 // RemoveNewlines returns a copy of |in| with all '\n' characters removed.
 static std::string RemoveNewlines(const char *in) {
diff --git a/src/crypto/bio/bio_test.cc b/src/crypto/bio/bio_test.cc
index 8479c8e..797a733 100644
--- a/src/crypto/bio/bio_test.cc
+++ b/src/crypto/bio/bio_test.cc
@@ -220,7 +220,7 @@
   }
 }
 
-INSTANTIATE_TEST_CASE_P(, BIOASN1Test, testing::ValuesIn(kASN1TestParams));
+INSTANTIATE_TEST_SUITE_P(, BIOASN1Test, testing::ValuesIn(kASN1TestParams));
 
 // Run through the tests twice, swapping |bio1| and |bio2|, for symmetry.
 class BIOPairTest : public testing::TestWithParam<bool> {};
@@ -322,4 +322,4 @@
   EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
 }
 
-INSTANTIATE_TEST_CASE_P(, BIOPairTest, testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(, BIOPairTest, testing::Values(false, true));
diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c
index 7998a48..1ddc73c 100644
--- a/src/crypto/bytestring/cbb.c
+++ b/src/crypto/bytestring/cbb.c
@@ -44,7 +44,7 @@
   base->error = 0;
 
   cbb->base = base;
-  cbb->is_top_level = 1;
+  cbb->is_child = 0;
   return 1;
 }
 
@@ -76,11 +76,14 @@
 }
 
 void CBB_cleanup(CBB *cbb) {
-  if (cbb->base) {
-    // Only top-level |CBB|s are cleaned up. Child |CBB|s are non-owning. They
-    // are implicitly discarded when the parent is flushed or cleaned up.
-    assert(cbb->is_top_level);
+  // Child |CBB|s are non-owning. They are implicitly discarded and should not
+  // be used with |CBB_cleanup| or |ScopedCBB|.
+  assert(!cbb->is_child);
+  if (cbb->is_child) {
+    return;
+  }
 
+  if (cbb->base) {
     if (cbb->base->can_resize) {
       OPENSSL_free(cbb->base->buf);
     }
@@ -169,7 +172,7 @@
 }
 
 int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) {
-  if (!cbb->is_top_level) {
+  if (cbb->is_child) {
     return 0;
   }
 
@@ -310,6 +313,7 @@
   OPENSSL_memset(prefix_bytes, 0, len_len);
   OPENSSL_memset(out_contents, 0, sizeof(CBB));
   out_contents->base = cbb->base;
+  out_contents->is_child = 1;
   cbb->child = out_contents;
   cbb->child->offset = offset;
   cbb->child->pending_len_len = len_len;
@@ -381,6 +385,7 @@
 
   OPENSSL_memset(out_contents, 0, sizeof(CBB));
   out_contents->base = cbb->base;
+  out_contents->is_child = 1;
   cbb->child = out_contents;
   cbb->child->offset = offset;
   cbb->child->pending_len_len = 1;
diff --git a/src/crypto/cipher_extra/aead_test.cc b/src/crypto/cipher_extra/aead_test.cc
index fff7d43..25924bd 100644
--- a/src/crypto/cipher_extra/aead_test.cc
+++ b/src/crypto/cipher_extra/aead_test.cc
@@ -42,58 +42,58 @@
   // truncated_tags is true if the AEAD supports truncating tags to arbitrary
   // lengths.
   bool truncated_tags;
+  // variable_nonce is true if the AEAD supports a variable nonce length.
+  bool variable_nonce;
   // ad_len, if non-zero, is the required length of the AD.
   size_t ad_len;
 };
 
 static const struct KnownAEAD kAEADs[] = {
     {"AES_128_GCM", EVP_aead_aes_128_gcm, "aes_128_gcm_tests.txt", false, true,
-     0},
+     true, 0},
     {"AES_128_GCM_NIST", EVP_aead_aes_128_gcm, "nist_cavp/aes_128_gcm.txt",
-     false, true, 0},
+     false, true, true, 0},
     {"AES_256_GCM", EVP_aead_aes_256_gcm, "aes_256_gcm_tests.txt", false, true,
-     0},
+     true, 0},
     {"AES_256_GCM_NIST", EVP_aead_aes_256_gcm, "nist_cavp/aes_256_gcm.txt",
-     false, true, 0},
-#if !defined(OPENSSL_SMALL)
+     false, true, true, 0},
     {"AES_128_GCM_SIV", EVP_aead_aes_128_gcm_siv, "aes_128_gcm_siv_tests.txt",
-     false, false, 0},
+     false, false, false, 0},
     {"AES_256_GCM_SIV", EVP_aead_aes_256_gcm_siv, "aes_256_gcm_siv_tests.txt",
-     false, false, 0},
-#endif
+     false, false, false, 0},
     {"ChaCha20Poly1305", EVP_aead_chacha20_poly1305,
-     "chacha20_poly1305_tests.txt", false, true, 0},
+     "chacha20_poly1305_tests.txt", false, true, false, 0},
     {"XChaCha20Poly1305", EVP_aead_xchacha20_poly1305,
-     "xchacha20_poly1305_tests.txt", false, true, 0},
+     "xchacha20_poly1305_tests.txt", false, true, false, 0},
     {"AES_128_CBC_SHA1_TLS", EVP_aead_aes_128_cbc_sha1_tls,
-     "aes_128_cbc_sha1_tls_tests.txt", true, false, 11},
+     "aes_128_cbc_sha1_tls_tests.txt", true, false, false, 11},
     {"AES_128_CBC_SHA1_TLSImplicitIV",
      EVP_aead_aes_128_cbc_sha1_tls_implicit_iv,
-     "aes_128_cbc_sha1_tls_implicit_iv_tests.txt", true, false, 11},
+     "aes_128_cbc_sha1_tls_implicit_iv_tests.txt", true, false, false, 11},
     {"AES_128_CBC_SHA256_TLS", EVP_aead_aes_128_cbc_sha256_tls,
-     "aes_128_cbc_sha256_tls_tests.txt", true, false, 11},
+     "aes_128_cbc_sha256_tls_tests.txt", true, false, false, 11},
     {"AES_256_CBC_SHA1_TLS", EVP_aead_aes_256_cbc_sha1_tls,
-     "aes_256_cbc_sha1_tls_tests.txt", true, false, 11},
+     "aes_256_cbc_sha1_tls_tests.txt", true, false, false, 11},
     {"AES_256_CBC_SHA1_TLSImplicitIV",
      EVP_aead_aes_256_cbc_sha1_tls_implicit_iv,
-     "aes_256_cbc_sha1_tls_implicit_iv_tests.txt", true, false, 11},
+     "aes_256_cbc_sha1_tls_implicit_iv_tests.txt", true, false, false, 11},
     {"AES_256_CBC_SHA256_TLS", EVP_aead_aes_256_cbc_sha256_tls,
-     "aes_256_cbc_sha256_tls_tests.txt", true, false, 11},
+     "aes_256_cbc_sha256_tls_tests.txt", true, false, false, 11},
     {"AES_256_CBC_SHA384_TLS", EVP_aead_aes_256_cbc_sha384_tls,
-     "aes_256_cbc_sha384_tls_tests.txt", true, false, 11},
+     "aes_256_cbc_sha384_tls_tests.txt", true, false, false, 11},
     {"DES_EDE3_CBC_SHA1_TLS", EVP_aead_des_ede3_cbc_sha1_tls,
-     "des_ede3_cbc_sha1_tls_tests.txt", true, false, 11},
+     "des_ede3_cbc_sha1_tls_tests.txt", true, false, false, 11},
     {"DES_EDE3_CBC_SHA1_TLSImplicitIV",
      EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv,
-     "des_ede3_cbc_sha1_tls_implicit_iv_tests.txt", true, false, 11},
+     "des_ede3_cbc_sha1_tls_implicit_iv_tests.txt", true, false, false, 11},
     {"AES_128_CTR_HMAC_SHA256", EVP_aead_aes_128_ctr_hmac_sha256,
-     "aes_128_ctr_hmac_sha256.txt", false, true, 0},
+     "aes_128_ctr_hmac_sha256.txt", false, true, false, 0},
     {"AES_256_CTR_HMAC_SHA256", EVP_aead_aes_256_ctr_hmac_sha256,
-     "aes_256_ctr_hmac_sha256.txt", false, true, 0},
+     "aes_256_ctr_hmac_sha256.txt", false, true, false, 0},
     {"AES_128_CCM_BLUETOOTH", EVP_aead_aes_128_ccm_bluetooth,
-     "aes_128_ccm_bluetooth_tests.txt", false, false, 0},
+     "aes_128_ccm_bluetooth_tests.txt", false, false, false, 0},
     {"AES_128_CCM_BLUETOOTH_8", EVP_aead_aes_128_ccm_bluetooth_8,
-     "aes_128_ccm_bluetooth_8_tests.txt", false, false, 0},
+     "aes_128_ccm_bluetooth_8_tests.txt", false, false, false, 0},
 };
 
 class PerAEADTest : public testing::TestWithParam<KnownAEAD> {
@@ -101,9 +101,9 @@
   const EVP_AEAD *aead() { return GetParam().func(); }
 };
 
-INSTANTIATE_TEST_CASE_P(, PerAEADTest, testing::ValuesIn(kAEADs),
-                        [](const testing::TestParamInfo<KnownAEAD> &params)
-                            -> std::string { return params.param.name; });
+INSTANTIATE_TEST_SUITE_P(, PerAEADTest, testing::ValuesIn(kAEADs),
+                         [](const testing::TestParamInfo<KnownAEAD> &params)
+                             -> std::string { return params.param.name; });
 
 // Tests an AEAD against a series of test vectors from a file, using the
 // FileTest format. As an example, here's a valid test case:
@@ -607,50 +607,59 @@
   // as the input.)
 }
 
-// Test that EVP_aead_aes_128_gcm and EVP_aead_aes_256_gcm reject empty nonces.
-// AES-GCM is not defined for those.
-TEST(AEADTest, AESGCMEmptyNonce) {
-  static const uint8_t kZeros[32] = {0};
+TEST_P(PerAEADTest, InvalidNonceLength) {
+  size_t valid_nonce_len = EVP_AEAD_nonce_length(aead());
+  std::vector<size_t> nonce_lens;
+  if (valid_nonce_len != 0) {
+    // Other than the implicit IV TLS "AEAD"s, none of our AEADs allow empty
+    // nonces. In particular, although AES-GCM was incorrectly specified with
+    // variable-length nonces, it does not allow the empty nonce.
+    nonce_lens.push_back(0);
+  }
+  if (!GetParam().variable_nonce) {
+    nonce_lens.push_back(valid_nonce_len + 1);
+    if (valid_nonce_len != 0) {
+      nonce_lens.push_back(valid_nonce_len - 1);
+    }
+  }
 
-  // Test AES-128-GCM.
-  uint8_t buf[16];
-  size_t len;
-  bssl::ScopedEVP_AEAD_CTX ctx;
-  ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_128_gcm(), kZeros, 16,
-                                EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
+  static const uint8_t kZeros[EVP_AEAD_MAX_KEY_LENGTH] = {0};
+  const size_t ad_len = GetParam().ad_len != 0 ? GetParam().ad_len : 16;
+  ASSERT_LE(ad_len, sizeof(kZeros));
 
-  EXPECT_FALSE(EVP_AEAD_CTX_seal(ctx.get(), buf, &len, sizeof(buf),
-                                 nullptr /* nonce */, 0, nullptr /* in */, 0,
-                                 nullptr /* ad */, 0));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
-  EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
+  for (size_t nonce_len : nonce_lens) {
+    SCOPED_TRACE(nonce_len);
+    uint8_t buf[256];
+    size_t len;
+    std::vector<uint8_t> nonce(nonce_len);
+    bssl::ScopedEVP_AEAD_CTX ctx;
+    ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
+        ctx.get(), aead(), kZeros, EVP_AEAD_key_length(aead()),
+        EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_seal));
 
-  EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), buf, &len, sizeof(buf),
-                                 nullptr /* nonce */, 0, kZeros /* in */,
-                                 sizeof(kZeros), nullptr /* ad */, 0));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
-  EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
+    EXPECT_FALSE(EVP_AEAD_CTX_seal(ctx.get(), buf, &len, sizeof(buf),
+                                   nonce.data(), nonce.size(), nullptr /* in */,
+                                   0, kZeros /* ad */, ad_len));
+    uint32_t err = ERR_get_error();
+    EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
+    // TODO(davidben): Merge these errors. https://crbug.com/boringssl/129.
+    if (ERR_GET_REASON(err) != CIPHER_R_UNSUPPORTED_NONCE_SIZE) {
+      EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
+    }
 
-  // Test AES-256-GCM.
-  ctx.Reset();
-  ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_256_gcm(), kZeros, 32,
-                                EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
-
-  EXPECT_FALSE(EVP_AEAD_CTX_seal(ctx.get(), buf, &len, sizeof(buf),
-                                 nullptr /* nonce */, 0, nullptr /* in */, 0,
-                                 nullptr /* ad */, 0));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
-  EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
-
-  EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), buf, &len, sizeof(buf),
-                                 nullptr /* nonce */, 0, kZeros /* in */,
-                                 sizeof(kZeros), nullptr /* ad */, 0));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
-  EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
+    ctx.Reset();
+    ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
+        ctx.get(), aead(), kZeros, EVP_AEAD_key_length(aead()),
+        EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_open));
+    EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), buf, &len, sizeof(buf),
+                                   nonce.data(), nonce.size(), kZeros /* in */,
+                                   sizeof(kZeros), kZeros /* ad */, ad_len));
+    err = ERR_get_error();
+    EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
+    if (ERR_GET_REASON(err) != CIPHER_R_UNSUPPORTED_NONCE_SIZE) {
+      EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
+    }
+  }
 }
 
 TEST(AEADTest, AESCCMLargeAD) {
diff --git a/src/crypto/cipher_extra/cipher_test.cc b/src/crypto/cipher_extra/cipher_test.cc
index 62ef939..0a96bf3 100644
--- a/src/crypto/cipher_extra/cipher_test.cc
+++ b/src/crypto/cipher_extra/cipher_test.cc
@@ -150,7 +150,8 @@
 }
 
 static void TestOperation(FileTest *t, const EVP_CIPHER *cipher, bool encrypt,
-                          size_t chunk_size, const std::vector<uint8_t> &key,
+                          bool copy, size_t chunk_size,
+                          const std::vector<uint8_t> &key,
                           const std::vector<uint8_t> &iv,
                           const std::vector<uint8_t> &plaintext,
                           const std::vector<uint8_t> &ciphertext,
@@ -167,45 +168,52 @@
 
   bool is_aead = EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE;
 
-  bssl::ScopedEVP_CIPHER_CTX ctx;
-  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr,
-                         encrypt ? 1 : 0));
+  bssl::ScopedEVP_CIPHER_CTX ctx1;
+  ASSERT_TRUE(EVP_CipherInit_ex(ctx1.get(), cipher, nullptr, nullptr, nullptr,
+                                encrypt ? 1 : 0));
   if (t->HasAttribute("IV")) {
     if (is_aead) {
-      ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
+      ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx1.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                       iv.size(), 0));
     } else {
-      ASSERT_EQ(iv.size(), EVP_CIPHER_CTX_iv_length(ctx.get()));
+      ASSERT_EQ(iv.size(), EVP_CIPHER_CTX_iv_length(ctx1.get()));
     }
   }
+
+  bssl::ScopedEVP_CIPHER_CTX ctx2;
+  EVP_CIPHER_CTX *ctx = ctx1.get();
+  if (copy) {
+    ASSERT_TRUE(EVP_CIPHER_CTX_copy(ctx2.get(), ctx1.get()));
+    ctx = ctx2.get();
+  }
+
   if (is_aead && !encrypt) {
-    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_TAG,
-                                    tag.size(),
+    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag.size(),
                                     const_cast<uint8_t *>(tag.data())));
   }
   // The ciphers are run with no padding. For each of the ciphers we test, the
   // output size matches the input size.
   ASSERT_EQ(in->size(), out->size());
-  ASSERT_TRUE(EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()));
-  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, key.data(),
-                                iv.data(), -1));
+  ASSERT_TRUE(EVP_CIPHER_CTX_set_key_length(ctx, key.size()));
+  ASSERT_TRUE(
+      EVP_CipherInit_ex(ctx, nullptr, nullptr, key.data(), iv.data(), -1));
   // Note: the deprecated |EVP_CIPHER|-based AEAD API is sensitive to whether
   // parameters are NULL, so it is important to skip the |in| and |aad|
   // |EVP_CipherUpdate| calls when empty.
   if (!aad.empty()) {
     int unused;
     ASSERT_TRUE(
-        EVP_CipherUpdate(ctx.get(), nullptr, &unused, aad.data(), aad.size()));
+        EVP_CipherUpdate(ctx, nullptr, &unused, aad.data(), aad.size()));
   }
-  ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx.get(), 0));
+  ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx, 0));
   std::vector<uint8_t> result;
-  ASSERT_TRUE(DoCipher(ctx.get(), &result, *in, chunk_size));
+  ASSERT_TRUE(DoCipher(ctx, &result, *in, chunk_size));
   EXPECT_EQ(Bytes(*out), Bytes(result));
   if (encrypt && is_aead) {
     uint8_t rtag[16];
     ASSERT_LE(tag.size(), sizeof(rtag));
-    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_GET_TAG,
-                                    tag.size(), rtag));
+    ASSERT_TRUE(
+        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag.size(), rtag));
     EXPECT_EQ(Bytes(tag), Bytes(rtag, tag.size()));
   }
 }
@@ -252,14 +260,18 @@
     // By default, both directions are run, unless overridden by the operation.
     if (operation != kDecrypt) {
       SCOPED_TRACE("encrypt");
-      TestOperation(t, cipher, true /* encrypt */, chunk_size, key, iv,
-                    plaintext, ciphertext, aad, tag);
+      TestOperation(t, cipher, true /* encrypt */, false /* no copy */,
+                    chunk_size, key, iv, plaintext, ciphertext, aad, tag);
+      TestOperation(t, cipher, true /* encrypt */, true /* copy */, chunk_size,
+                    key, iv, plaintext, ciphertext, aad, tag);
     }
 
     if (operation != kEncrypt) {
       SCOPED_TRACE("decrypt");
-      TestOperation(t, cipher, false /* decrypt */, chunk_size, key, iv,
-                    plaintext, ciphertext, aad, tag);
+      TestOperation(t, cipher, false /* decrypt */, false /* no copy */,
+                    chunk_size, key, iv, plaintext, ciphertext, aad, tag);
+      TestOperation(t, cipher, false /* decrypt */, true /* copy */, chunk_size,
+                    key, iv, plaintext, ciphertext, aad, tag);
     }
   }
 }
diff --git a/src/crypto/cipher_extra/e_aesgcmsiv.c b/src/crypto/cipher_extra/e_aesgcmsiv.c
index 71a71fa..64febae 100644
--- a/src/crypto/cipher_extra/e_aesgcmsiv.c
+++ b/src/crypto/cipher_extra/e_aesgcmsiv.c
@@ -426,6 +426,11 @@
     return 0;
   }
 
+  if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+    return 0;
+  }
+
   const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = asm_ctx_from_ctx(ctx);
   const size_t plaintext_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN;
   const uint8_t *const given_tag = in + plaintext_len;
diff --git a/src/crypto/digest_extra/digest_test.cc b/src/crypto/digest_extra/digest_test.cc
index de2e9d1..7d07c04 100644
--- a/src/crypto/digest_extra/digest_test.cc
+++ b/src/crypto/digest_extra/digest_test.cc
@@ -198,6 +198,28 @@
   ASSERT_TRUE(EVP_DigestFinal_ex(ctx.get(), digest.get(), &digest_len));
   CompareDigest(test, digest.get(), digest_len);
 
+  // Make a copy of the digest in the initial state.
+  ASSERT_TRUE(EVP_DigestInit_ex(ctx.get(), test->md.func(), NULL));
+  bssl::ScopedEVP_MD_CTX copy;
+  ASSERT_TRUE(EVP_MD_CTX_copy_ex(copy.get(), ctx.get()));
+  for (size_t i = 0; i < test->repeat; i++) {
+    ASSERT_TRUE(EVP_DigestUpdate(copy.get(), test->input, strlen(test->input)));
+  }
+  ASSERT_TRUE(EVP_DigestFinal_ex(copy.get(), digest.get(), &digest_len));
+  CompareDigest(test, digest.get(), digest_len);
+
+  // Make a copy of the digest with half the input provided.
+  size_t half = strlen(test->input) / 2;
+  ASSERT_TRUE(EVP_DigestUpdate(ctx.get(), test->input, half));
+  ASSERT_TRUE(EVP_MD_CTX_copy_ex(copy.get(), ctx.get()));
+  ASSERT_TRUE(EVP_DigestUpdate(copy.get(), test->input + half,
+                               strlen(test->input) - half));
+  for (size_t i = 1; i < test->repeat; i++) {
+    ASSERT_TRUE(EVP_DigestUpdate(copy.get(), test->input, strlen(test->input)));
+  }
+  ASSERT_TRUE(EVP_DigestFinal_ex(copy.get(), digest.get(), &digest_len));
+  CompareDigest(test, digest.get(), digest_len);
+
   // Test the one-shot function.
   if (test->md.one_shot_func && test->repeat == 1) {
     uint8_t *out = test->md.one_shot_func((const uint8_t *)test->input,
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
index 6571c30..4d74292 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -297,16 +297,19 @@
   }
 
   if (md_op_init) {
-    bssl::ScopedEVP_MD_CTX ctx;
+    bssl::ScopedEVP_MD_CTX ctx, copy;
     EVP_PKEY_CTX *pctx;
     if (!md_op_init(ctx.get(), &pctx, digest, nullptr, key) ||
-        !SetupContext(t, pctx)) {
+        !SetupContext(t, pctx) ||
+        !EVP_MD_CTX_copy_ex(copy.get(), ctx.get())) {
       return false;
     }
 
     if (is_verify) {
-      return !!EVP_DigestVerify(ctx.get(), output.data(), output.size(),
-                                input.data(), input.size());
+      return EVP_DigestVerify(ctx.get(), output.data(), output.size(),
+                              input.data(), input.size()) &&
+             EVP_DigestVerify(copy.get(), output.data(), output.size(),
+                              input.data(), input.size());
     }
 
     size_t len;
@@ -321,6 +324,21 @@
     }
     actual.resize(len);
     EXPECT_EQ(Bytes(output), Bytes(actual));
+
+    // Repeat the test with |copy|, to check |EVP_MD_CTX_copy_ex| duplicated
+    // everything.
+    if (!EVP_DigestSign(copy.get(), nullptr, &len, input.data(),
+                        input.size())) {
+      return false;
+    }
+    actual.resize(len);
+    if (!EVP_DigestSign(copy.get(), actual.data(), &len, input.data(),
+                        input.size()) ||
+        !t->GetBytes(&output, "Output")) {
+      return false;
+    }
+    actual.resize(len);
+    EXPECT_EQ(Bytes(output), Bytes(actual));
     return true;
   }
 
@@ -333,72 +351,78 @@
     return false;
   }
 
+  bssl::UniquePtr<EVP_PKEY_CTX> copy(EVP_PKEY_CTX_dup(ctx.get()));
+  if (!copy) {
+    return false;
+  }
+
   if (is_verify) {
-    return !!EVP_PKEY_verify(ctx.get(), output.data(), output.size(),
-                             input.data(), input.size());
+    return EVP_PKEY_verify(ctx.get(), output.data(), output.size(),
+                           input.data(), input.size()) &&
+           EVP_PKEY_verify(copy.get(), output.data(), output.size(),
+                           input.data(), input.size());
   }
 
-  size_t len;
-  if (!key_op(ctx.get(), nullptr, &len, input.data(), input.size())) {
-    return false;
-  }
-  actual.resize(len);
-  if (!key_op(ctx.get(), actual.data(), &len, input.data(), input.size())) {
-    return false;
-  }
+  for (EVP_PKEY_CTX *pctx : {ctx.get(), copy.get()}) {
+    size_t len;
+    if (!key_op(pctx, nullptr, &len, input.data(), input.size())) {
+      return false;
+    }
+    actual.resize(len);
+    if (!key_op(pctx, actual.data(), &len, input.data(), input.size())) {
+      return false;
+    }
 
-  // Encryption is non-deterministic, so we check by decrypting.
-  if (t->HasAttribute("CheckDecrypt")) {
-    size_t plaintext_len;
-    ctx.reset(EVP_PKEY_CTX_new(key, nullptr));
-    if (!ctx ||
-        !EVP_PKEY_decrypt_init(ctx.get()) ||
-        (digest != nullptr &&
-         !EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
-        !SetupContext(t, ctx.get()) ||
-        !EVP_PKEY_decrypt(ctx.get(), nullptr, &plaintext_len, actual.data(),
-                          actual.size())) {
-      return false;
+    if (t->HasAttribute("CheckDecrypt")) {
+      // Encryption is non-deterministic, so we check by decrypting.
+      size_t plaintext_len;
+      bssl::UniquePtr<EVP_PKEY_CTX> decrypt_ctx(EVP_PKEY_CTX_new(key, nullptr));
+      if (!decrypt_ctx ||
+          !EVP_PKEY_decrypt_init(decrypt_ctx.get()) ||
+          (digest != nullptr &&
+           !EVP_PKEY_CTX_set_signature_md(decrypt_ctx.get(), digest)) ||
+          !SetupContext(t, decrypt_ctx.get()) ||
+          !EVP_PKEY_decrypt(decrypt_ctx.get(), nullptr, &plaintext_len,
+                            actual.data(), actual.size())) {
+        return false;
+      }
+      output.resize(plaintext_len);
+      if (!EVP_PKEY_decrypt(decrypt_ctx.get(), output.data(), &plaintext_len,
+                            actual.data(), actual.size())) {
+        ADD_FAILURE() << "Could not decrypt result.";
+        return false;
+      }
+      output.resize(plaintext_len);
+      EXPECT_EQ(Bytes(input), Bytes(output)) << "Decrypted result mismatch.";
+    } else if (t->HasAttribute("CheckVerify")) {
+      // Some signature schemes are non-deterministic, so we check by verifying.
+      bssl::UniquePtr<EVP_PKEY_CTX> verify_ctx(EVP_PKEY_CTX_new(key, nullptr));
+      if (!verify_ctx ||
+          !EVP_PKEY_verify_init(verify_ctx.get()) ||
+          (digest != nullptr &&
+           !EVP_PKEY_CTX_set_signature_md(verify_ctx.get(), digest)) ||
+          !SetupContext(t, verify_ctx.get())) {
+        return false;
+      }
+      if (t->HasAttribute("VerifyPSSSaltLength")) {
+        if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(
+                verify_ctx.get(),
+                atoi(t->GetAttributeOrDie("VerifyPSSSaltLength").c_str()))) {
+          return false;
+        }
+      }
+      EXPECT_TRUE(EVP_PKEY_verify(verify_ctx.get(), actual.data(),
+                                  actual.size(), input.data(), input.size()))
+          << "Could not verify result.";
+    } else {
+      // By default, check by comparing the result against Output.
+      if (!t->GetBytes(&output, "Output")) {
+        return false;
+      }
+      actual.resize(len);
+      EXPECT_EQ(Bytes(output), Bytes(actual));
     }
-    output.resize(plaintext_len);
-    if (!EVP_PKEY_decrypt(ctx.get(), output.data(), &plaintext_len,
-                          actual.data(), actual.size())) {
-      ADD_FAILURE() << "Could not decrypt result.";
-      return false;
-    }
-    output.resize(plaintext_len);
-    EXPECT_EQ(Bytes(input), Bytes(output)) << "Decrypted result mismatch.";
-    return true;
   }
-
-  // Some signature schemes are non-deterministic, so we check by verifying.
-  if (t->HasAttribute("CheckVerify")) {
-    ctx.reset(EVP_PKEY_CTX_new(key, nullptr));
-    if (!ctx ||
-        !EVP_PKEY_verify_init(ctx.get()) ||
-        (digest != nullptr &&
-         !EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
-        !SetupContext(t, ctx.get())) {
-      return false;
-    }
-    if (t->HasAttribute("VerifyPSSSaltLength") &&
-        !EVP_PKEY_CTX_set_rsa_pss_saltlen(
-            ctx.get(),
-            atoi(t->GetAttributeOrDie("VerifyPSSSaltLength").c_str()))) {
-      return false;
-    }
-    EXPECT_TRUE(EVP_PKEY_verify(ctx.get(), actual.data(), actual.size(),
-                                input.data(), input.size()))
-        << "Could not verify result.";
-    return true;
-  }
-
-  // By default, check by comparing the result against Output.
-  if (!t->GetBytes(&output, "Output")) {
-    return false;
-  }
-  actual.resize(len);
-  EXPECT_EQ(Bytes(output), Bytes(actual));
   return true;
 }
 
diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt
index ff08ee7..9dbe1cb 100644
--- a/src/crypto/evp/evp_tests.txt
+++ b/src/crypto/evp/evp_tests.txt
@@ -274,6 +274,17 @@
 Input = "0123456789ABCDEF0123456789ABCDEF"
 CheckVerify
 
+# Check a salt length with a non-standard digest length, to verify things are
+# not just working due to defaults. (The current default is a maximum salt
+# length, but the ecosystem has converged on matching the digest length, so we
+# may change this in the future.)
+Sign = RSA-2048
+RSAPadding = PSS
+PSSSaltLength = 42
+Digest = SHA256
+Input = "0123456789ABCDEF0123456789ABCDEF"
+CheckVerify
+
 # Auto-detected salt length
 Verify = RSA-2048-SPKI
 RSAPadding = PSS
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index eb59901..865b36a 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -132,6 +132,7 @@
   dctx->pad_mode = sctx->pad_mode;
   dctx->md = sctx->md;
   dctx->mgf1md = sctx->mgf1md;
+  dctx->saltlen = sctx->saltlen;
   if (sctx->oaep_label) {
     OPENSSL_free(dctx->oaep_label);
     dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
diff --git a/src/crypto/fipsmodule/aes/aes.c b/src/crypto/fipsmodule/aes/aes.c
index 8a1ca31..48d60ee 100644
--- a/src/crypto/fipsmodule/aes/aes.c
+++ b/src/crypto/fipsmodule/aes/aes.c
@@ -834,6 +834,9 @@
 }
 
 int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
+  if (bits != 128 && bits != 192 && bits != 256) {
+    return -2;
+  }
   if (hwaes_capable()) {
     return aes_hw_set_encrypt_key(key, bits, aeskey);
   } else if (vpaes_capable()) {
@@ -844,6 +847,9 @@
 }
 
 int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
+  if (bits != 128 && bits != 192 && bits != 256) {
+    return -2;
+  }
   if (hwaes_capable()) {
     return aes_hw_set_decrypt_key(key, bits, aeskey);
   } else if (vpaes_capable()) {
diff --git a/src/crypto/fipsmodule/aes/aes_test.cc b/src/crypto/fipsmodule/aes/aes_test.cc
index 2222b63..1f9a491 100644
--- a/src/crypto/fipsmodule/aes/aes_test.cc
+++ b/src/crypto/fipsmodule/aes/aes_test.cc
@@ -189,6 +189,13 @@
   }
 }
 
+TEST(AESTest, InvalidKeySize) {
+  static const uint8_t kZero[8] = {0};
+  AES_KEY key;
+  EXPECT_LT(AES_set_encrypt_key(kZero, 42, &key), 0);
+  EXPECT_LT(AES_set_decrypt_key(kZero, 42, &key), 0);
+}
+
 #if defined(SUPPORTS_ABI_TEST)
 TEST(AESTest, ABI) {
   for (int bits : {128, 192, 256}) {
diff --git a/src/crypto/fipsmodule/cipher/e_aes.c b/src/crypto/fipsmodule/cipher/e_aes.c
index dc94166..1ea012d 100644
--- a/src/crypto/fipsmodule/cipher/e_aes.c
+++ b/src/crypto/fipsmodule/cipher/e_aes.c
@@ -456,6 +456,9 @@
     case EVP_CTRL_COPY: {
       EVP_CIPHER_CTX *out = ptr;
       EVP_AES_GCM_CTX *gctx_out = aes_gcm_from_cipher_ctx(out);
+      // |EVP_CIPHER_CTX_copy| copies this generically, but we must redo it in
+      // case |out->cipher_data| and |in->cipher_data| are differently aligned.
+      OPENSSL_memcpy(gctx_out, gctx, sizeof(EVP_AES_GCM_CTX));
       if (gctx->iv == c->iv) {
         gctx_out->iv = out->iv;
       } else {
@@ -590,7 +593,7 @@
   out->key_len = 16;
   out->iv_len = 12;
   out->ctx_size = sizeof(EVP_AES_GCM_CTX) + EVP_AES_GCM_CTX_PADDING;
-  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_CUSTOM_COPY |
                EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
                EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
   out->init = aes_gcm_init_key;
@@ -658,7 +661,7 @@
   out->key_len = 24;
   out->iv_len = 12;
   out->ctx_size = sizeof(EVP_AES_GCM_CTX) + EVP_AES_GCM_CTX_PADDING;
-  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_CUSTOM_COPY |
                EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
                EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
   out->init = aes_gcm_init_key;
@@ -726,7 +729,7 @@
   out->key_len = 32;
   out->iv_len = 12;
   out->ctx_size = sizeof(EVP_AES_GCM_CTX) + EVP_AES_GCM_CTX_PADDING;
-  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_CUSTOM_COPY |
                EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
                EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
   out->init = aes_gcm_init_key;
diff --git a/src/crypto/fipsmodule/digest/digest.c b/src/crypto/fipsmodule/digest/digest.c
index e49d552..6705867 100644
--- a/src/crypto/fipsmodule/digest/digest.c
+++ b/src/crypto/fipsmodule/digest/digest.c
@@ -116,7 +116,9 @@
 void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) { EVP_MD_CTX_free(ctx); }
 
 int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
-  if (in == NULL || in->digest == NULL) {
+  // |in->digest| may be NULL if this is a signing |EVP_MD_CTX| for, e.g.,
+  // Ed25519 which does not hash with |EVP_MD_CTX|.
+  if (in == NULL || (in->pctx == NULL && in->digest == NULL)) {
     OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED);
     return 0;
   }
@@ -131,29 +133,34 @@
     }
   }
 
-  uint8_t *tmp_buf;
-  if (out->digest != in->digest) {
-    assert(in->digest->ctx_size != 0);
-    tmp_buf = OPENSSL_malloc(in->digest->ctx_size);
-    if (tmp_buf == NULL) {
-      if (pctx) {
-        in->pctx_ops->free(pctx);
+  uint8_t *tmp_buf = NULL;
+  if (in->digest != NULL) {
+    if (out->digest != in->digest) {
+      assert(in->digest->ctx_size != 0);
+      tmp_buf = OPENSSL_malloc(in->digest->ctx_size);
+      if (tmp_buf == NULL) {
+        if (pctx) {
+          in->pctx_ops->free(pctx);
+        }
+        OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
+        return 0;
       }
-      OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
-      return 0;
+    } else {
+      // |md_data| will be the correct size in this case. It's removed from
+      // |out| so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's
+      // reused.
+      tmp_buf = out->md_data;
+      out->md_data = NULL;
     }
-  } else {
-    // |md_data| will be the correct size in this case. It's removed from |out|
-    // so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's reused.
-    tmp_buf = out->md_data;
-    out->md_data = NULL;
   }
 
   EVP_MD_CTX_cleanup(out);
 
   out->digest = in->digest;
   out->md_data = tmp_buf;
-  OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size);
+  if (in->digest != NULL) {
+    OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size);
+  }
   out->pctx = pctx;
   out->pctx_ops = in->pctx_ops;
   assert(out->pctx == NULL || out->pctx_ops != NULL);
diff --git a/src/crypto/fipsmodule/ec/ec_test.cc b/src/crypto/fipsmodule/ec/ec_test.cc
index dd4c75a..1219e2b 100644
--- a/src/crypto/fipsmodule/ec/ec_test.cc
+++ b/src/crypto/fipsmodule/ec/ec_test.cc
@@ -792,8 +792,8 @@
   return OBJ_nid2sn(params.param.nid);
 }
 
-INSTANTIATE_TEST_CASE_P(, ECCurveTest, testing::ValuesIn(AllCurves()),
-                        CurveToString);
+INSTANTIATE_TEST_SUITE_P(, ECCurveTest, testing::ValuesIn(AllCurves()),
+                         CurveToString);
 
 static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
   std::string curve_name;
diff --git a/src/crypto/rsa_extra/rsa_test.cc b/src/crypto/rsa_extra/rsa_test.cc
index 9bd47b1..ed1630d 100644
--- a/src/crypto/rsa_extra/rsa_test.cc
+++ b/src/crypto/rsa_extra/rsa_test.cc
@@ -461,7 +461,8 @@
   }
 }
 
-INSTANTIATE_TEST_CASE_P(, RSAEncryptTest, testing::ValuesIn(kRSAEncryptParams));
+INSTANTIATE_TEST_SUITE_P(, RSAEncryptTest,
+                         testing::ValuesIn(kRSAEncryptParams));
 
 TEST(RSATest, TestDecrypt) {
   bssl::UniquePtr<RSA> rsa(