// Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <openssl/aes.h>
#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/span.h>

#include "../fipsmodule/cipher/internal.h"
#include "../internal.h"
#include "../test/file_test.h"
#include "../test/test_util.h"
#include "../test/wycheproof_util.h"
#include "./internal.h"


BSSL_NAMESPACE_BEGIN
namespace {

static const EVP_CIPHER *GetCipher(const std::string &name) {
  if (name == "DES-CBC") {
    return EVP_des_cbc();
  } else if (name == "DES-ECB") {
    return EVP_des_ecb();
  } else if (name == "DES-EDE") {
    return EVP_des_ede();
  } else if (name == "DES-EDE3") {
    return EVP_des_ede3();
  } else if (name == "DES-EDE-CBC") {
    return EVP_des_ede_cbc();
  } else if (name == "DES-EDE3-CBC") {
    return EVP_des_ede3_cbc();
  } else if (name == "RC4") {
    return EVP_rc4();
  } else if (name == "AES-128-ECB") {
    return EVP_aes_128_ecb();
  } else if (name == "AES-256-ECB") {
    return EVP_aes_256_ecb();
  } else if (name == "AES-128-CBC") {
    return EVP_aes_128_cbc();
  } else if (name == "AES-128-GCM") {
    return EVP_aes_128_gcm();
  } else if (name == "AES-128-OFB") {
    return EVP_aes_128_ofb();
  } else if (name == "AES-192-CBC") {
    return EVP_aes_192_cbc();
  } else if (name == "AES-192-CTR") {
    return EVP_aes_192_ctr();
  } else if (name == "AES-192-ECB") {
    return EVP_aes_192_ecb();
  } else if (name == "AES-192-GCM") {
    return EVP_aes_192_gcm();
  } else if (name == "AES-192-OFB") {
    return EVP_aes_192_ofb();
  } else if (name == "AES-256-CBC") {
    return EVP_aes_256_cbc();
  } else if (name == "AES-128-CTR") {
    return EVP_aes_128_ctr();
  } else if (name == "AES-256-CTR") {
    return EVP_aes_256_ctr();
  } else if (name == "AES-256-GCM") {
    return EVP_aes_256_gcm();
  } else if (name == "AES-256-OFB") {
    return EVP_aes_256_ofb();
  }
  return nullptr;
}

enum class Operation {
  // kBoth tests both encryption and decryption.
  kBoth,
  // kEncrypt tests encryption. The result of encryption should always
  // successfully decrypt, so this should only be used if the test file has a
  // matching decrypt-only vector.
  kEncrypt,
  // kDecrypt tests decryption. This should only be used if the test file has a
  // matching encrypt-only input, or if multiple ciphertexts are valid for
  // a given plaintext and this is a non-canonical ciphertext.
  kDecrypt,
  // kInvalidDecrypt tests decryption and expects it to fail, e.g. due to
  // invalid tag or padding.
  kInvalidDecrypt,
};

static const char *OperationToString(Operation op) {
  switch (op) {
    case Operation::kBoth:
      return "Both";
    case Operation::kEncrypt:
      return "Encrypt";
    case Operation::kDecrypt:
      return "Decrypt";
    case Operation::kInvalidDecrypt:
      return "InvalidDecrypt";
  }
  abort();
}

enum class API {
  // kCipher tests the EVP_Cipher() API. Arcane!
  kCipher,
  // kUnsized tests the EVP_CipherUpdate_ex() API. No size checking!
  kUnsized,
  // kSized tests the EVP_CipherUpdate_Ex2() API. With size checking!
  kSized,
};

static const char *APIToString(API api) {
  switch (api) {
    case API::kCipher:
      return "Cipher";
    case API::kUnsized:
      return "Unsized";
    case API::kSized:
      return "Sized";
  }
  abort();
}

// MaybeCopyCipherContext, if `copy` is true, replaces `*ctx` with a, hopefully
// equivalent, copy of it.
static bool MaybeCopyCipherContext(bool copy, UniquePtr<EVP_CIPHER_CTX> *ctx) {
  if (!copy) {
    return true;
  }
  UniquePtr<EVP_CIPHER_CTX> ctx2(EVP_CIPHER_CTX_new());
  if (!ctx2 || !EVP_CIPHER_CTX_copy(ctx2.get(), ctx->get())) {
    return false;
  }
  *ctx = std::move(ctx2);
  return true;
}

static void TestCipherAPI(const EVP_CIPHER *cipher, Operation op, bool padding,
                          bool copy, bool in_place, API api, size_t chunk_size,
                          Span<const uint8_t> key, Span<const uint8_t> iv,
                          Span<const uint8_t> plaintext,
                          Span<const uint8_t> ciphertext,
                          Span<const uint8_t> aad, Span<const uint8_t> tag) {
  SCOPED_TRACE(APIToString(api));

  bool encrypt = op == Operation::kEncrypt;
  bool is_custom_cipher =
      EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_CIPHER;
  Span<const uint8_t> in = encrypt ? plaintext : ciphertext;
  Span<const uint8_t> expected = encrypt ? ciphertext : plaintext;
  bool is_aead = EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE;

  // Some `EVP_CIPHER`s take a variable-length key, and need to first be
  // configured with the key length, which requires configuring the cipher.
  UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
  ASSERT_TRUE(ctx);
  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), cipher, /*engine=*/nullptr,
                                /*key=*/nullptr, /*iv=*/nullptr,
                                encrypt ? 1 : 0));
  ASSERT_TRUE(EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()));
  if (!padding) {
    ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx.get(), 0));
  }

  // Configure the key.
  ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), /*cipher=*/nullptr,
                                /*engine=*/nullptr, key.data(), /*iv=*/nullptr,
                                /*enc=*/-1));

  // Configure the IV to run the actual operation. Callers that wish to use a
  // key for multiple, potentially concurrent, operations will likely copy at
  // this point. The `EVP_CIPHER_CTX` API uses the same type to represent a
  // pre-computed key schedule and a streaming operation.
  ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
  if (is_aead) {
    ASSERT_LE(iv.size(), size_t{INT_MAX});
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                    static_cast<int>(iv.size()), nullptr));
    ASSERT_EQ(EVP_CIPHER_CTX_iv_length(ctx.get()), iv.size());
  } else {
    ASSERT_EQ(iv.size(), EVP_CIPHER_CTX_iv_length(ctx.get()));
  }
  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), /*cipher=*/nullptr,
                                /*engine=*/nullptr,
                                /*key=*/nullptr, iv.data(), /*enc=*/-1));

  if (is_aead && !encrypt) {
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_TAG,
                                    tag.size(),
                                    const_cast<uint8_t *>(tag.data())));
  }

  // 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.
  while (!aad.empty()) {
    size_t todo =
        chunk_size == 0 ? aad.size() : std::min(aad.size(), chunk_size);
    switch (api) {
      case API::kCipher:
        // AEADs always use the "custom cipher" return value convention. Passing
        // a null output pointer triggers the AAD logic.
        ASSERT_TRUE(is_custom_cipher);
        ASSERT_EQ(static_cast<int>(todo),
                  EVP_Cipher(ctx.get(), nullptr, aad.data(), todo));
        break;
      case API::kUnsized: {
        int len;
        ASSERT_TRUE(
            EVP_CipherUpdate(ctx.get(), nullptr, &len, aad.data(), todo));
        // Although it doesn't output anything, `EVP_CipherUpdate` should claim
        // to output the input length.
        EXPECT_EQ(len, static_cast<int>(todo));
        break;
      }
      case API::kSized: {
        ASSERT_TRUE(EVP_CipherUpdateAAD(ctx.get(), aad.data(), todo));
        break;
      }
    }
    aad = aad.subspan(todo);
  }

  // Set up the output buffer.
  size_t max_out = in.size();
  size_t block_size = EVP_CIPHER_CTX_block_size(ctx.get());
  if (block_size > 1 &&
      (EVP_CIPHER_CTX_flags(ctx.get()) & EVP_CIPH_NO_PADDING) == 0 &&
      EVP_CIPHER_CTX_encrypting(ctx.get())) {
    max_out += block_size - (max_out % block_size);
  }
  std::vector<uint8_t> result(max_out);
  if (in_place) {
    std::copy(in.begin(), in.end(), result.begin());
    in = Span(result).first(in.size());
  }

  size_t total = 0;
  int len;
  while (!in.empty()) {
    size_t todo = chunk_size == 0 ? in.size() : std::min(in.size(), chunk_size);
    EXPECT_LE(todo, static_cast<size_t>(INT_MAX));
    ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
    size_t max = EVP_CIPHER_CTX_max_next_update(ctx.get(), todo);
    switch (api) {
      case API::kCipher:
        // `EVP_Cipher` sometimes returns the number of bytes written, or -1 on
        // error, and sometimes 1 or 0, implicitly writing `in_len` bytes.
        if (is_custom_cipher) {
          len = EVP_Cipher(ctx.get(), result.data() + total, in.data(), todo);
        } else {
          ASSERT_EQ(
              1, EVP_Cipher(ctx.get(), result.data() + total, in.data(), todo));
          len = static_cast<int>(todo);
        }
        break;
      case API::kUnsized:
        ASSERT_TRUE(EVP_CipherUpdate(ctx.get(), result.data() + total, &len,
                                     in.data(), static_cast<int>(todo)));
        break;
      case API::kSized: {
        size_t len_sz;
        ASSERT_TRUE(EVP_CipherUpdate_ex(ctx.get(), result.data() + total,
                                        &len_sz, result.size() - total,
                                        in.data(), static_cast<int>(todo)));
        len = static_cast<int>(len_sz);
        break;
      }
    }
    ASSERT_GE(len, 0);
    // `EVP_CIPHER_CTX_max_next_update` is, for all currently-implemented
    // ciphers, exact.
    EXPECT_EQ(static_cast<size_t>(len), max);
    total += static_cast<size_t>(len);
    in = in.subspan(todo);
  }
  if (op == Operation::kInvalidDecrypt) {
    switch (api) {
      case API::kCipher:
        // Only the "custom cipher" return value convention can report failures.
        // Passing all nulls should act like `EVP_CipherFinal_ex`.
        ASSERT_TRUE(is_custom_cipher);
        EXPECT_EQ(-1, EVP_Cipher(ctx.get(), nullptr, nullptr, 0));
        break;
      case API::kSized:
        // Invalid padding and invalid tags all appear as a failed
        // `EVP_CipherFinal_ex`.
        EXPECT_FALSE(
            EVP_CipherFinal_ex(ctx.get(), result.data() + total, &len));
        break;
      case API::kUnsized: {
        size_t len_sz;
        EXPECT_FALSE(EVP_CipherFinal_ex2(ctx.get(), result.data() + total,
                                         &len_sz, result.size() - total));
        len = static_cast<int>(len_sz);
        break;
      }
    }
  } else {
    ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
    size_t max = EVP_CIPHER_CTX_max_final(ctx.get());
    switch (api) {
      case API::kCipher:
        if (is_custom_cipher) {
          // Only the "custom cipher" convention has an `EVP_CipherFinal_ex`
          // equivalent.
          len = EVP_Cipher(ctx.get(), nullptr, nullptr, 0);
        } else {
          len = 0;
        }
        break;
      case API::kUnsized:
        ASSERT_TRUE(EVP_CipherFinal_ex(ctx.get(), result.data() + total, &len));
        break;
      case API::kSized: {
        size_t len_sz;
        ASSERT_TRUE(EVP_CipherFinal_ex2(ctx.get(), result.data() + total,
                                        &len_sz, result.size() - total));
        len = static_cast<int>(len_sz);
        break;
      }
    }
    ASSERT_GE(len, 0);
    // `EVP_CIPHER_CTX_max_final` is, for currently-implemented ciphers, exact
    // for all but padded decrypt.
    if (op == Operation::kDecrypt && padding) {
      EXPECT_LE(static_cast<size_t>(len), max);
    } else {
      EXPECT_EQ(static_cast<size_t>(len), max);
    }
    total += static_cast<size_t>(len);
    result.resize(total);
    EXPECT_EQ(Bytes(expected), Bytes(result));
    if (encrypt && is_aead) {
      uint8_t rtag[16];
      ASSERT_LE(tag.size(), sizeof(rtag));
      ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
      ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_GET_TAG,
                                      tag.size(), rtag));
      EXPECT_EQ(Bytes(tag), Bytes(rtag, tag.size()));
    }
  }
}

static void TestLowLevelAPI(const EVP_CIPHER *cipher, Operation op,
                            bool in_place, size_t chunk_size,
                            Span<const uint8_t> key, Span<const uint8_t> iv,
                            Span<const uint8_t> plaintext,
                            Span<const uint8_t> ciphertext) {
  bool encrypt = op == Operation::kEncrypt;
  Span<const uint8_t> in = encrypt ? plaintext : ciphertext;
  Span<const uint8_t> expected = encrypt ? ciphertext : plaintext;
  int nid = EVP_CIPHER_nid(cipher);
  bool is_ctr = nid == NID_aes_128_ctr || nid == NID_aes_192_ctr ||
                nid == NID_aes_256_ctr;
  bool is_cbc = nid == NID_aes_128_cbc || nid == NID_aes_192_cbc ||
                nid == NID_aes_256_cbc;
  bool is_ofb = nid == NID_aes_128_ofb128 || nid == NID_aes_192_ofb128 ||
                nid == NID_aes_256_ofb128;
  if (!is_ctr && !is_cbc && !is_ofb) {
    return;
  }

  // Invalid ciphertexts are not possible in any of the ciphers where this API
  // applies.
  ASSERT_NE(op, Operation::kInvalidDecrypt);

  AES_KEY aes;
  if (encrypt || !is_cbc) {
    ASSERT_EQ(0, AES_set_encrypt_key(key.data(), key.size() * 8, &aes));
  } else {
    ASSERT_EQ(0, AES_set_decrypt_key(key.data(), key.size() * 8, &aes));
  }

  std::vector<uint8_t> result;
  if (in_place) {
    result.assign(in.begin(), in.end());
  } else {
    result.resize(expected.size());
  }
  Span<uint8_t> out = Span(result);
  // Input and output sizes for all the low-level APIs should match.
  ASSERT_EQ(in.size(), out.size());

  // The low-level APIs all use block-size IVs.
  ASSERT_EQ(iv.size(), size_t{AES_BLOCK_SIZE});
  uint8_t ivec[AES_BLOCK_SIZE];
  OPENSSL_memcpy(ivec, iv.data(), iv.size());

  if (is_ctr) {
    unsigned num = 0;
    uint8_t ecount_buf[AES_BLOCK_SIZE];
    if (chunk_size == 0) {
      AES_ctr128_encrypt(in.data(), out.data(), in.size(), &aes, ivec,
                         ecount_buf, &num);
    } else {
      do {
        size_t todo = std::min(in.size(), chunk_size);
        AES_ctr128_encrypt(in.data(), out.data(), todo, &aes, ivec, ecount_buf,
                           &num);
        in = in.subspan(todo);
        out = out.subspan(todo);
      } while (!in.empty());
    }
    EXPECT_EQ(Bytes(expected), Bytes(result));
  } else if (is_cbc && chunk_size % AES_BLOCK_SIZE == 0) {
    // Note `AES_cbc_encrypt` requires block-aligned chunks.
    if (chunk_size == 0) {
      AES_cbc_encrypt(in.data(), out.data(), in.size(), &aes, ivec, encrypt);
    } else {
      do {
        size_t todo = std::min(in.size(), chunk_size);
        AES_cbc_encrypt(in.data(), out.data(), todo, &aes, ivec, encrypt);
        in = in.subspan(todo);
        out = out.subspan(todo);
      } while (!in.empty());
    }
    EXPECT_EQ(Bytes(expected), Bytes(result));
  } else if (is_ofb) {
    int num = 0;
    if (chunk_size == 0) {
      AES_ofb128_encrypt(in.data(), out.data(), in.size(), &aes, ivec, &num);
    } else {
      do {
        size_t todo = std::min(in.size(), chunk_size);
        AES_ofb128_encrypt(in.data(), out.data(), todo, &aes, ivec, &num);
        in = in.subspan(todo);
        out = out.subspan(todo);
      } while (!in.empty());
    }
    EXPECT_EQ(Bytes(expected), Bytes(result));
  }
}

enum class SizedAPIFailCase { kNever, kUpdate1, kUpdate2, kFinal };

static const char *SizedAPIFailCaseToString(SizedAPIFailCase fail_case) {
  switch (fail_case) {
    case SizedAPIFailCase::kNever:
      return "Never";
    case SizedAPIFailCase::kUpdate1:
      return "Update1";
    case SizedAPIFailCase::kUpdate2:
      return "Update2";
    case SizedAPIFailCase::kFinal:
      return "Final";
  }
  abort();
}

static size_t RoundDown(size_t n, size_t block_size) {
  return n / block_size * block_size;
}

static void TestSizedAPIRangeChecks(const EVP_CIPHER *cipher, Operation op,
                                    bool padding, Span<const uint8_t> key,
                                    Span<const uint8_t> iv,
                                    Span<const uint8_t> plaintext,
                                    Span<const uint8_t> ciphertext,
                                    Span<const uint8_t> aad,
                                    Span<const uint8_t> tag) {
  bool encrypt = op == Operation::kEncrypt;
  Span<const uint8_t> in = encrypt ? plaintext : ciphertext;
  Span<const uint8_t> expected = encrypt ? ciphertext : plaintext;
  bool is_aead = EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE;

  // Some `EVP_CIPHER`s take a variable-length key, and need to first be
  // configured with the key length, which requires configuring the cipher.
  UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
  ASSERT_TRUE(ctx);
  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), cipher, /*engine=*/nullptr,
                                /*key=*/nullptr, /*iv=*/nullptr,
                                encrypt ? 1 : 0));
  ASSERT_TRUE(EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()));
  if (!padding) {
    ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx.get(), 0));
  }

  // Configure the key.
  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), /*cipher=*/nullptr,
                                /*engine=*/nullptr, key.data(),
                                /*iv=*/nullptr,
                                /*enc=*/-1));

  // Configure the IV to run the actual operation. Callers that wish to use
  // a key for multiple, potentially concurrent, operations will likely copy
  // at this point. The `EVP_CIPHER_CTX` API uses the same type to represent
  // a pre-computed key schedule and a streaming operation.
  if (is_aead) {
    ASSERT_LE(iv.size(), size_t{INT_MAX});
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                    static_cast<int>(iv.size()), nullptr));
    ASSERT_EQ(EVP_CIPHER_CTX_iv_length(ctx.get()), iv.size());
  } else {
    ASSERT_EQ(iv.size(), EVP_CIPHER_CTX_iv_length(ctx.get()));
  }
  ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), /*cipher=*/nullptr,
                                /*engine=*/nullptr,
                                /*key=*/nullptr, iv.data(), /*enc=*/-1));

  if (is_aead) {
    if (!encrypt) {
      ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_TAG,
                                      tag.size(),
                                      const_cast<uint8_t *>(tag.data())));
    }
    ASSERT_TRUE(EVP_CipherUpdateAAD(ctx.get(), aad.data(), aad.size()));
  }

  size_t block_size = EVP_CIPHER_block_size(cipher);
  for (size_t len_to_split = 0; len_to_split <= in.size(); ++len_to_split) {
    SCOPED_TRACE(len_to_split);
    for (SizedAPIFailCase fail_case :
         {SizedAPIFailCase::kNever, SizedAPIFailCase::kUpdate1,
          SizedAPIFailCase::kUpdate2, SizedAPIFailCase::kFinal}) {
      SCOPED_TRACE(SizedAPIFailCaseToString(fail_case));

      UniquePtr<EVP_CIPHER_CTX> thisctx(EVP_CIPHER_CTX_new());
      ASSERT_TRUE(thisctx);
      ASSERT_TRUE(EVP_CIPHER_CTX_copy(thisctx.get(), ctx.get()));

      size_t update_size = RoundDown(
          (padding && !encrypt)
              // When decrypting, the final block will not be output right away.
              ? std::max(in.size(), size_t{1}) - 1
              : in.size(),
          block_size);
      Span<const uint8_t> in1 = in.first(len_to_split);
      size_t update1_size = RoundDown(
          (padding && !encrypt)
              // When decrypting, the final block will not be output right away.
              ? std::max(in1.size(), size_t{1}) - 1
              : in1.size(),
          block_size);
      size_t update2_size = update_size - update1_size;
      Span<const uint8_t> in2 = in.subspan(len_to_split);
      size_t final_size = expected.size() - update1_size - update2_size;

      // Now, finally, the cipher is ready to be abused.
      size_t len;
      if (fail_case == SizedAPIFailCase::kUpdate1 && update1_size > 0) {
        std::vector<uint8_t> buf(update1_size - 1);
        EXPECT_FALSE(EVP_CipherUpdate_ex(thisctx.get(), buf.data(), &len,
                                         buf.size(), in1.data(), in1.size()));
        EXPECT_EQ(len, size_t{0});
        continue;
      } else {
        std::vector<uint8_t> buf(update1_size);
        EXPECT_TRUE(EVP_CipherUpdate_ex(thisctx.get(), buf.data(), &len,
                                        buf.size(), in1.data(), in1.size()));
        EXPECT_EQ(len, update1_size);
        EXPECT_EQ(Bytes(expected.first(update1_size)), Bytes(buf));
      }
      if (fail_case == SizedAPIFailCase::kUpdate2 && update2_size > 0) {
        std::vector<uint8_t> buf(update2_size - 1);
        EXPECT_FALSE(EVP_CipherUpdate_ex(thisctx.get(), buf.data(), &len,
                                         buf.size(), in2.data(), in2.size()));
        EXPECT_EQ(len, size_t{0});
        continue;
      } else {
        std::vector<uint8_t> buf(update2_size);
        EXPECT_TRUE(EVP_CipherUpdate_ex(thisctx.get(), buf.data(), &len,
                                        buf.size(), in2.data(), in2.size()));
        EXPECT_EQ(len, update2_size);
        EXPECT_EQ(Bytes(expected.subspan(update1_size, update2_size)),
                  Bytes(buf));
      }
      if (fail_case == SizedAPIFailCase::kFinal && final_size > 0) {
        std::vector<uint8_t> buf(final_size - 1);
        EXPECT_FALSE(
            EVP_CipherFinal_ex2(thisctx.get(), buf.data(), &len, buf.size()));
        EXPECT_EQ(len, size_t{0});
        continue;
      } else {
        std::vector<uint8_t> buf(final_size);
        EXPECT_TRUE(
            EVP_CipherFinal_ex2(thisctx.get(), buf.data(), &len, buf.size()));
        EXPECT_EQ(len, final_size);
        EXPECT_EQ(Bytes(expected.subspan(update1_size + update2_size)),
                  Bytes(buf));
      }
      if (encrypt && is_aead) {
        uint8_t rtag[16];
        ASSERT_LE(tag.size(), sizeof(rtag));
        ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(thisctx.get(), EVP_CTRL_AEAD_GET_TAG,
                                        tag.size(), rtag));
        EXPECT_EQ(Bytes(tag), Bytes(rtag, tag.size()));
      }
    }
  }
}

static void TestCipher(const EVP_CIPHER *cipher, Operation input_op,
                       bool padding, Span<const uint8_t> key,
                       Span<const uint8_t> iv, Span<const uint8_t> plaintext,
                       Span<const uint8_t> ciphertext, Span<const uint8_t> aad,
                       Span<const uint8_t> tag) {
  size_t block_size = EVP_CIPHER_block_size(cipher);
  std::vector<Operation> ops = {Operation::kEncrypt, Operation::kDecrypt};
  if (input_op != Operation::kBoth) {
    ops = {input_op};
  }
  for (Operation op : ops) {
    SCOPED_TRACE(OperationToString(op));
    // Zero indicates a single-shot API.
    static const size_t kChunkSizes[] = {0,  1,  2,  5,  7,  8,  9,  15, 16,
                                         17, 31, 32, 33, 63, 64, 65, 512};
    for (size_t chunk_size : kChunkSizes) {
      SCOPED_TRACE(chunk_size);
      if (chunk_size > plaintext.size() && chunk_size > ciphertext.size() &&
          chunk_size > aad.size()) {
        continue;
      }
      for (bool in_place : {false, true}) {
        SCOPED_TRACE(in_place);
        for (bool copy : {false, true}) {
          SCOPED_TRACE(copy);
          TestCipherAPI(cipher, op, padding, copy, in_place, API::kSized,
                        chunk_size, key, iv, plaintext, ciphertext, aad, tag);
          TestCipherAPI(cipher, op, padding, copy, in_place, API::kUnsized,
                        chunk_size, key, iv, plaintext, ciphertext, aad, tag);
          if (!padding && chunk_size % block_size == 0) {
            TestCipherAPI(cipher, op, padding, copy, in_place, API::kCipher,
                          chunk_size, key, iv, plaintext, ciphertext, aad, tag);
          }
        }
        if (!padding) {
          TestLowLevelAPI(cipher, op, in_place, chunk_size, key, iv, plaintext,
                          ciphertext);
        }
      }
    }
    if (op != Operation::kInvalidDecrypt) {
      TestSizedAPIRangeChecks(cipher, op, padding, key, iv, plaintext,
                              ciphertext, aad, tag);
    }
  }
}

static void CipherFileTest(FileTest *t) {
  std::string cipher_str;
  ASSERT_TRUE(t->GetAttribute(&cipher_str, "Cipher"));
  SCOPED_TRACE(cipher_str);
  const EVP_CIPHER *cipher = GetCipher(cipher_str);
  ASSERT_TRUE(cipher);

  std::vector<uint8_t> key, iv, plaintext, ciphertext, aad, tag;
  ASSERT_TRUE(t->GetBytes(&key, "Key"));
  ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
  ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
  if (EVP_CIPHER_iv_length(cipher) > 0) {
    ASSERT_TRUE(t->GetBytes(&iv, "IV"));
  }
  if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) {
    ASSERT_TRUE(t->GetBytes(&aad, "AAD"));
    ASSERT_TRUE(t->GetBytes(&tag, "Tag"));
  }

  Operation op = Operation::kBoth;
  if (t->HasAttribute("Operation")) {
    const std::string &str = t->GetAttributeOrDie("Operation");
    if (str == "Encrypt" || str == "ENCRYPT") {
      op = Operation::kEncrypt;
    } else if (str == "Decrypt" || str == "DECRYPT") {
      op = Operation::kDecrypt;
    } else if (str == "InvalidDecrypt") {
      op = Operation::kInvalidDecrypt;
    } else {
      FAIL() << "Unknown operation: " << str;
    }
  }

  TestCipher(cipher, op, /*padding=*/false, key, iv, plaintext, ciphertext, aad,
             tag);
}

TEST(CipherTest, TestVectors) {
  FileTestGTest("crypto/cipher/test/cipher_tests.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_AES_128_CBC) {
  FileTestGTest("crypto/cipher/test/nist_cavp/aes_128_cbc.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_AES_128_CTR) {
  FileTestGTest("crypto/cipher/test/nist_cavp/aes_128_ctr.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_AES_192_CBC) {
  FileTestGTest("crypto/cipher/test/nist_cavp/aes_192_cbc.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_AES_192_CTR) {
  FileTestGTest("crypto/cipher/test/nist_cavp/aes_192_ctr.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_AES_256_CBC) {
  FileTestGTest("crypto/cipher/test/nist_cavp/aes_256_cbc.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_AES_256_CTR) {
  FileTestGTest("crypto/cipher/test/nist_cavp/aes_256_ctr.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_TDES_CBC) {
  FileTestGTest("crypto/cipher/test/nist_cavp/tdes_cbc.txt", CipherFileTest);
}

TEST(CipherTest, CAVP_TDES_ECB) {
  FileTestGTest("crypto/cipher/test/nist_cavp/tdes_ecb.txt", CipherFileTest);
}

TEST(CipherTest, WycheproofAESCBC) {
  FileTestGTest("third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt",
                [](FileTest *t) {
                  t->IgnoreInstruction("type");
                  t->IgnoreInstruction("ivSize");

                  std::string key_size;
                  ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
                  SCOPED_TRACE(std::string{"aes_"} + key_size +
                               std::string{"_cbc"});
                  const EVP_CIPHER *cipher;
                  switch (atoi(key_size.c_str())) {
                    case 128:
                      cipher = EVP_aes_128_cbc();
                      break;
                    case 192:
                      cipher = EVP_aes_192_cbc();
                      break;
                    case 256:
                      cipher = EVP_aes_256_cbc();
                      break;
                    default:
                      FAIL() << "Unsupported key size: " << key_size;
                  }

                  std::vector<uint8_t> key, iv, msg, ct;
                  ASSERT_TRUE(t->GetBytes(&key, "key"));
                  ASSERT_TRUE(t->GetBytes(&iv, "iv"));
                  ASSERT_TRUE(t->GetBytes(&msg, "msg"));
                  ASSERT_TRUE(t->GetBytes(&ct, "ct"));
                  WycheproofResult result;
                  ASSERT_TRUE(GetWycheproofResult(t, &result));
                  TestCipher(cipher,
                             result.IsValid() ? Operation::kBoth
                                              : Operation::kInvalidDecrypt,
                             /*padding=*/true, key, iv, msg, ct, /*aad=*/{},
                             /*tag=*/{});
                });
}

TEST(CipherTest, SHA1WithSecretSuffix) {
  uint8_t buf[SHA_CBLOCK * 4];
  RAND_bytes(buf, sizeof(buf));
  // Hashing should run in time independent of the bytes.
  CONSTTIME_SECRET(buf, sizeof(buf));

  // Exhaustively testing interesting cases in this function is cubic in the
  // block size, so we test in 3-byte increments.
  constexpr size_t kSkip = 3;
  // This value should be less than 8 to test the edge case when the 8-byte
  // length wraps to the next block.
  static_assert(kSkip < 8, "kSkip is too large");

  // `EVP_sha1_final_with_secret_suffix` is sensitive to the public length of
  // the partial block previously hashed. In TLS, this is the HMAC prefix, the
  // header, and the public minimum padding length.
  for (size_t prefix = 0; prefix < SHA_CBLOCK; prefix += kSkip) {
    SCOPED_TRACE(prefix);
    // The first block is treated differently, so we run with up to three
    // blocks of length variability.
    for (size_t max_len = 0; max_len < 3 * SHA_CBLOCK; max_len += kSkip) {
      SCOPED_TRACE(max_len);
      for (size_t len = 0; len <= max_len; len += kSkip) {
        SCOPED_TRACE(len);

        uint8_t expected[SHA_DIGEST_LENGTH];
        SHA1(buf, prefix + len, expected);
        CONSTTIME_DECLASSIFY(expected, sizeof(expected));

        // Make a copy of the secret length to avoid interfering with the loop.
        size_t secret_len = len;
        CONSTTIME_SECRET(&secret_len, sizeof(secret_len));

        SHA_CTX ctx;
        SHA1_Init(&ctx);
        SHA1_Update(&ctx, buf, prefix);
        uint8_t computed[SHA_DIGEST_LENGTH];
        ASSERT_TRUE(EVP_sha1_final_with_secret_suffix(
            &ctx, computed, buf + prefix, secret_len, max_len));

        CONSTTIME_DECLASSIFY(computed, sizeof(computed));
        EXPECT_EQ(Bytes(expected), Bytes(computed));
      }
    }
  }
}

TEST(CipherTest, SHA256WithSecretSuffix) {
  uint8_t buf[SHA256_CBLOCK * 4];
  RAND_bytes(buf, sizeof(buf));
  // Hashing should run in time independent of the bytes.
  CONSTTIME_SECRET(buf, sizeof(buf));

  // Exhaustively testing interesting cases in this function is cubic in the
  // block size, so we test in 3-byte increments.
  constexpr size_t kSkip = 3;
  // This value should be less than 8 to test the edge case when the 8-byte
  // length wraps to the next block.
  static_assert(kSkip < 8, "kSkip is too large");

  // `EVP_sha256_final_with_secret_suffix` is sensitive to the public length of
  // the partial block previously hashed. In TLS, this is the HMAC prefix, the
  // header, and the public minimum padding length.
  for (size_t prefix = 0; prefix < SHA256_CBLOCK; prefix += kSkip) {
    SCOPED_TRACE(prefix);
    // The first block is treated differently, so we run with up to three
    // blocks of length variability.
    for (size_t max_len = 0; max_len < 3 * SHA256_CBLOCK; max_len += kSkip) {
      SCOPED_TRACE(max_len);
      for (size_t len = 0; len <= max_len; len += kSkip) {
        SCOPED_TRACE(len);

        uint8_t expected[SHA256_DIGEST_LENGTH];
        SHA256(buf, prefix + len, expected);
        CONSTTIME_DECLASSIFY(expected, sizeof(expected));

        // Make a copy of the secret length to avoid interfering with the loop.
        size_t secret_len = len;
        CONSTTIME_SECRET(&secret_len, sizeof(secret_len));

        SHA256_CTX ctx;
        SHA256_Init(&ctx);
        SHA256_Update(&ctx, buf, prefix);
        uint8_t computed[SHA256_DIGEST_LENGTH];
        ASSERT_TRUE(EVP_sha256_final_with_secret_suffix(
            &ctx, computed, buf + prefix, secret_len, max_len));

        CONSTTIME_DECLASSIFY(computed, sizeof(computed));
        EXPECT_EQ(Bytes(expected), Bytes(computed));
      }
    }
  }
}

TEST(CipherTest, GetCipher) {
  const EVP_CIPHER *cipher = EVP_get_cipherbynid(NID_aes_128_gcm);
  ASSERT_TRUE(cipher);
  EXPECT_EQ(NID_aes_128_gcm, EVP_CIPHER_nid(cipher));

  cipher = EVP_get_cipherbyname("aes-128-gcm");
  ASSERT_TRUE(cipher);
  EXPECT_EQ(NID_aes_128_gcm, EVP_CIPHER_nid(cipher));

  cipher = EVP_get_cipherbyname("AES-128-GCM");
  ASSERT_TRUE(cipher);
  EXPECT_EQ(NID_aes_128_gcm, EVP_CIPHER_nid(cipher));

  // We support a tcpdump-specific alias for 3DES.
  cipher = EVP_get_cipherbyname("3des");
  ASSERT_TRUE(cipher);
  EXPECT_EQ(NID_des_ede3_cbc, EVP_CIPHER_nid(cipher));
}

// Test the AES-GCM EVP_CIPHER's internal IV management APIs. OpenSSH uses these
// APIs.
TEST(CipherTest, GCMIncrementingIV) {
  const EVP_CIPHER *kCipher = EVP_aes_128_gcm();
  static const uint8_t kKey[16] = {0, 1, 2,  3,  4,  5,  6,  7,
                                   8, 9, 10, 11, 12, 13, 14, 15};
  static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};

  auto expect_iv = [&](EVP_CIPHER_CTX *ctx, Span<const uint8_t> iv, bool enc) {
    // Make a reference ciphertext.
    ScopedEVP_CIPHER_CTX ref;
    ASSERT_TRUE(EVP_EncryptInit_ex(ref.get(), kCipher, /*impl=*/nullptr,
                                   kKey, /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ref.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                    static_cast<int>(iv.size()), nullptr));
    ASSERT_TRUE(EVP_EncryptInit_ex(ref.get(), /*cipher=*/nullptr,
                                   /*impl=*/nullptr, /*key=*/nullptr,
                                   iv.data()));
    uint8_t ciphertext[sizeof(kInput)];
    int ciphertext_len;
    ASSERT_TRUE(EVP_EncryptUpdate(ref.get(), ciphertext, &ciphertext_len,
                                  kInput, sizeof(kInput)));
    int extra_len;
    ASSERT_TRUE(EVP_EncryptFinal_ex(ref.get(), nullptr, &extra_len));
    ASSERT_EQ(extra_len, 0);
    uint8_t tag[16];
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ref.get(), EVP_CTRL_AEAD_GET_TAG,
                                    sizeof(tag), tag));

    if (enc) {
      uint8_t actual[sizeof(kInput)];
      int actual_len;
      ASSERT_TRUE(
          EVP_EncryptUpdate(ctx, actual, &actual_len, kInput, sizeof(kInput)));
      ASSERT_TRUE(EVP_EncryptFinal_ex(ctx, nullptr, &extra_len));
      ASSERT_EQ(extra_len, 0);
      EXPECT_EQ(Bytes(actual, actual_len), Bytes(ciphertext, ciphertext_len));
      uint8_t actual_tag[16];
      ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
                                      sizeof(actual_tag), actual_tag));
      EXPECT_EQ(Bytes(actual_tag), Bytes(tag));
    } else {
      ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
                                      const_cast<uint8_t *>(tag)));
      uint8_t actual[sizeof(kInput)];
      int actual_len;
      ASSERT_TRUE(EVP_DecryptUpdate(ctx, actual, &actual_len, ciphertext,
                                    sizeof(ciphertext)));
      ASSERT_TRUE(EVP_DecryptFinal_ex(ctx, nullptr, &extra_len));
      ASSERT_EQ(extra_len, 0);
      EXPECT_EQ(Bytes(actual, actual_len), Bytes(kInput));
    }
  };

  {
    // Passing in a fixed IV length of -1 sets the whole IV, but then configures
    // `EVP_CIPHER_CTX` to increment the bottom 8 bytes of the IV.
    static const uint8_t kIV1[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    static const uint8_t kIV2[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13};
    static const uint8_t kIV3[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14};
    static const uint8_t kIV4[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, -1,
                                    const_cast<uint8_t *>(kIV1)));

    // EVP_CTRL_GCM_IV_GEN both configures and returns the IV.
    uint8_t iv[12];
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV1));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV1, /*enc=*/true));

    // Continuing to run EVP_CTRL_GCM_IV_GEN should increment the IV.
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV2));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV2, /*enc=*/true));

    // Passing in a shorter length outputs the suffix portion.
    uint8_t suffix[8];
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN,
                                    sizeof(suffix), suffix));
    EXPECT_EQ(Bytes(suffix), Bytes(Span(kIV3).last(sizeof(suffix))));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV3, /*enc=*/true));

    // A length of -1 returns the whole IV.
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, -1, iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV4));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV4, /*enc=*/true));
  }

  {
    // Similar to the above, but for decrypting.
    static const uint8_t kIV1[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    static const uint8_t kIV2[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, -1,
                                    const_cast<uint8_t *>(kIV1)));

    uint8_t iv[12];
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV1));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV1, /*enc=*/false));

    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV2));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV2, /*enc=*/false));
  }

  {
    // Test that only the bottom 8 bytes are used as a counter.
    static const uint8_t kIV1[12] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    static const uint8_t kIV2[12] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    static const uint8_t kIV3[12] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x01};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, -1,
                                    const_cast<uint8_t *>(kIV1)));

    uint8_t iv[12];
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV1));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV1, /*enc=*/true));

    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV2));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV2, /*enc=*/true));

    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV3));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV3, /*enc=*/true));
  }

  {
    // Test with a longer IV length.
    static const uint8_t kIV1[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                     0xff, 0xff, 0xff, 0xff};
    static const uint8_t kIV2[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                     0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
                                     0x00, 0x00, 0x00, 0x00};
    static const uint8_t kIV3[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                     0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
                                     0x00, 0x00, 0x00, 0x01};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                    sizeof(kIV1), nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, -1,
                                    const_cast<uint8_t *>(kIV1)));

    uint8_t iv[16];
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV1));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV1, /*enc=*/true));

    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV2));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV2, /*enc=*/true));

    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN, sizeof(iv), iv));
    EXPECT_EQ(Bytes(iv), Bytes(kIV3));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV3, /*enc=*/true));
  }

  {
    // When decrypting, callers are expected to configure the fixed half and
    // invocation half separately. The two will get stitched together into the
    // final IV.
    const uint8_t kIV[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 4,
                                    const_cast<uint8_t *>(kIV)));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IV_INV, 8,
                                    const_cast<uint8_t *>(kIV + 4)));
    // EVP_CTRL_GCM_SET_IV_INV is sufficient to configure the IV. There is no
    // need to call EVP_CTRL_GCM_IV_GEN.
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV, /*enc=*/false));
  }

  {
    // Stitching together a decryption IV that exceeds the standard IV length.
    const uint8_t kIV[16] = {1, 2,  3,  4,  5,  6,  7,  8,
                             9, 10, 11, 12, 13, 14, 15, 16};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                    sizeof(kIV), nullptr));

    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 4,
                                    const_cast<uint8_t *>(kIV)));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IV_INV, 12,
                                    const_cast<uint8_t *>(kIV + 4)));
    // EVP_CTRL_GCM_SET_IV_INV is sufficient to configure the IV. There is no
    // need to call EVP_CTRL_GCM_IV_GEN.
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), kIV, /*enc=*/false));
  }

  {
    // Fixed IVs must be at least 4 bytes and admit at least an 8 byte counter.
    const uint8_t kIV[16] = {1, 2,  3,  4,  5,  6,  7,  8,
                             9, 10, 11, 12, 13, 14, 15, 16};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));

    // This means the default IV length only allows a 4/8 split.
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 0,
                                     const_cast<uint8_t *>(kIV)));
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 3,
                                     const_cast<uint8_t *>(kIV)));
    EXPECT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 4,
                                    const_cast<uint8_t *>(kIV)));
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 5,
                                     const_cast<uint8_t *>(kIV)));
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 16,
                                     const_cast<uint8_t *>(kIV)));

    // A longer IV allows a wider range.
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN, 16, nullptr));
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 0,
                                     const_cast<uint8_t *>(kIV)));
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 3,
                                     const_cast<uint8_t *>(kIV)));
    EXPECT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 4,
                                    const_cast<uint8_t *>(kIV)));
    EXPECT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 6,
                                    const_cast<uint8_t *>(kIV)));
    EXPECT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 8,
                                    const_cast<uint8_t *>(kIV)));
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 9,
                                     const_cast<uint8_t *>(kIV)));
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 16,
                                     const_cast<uint8_t *>(kIV)));
  }

  {
    // When encrypting, setting a fixed IV randomizes the counter portion.
    const uint8_t kFixedIV[4] = {1, 2, 3, 4};
    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED,
                                    sizeof(kFixedIV),
                                    const_cast<uint8_t *>(kFixedIV)));
    uint8_t counter[8];
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN,
                                    sizeof(counter), counter));

    uint8_t iv[12];
    memcpy(iv, kFixedIV, sizeof(kFixedIV));
    memcpy(iv + sizeof(kFixedIV), counter, sizeof(counter));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), iv, /*enc=*/true));

    // The counter continues to act as a counter.
    uint8_t counter2[8];
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN,
                                    sizeof(counter2), counter2));
    EXPECT_EQ(CRYPTO_load_u64_be(counter2), CRYPTO_load_u64_be(counter) + 1);
    memcpy(iv + sizeof(kFixedIV), counter2, sizeof(counter2));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), iv, /*enc=*/true));
  }

  {
    // Same as above, but with a larger IV.
    const uint8_t kFixedIV[8] = {1, 2, 3, 4, 5, 6, 7, 8};
    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                    sizeof(kFixedIV) + 8, nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED,
                                    sizeof(kFixedIV),
                                    const_cast<uint8_t *>(kFixedIV)));
    uint8_t counter[8];
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN,
                                    sizeof(counter), counter));

    uint8_t iv[16];
    memcpy(iv, kFixedIV, sizeof(kFixedIV));
    memcpy(iv + sizeof(kFixedIV), counter, sizeof(counter));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), iv, /*enc=*/true));

    // The counter continues to act as a counter.
    uint8_t counter2[8];
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN,
                                    sizeof(counter2), counter2));
    EXPECT_EQ(CRYPTO_load_u64_be(counter2), CRYPTO_load_u64_be(counter) + 1);
    memcpy(iv + sizeof(kFixedIV), counter2, sizeof(counter2));
    ASSERT_NO_FATAL_FAILURE(expect_iv(ctx.get(), iv, /*enc=*/true));
  }

  {
    // If GCM IV length is less than 8, SET_IV_FIXED(-1) restores the whole IV,
    // but a subsequent EVP_CTRL_GCM_IV_GEN call must fail rather than
    // underflow.
    const uint8_t kIV[7] = {1, 2, 3, 4, 5, 6, 7};
    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN, 7, nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, -1,
                                    const_cast<uint8_t *>(kIV)));
    uint8_t counter[8];
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN,
                                     sizeof(counter), counter));
  }

  {
    // EVP_CTRL_GCM_SET_IV_INV should not overflow the IV.
    const uint8_t kFixedIV[4] = {1, 2, 3, 4};
    const uint8_t kIVInvTooLarge[13] = {1, 2, 3,  4,  5,  6, 7,
                                        8, 9, 10, 11, 12, 13};

    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 4,
                                    const_cast<uint8_t *>(kFixedIV)));
    // Negative lengths are invalid.
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IV_INV, -1,
                                     const_cast<uint8_t *>(kIVInvTooLarge)));
    // Overflows the IV.
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IV_INV, 13,
                                     const_cast<uint8_t *>(kIVInvTooLarge)));
  }
}

TEST(CipherTest, SetIVLengthResets) {
  const EVP_CIPHER *kCipher = EVP_aes_128_gcm();
  static const uint8_t kKey[16] = {};
  static const uint8_t kIV[12] = {};

  {
    // Set an IV...
    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr,
                                   /*key=*/nullptr, kIV));
    // But then change the length, invalidating the IV.
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN, 64, nullptr));
    // Configuring the key should not be enough...
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), /*cipher=*/nullptr,
                                   /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    // ...to perform any operation.
    uint8_t in[1] = {0};
    uint8_t out[1];
    int out_len;
    EXPECT_FALSE(EVP_EncryptUpdate(ctx.get(), out, &out_len, in, sizeof(in)));
  }

  {
    // Changing IV length should also reset the unusual IV generation feature.
    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IV_FIXED, 4,
                                    const_cast<uint8_t *>(kIV)));
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN, 64, nullptr));
    uint8_t counter[8];
    EXPECT_FALSE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_IV_GEN,
                                     sizeof(counter), counter));
  }

  {
    // Set an IV...
    ScopedEVP_CIPHER_CTX ctx;
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), kCipher, /*impl=*/nullptr,
                                   /*key=*/nullptr, kIV));
    // ...and then perform a no-op IV length change.
    ASSERT_TRUE(
        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN, 12, nullptr));
    // This time the IV is left alone. Some applications expect this to work.
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), /*cipher=*/nullptr,
                                   /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    uint8_t in[1] = {0};
    uint8_t out[1];
    int out_len;
    EXPECT_TRUE(EVP_EncryptUpdate(ctx.get(), out, &out_len, in, sizeof(in)));
  }
}

// EVP_CIPHER's buffer management for AES-GCM's variable-length IV is messy.
// Ensure it is correct even if the caller encrypts in a contrived way.
TEST(CipherTest, GCMRepeatedlyChangeIVLength) {
  const uint8_t kKey[16] = {0, 1, 2,  3,  4,  5,  6,  7,
                            8, 9, 10, 11, 12, 13, 14, 15};
  const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
  const std::vector<int> kLengthSequences[] = {
      // Keep making it bigger, all allocated.
      {64, 128, 256},
      // Keep making it bigger, all within the built-in buffer.
      {12, 13, 14, 15, 16},
      // Make it smaller, all allocated.
      {256, 128, 64},
      // Make it smaller, all within the built-in buffer.
      {12, 11, 10, 9},
      // As we go down and back up, don't lose track of which buffer it is.
      {256, 128, 64, 32, 16, 8, 4, 8, 16},
      {256, 128, 64, 32, 16, 8, 4, 8, 16, 32, 64, 128},
  };
  for (const auto &length_seq : kLengthSequences) {
    SCOPED_TRACE(testing::PrintToString(length_seq));

    // Compute the expected output.
    UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(),
                                   /*impl=*/nullptr, kKey,
                                   /*iv=*/nullptr));
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                    length_seq.back(), nullptr));
    std::vector<uint8_t> iv(length_seq.back());
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), /*cipher=*/nullptr,
                                   /*impl=*/nullptr, /*key=*/nullptr,
                                   iv.data()));
    uint8_t expected_ciphertext[sizeof(kInput)];
    size_t len;
    ASSERT_TRUE(EVP_EncryptUpdate_ex(ctx.get(), expected_ciphertext, &len,
                                     sizeof(expected_ciphertext), kInput,
                                     sizeof(kInput)));
    ASSERT_EQ(len, sizeof(expected_ciphertext));
    ASSERT_TRUE(EVP_EncryptFinal_ex2(ctx.get(), nullptr, &len, 0));
    uint8_t expected_tag[12];
    ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_GET_TAG,
                                    sizeof(expected_tag), expected_tag));

    for (bool copy : {false, true}) {
      SCOPED_TRACE(copy);

      ctx.reset(EVP_CIPHER_CTX_new());
      ASSERT_TRUE(ctx);
      ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(),
                                     /*impl=*/nullptr, kKey,
                                     /*iv=*/nullptr));
      ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
      // Simulate a caller that cannot make up its mind about the IV length.
      for (int iv_len : length_seq) {
        ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
                                        iv_len, nullptr));
        ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
      }
      // Finish the encryption.
      ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), /*cipher=*/nullptr,
                                     /*impl=*/nullptr, /*key=*/nullptr,
                                     iv.data()));
      ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
      uint8_t ciphertext[sizeof(kInput)];
      ASSERT_TRUE(EVP_EncryptUpdate_ex(ctx.get(), ciphertext, &len,
                                       sizeof(ciphertext), kInput,
                                       sizeof(kInput)));
      ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
      ASSERT_EQ(len, sizeof(ciphertext));
      ASSERT_TRUE(EVP_EncryptFinal_ex2(ctx.get(), nullptr, &len, 0));
      ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
      uint8_t tag[12];
      ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_GET_TAG,
                                      sizeof(tag), tag));

      // The answer should have been the same.
      EXPECT_EQ(Bytes(ciphertext), Bytes(expected_ciphertext));
      EXPECT_EQ(Bytes(tag), Bytes(expected_tag));
    }
  }
}

TEST(CipherTest, RC2KeyLengthOverflow) {
  const EVP_CIPHER *cipher = EVP_rc2_cbc();
  UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
  ASSERT_TRUE(ctx);

  ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr));

  if (EVP_CIPHER_CTX_set_key_length(ctx.get(), 0x80000000)) {
    std::vector<uint8_t> key(128, 0);
    // This should not crash.
    EVP_DecryptInit_ex(ctx.get(), nullptr, nullptr, key.data(), nullptr);
  }
}

// |EVP_CIPHER_CTX| is a caller-allocatable C struct. Some APIs are required to
// work when the struct is uninitialized.
TEST(CipherTest, Uninitialized) {
  // |EVP_CIPHER_CTX_init| initializes its input from an arbitrary state.
  {
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_CipherInit_ex(&ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr, -1);
    EVP_CIPHER_CTX_cleanup(&ctx);
  }

  // |EVP_CipherInit| internally calls |EVP_CIPHER_CTX_init| and thus
  // initializes it from an arbitrary state.
  {
    EVP_CIPHER_CTX ctx;
    EVP_CipherInit(&ctx, EVP_aes_128_gcm(), nullptr, nullptr, -1);
    EVP_CIPHER_CTX_cleanup(&ctx);
  }
}

TEST(CipherTest, NonPoisoningErrors) {
  const uint8_t kKey[16] = {1, 2,  3,  4,  5,  6,  7,  8,
                            9, 10, 11, 12, 13, 14, 15, 16};
  const uint8_t kIV[16] = {0};
  uint8_t in[32] = {0};
  uint8_t out[64];
  size_t out_len;

  // EncryptUpdate output buffer size error does not poison the context.
  {
    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(
        EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kKey, kIV));
    // Calling EVP_EncryptUpdate_ex with max_out_len = 0 fails with
    // CIPHER_R_BUFFER_TOO_SMALL.
    EXPECT_FALSE(
        EVP_EncryptUpdate_ex(ctx.get(), out, &out_len, 0, in, sizeof(in)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            CIPHER_R_BUFFER_TOO_SMALL));
    // The context is not poisoned; a subsequent call with sufficient output
    // buffer succeeds.
    EXPECT_TRUE(EVP_EncryptUpdate_ex(ctx.get(), out, &out_len, sizeof(out), in,
                                     sizeof(in)));
  }

  // EncryptFinal output buffer size error does not poison the context.
  {
    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(
        EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kKey, kIV));
    ASSERT_TRUE(EVP_EncryptUpdate_ex(ctx.get(), out, &out_len, sizeof(out), in,
                                     sizeof(in)));
    // Calling EVP_EncryptFinal_ex2 with max_out_len = 0 fails with
    // CIPHER_R_BUFFER_TOO_SMALL.
    EXPECT_FALSE(EVP_EncryptFinal_ex2(ctx.get(), out, &out_len, 0));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            CIPHER_R_BUFFER_TOO_SMALL));
    // The context is not poisoned; a subsequent call with sufficient output
    // buffer succeeds.
    EXPECT_TRUE(EVP_EncryptFinal_ex2(ctx.get(), out, &out_len, sizeof(out)));
  }

  // DecryptUpdate output buffer size error does not poison the context.
  {
    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(
        EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kKey, kIV));
    // Calling EVP_DecryptUpdate_ex with max_out_len = 0 fails with
    // CIPHER_R_BUFFER_TOO_SMALL.
    EXPECT_FALSE(
        EVP_DecryptUpdate_ex(ctx.get(), out, &out_len, 0, in, sizeof(in)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            CIPHER_R_BUFFER_TOO_SMALL));
    // The context is not poisoned; a subsequent call with sufficient output
    // buffer succeeds.
    EXPECT_TRUE(EVP_DecryptUpdate_ex(ctx.get(), out, &out_len, sizeof(out), in,
                                     sizeof(in)));
  }

  // DecryptFinal output buffer size error does not poison the context.
  {
    // Generate valid ciphertext for 10 bytes of input (so payload length is 10
    // > 0).
    uint8_t ciphertext[32];
    size_t ciphertext_len = 0, final_len = 0;
    bssl::UniquePtr<EVP_CIPHER_CTX> enc_ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(enc_ctx);
    ASSERT_TRUE(EVP_EncryptInit_ex(enc_ctx.get(), EVP_aes_128_cbc(), nullptr,
                                   kKey, kIV));
    ASSERT_TRUE(EVP_EncryptUpdate_ex(enc_ctx.get(), ciphertext, &ciphertext_len,
                                     sizeof(ciphertext), in, 10));
    ASSERT_TRUE(EVP_EncryptFinal_ex2(enc_ctx.get(), ciphertext + ciphertext_len,
                                     &final_len,
                                     sizeof(ciphertext) - ciphertext_len));
    ciphertext_len += final_len;

    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(
        EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kKey, kIV));
    ASSERT_TRUE(EVP_DecryptUpdate_ex(ctx.get(), out, &out_len, sizeof(out),
                                     ciphertext, ciphertext_len));
    // Calling EVP_DecryptFinal_ex2 with max_out_len = 5 (< payload size 10)
    // fails with CIPHER_R_BUFFER_TOO_SMALL.
    EXPECT_FALSE(EVP_DecryptFinal_ex2(ctx.get(), out, &out_len, 5));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            CIPHER_R_BUFFER_TOO_SMALL));
    // The context is not poisoned; a subsequent call with sufficient output
    // buffer succeeds.
    EXPECT_TRUE(EVP_DecryptFinal_ex2(ctx.get(), out, &out_len, sizeof(out)));
    EXPECT_EQ(out_len, 10u);
  }

  // DecryptFinal padding failure does not poison the context.
  //
  // google/play-licensing, sadly, relies on it by only ever calling `doFinal`
  // on a cipher object. (Which is known broken as the CBC IV will be wrong for
  // next call, but as next call's padding will pass if the input string has
  // correct padding, the IV for the call after will be correct again,
  // therefore reading bad data once in their `unobfuscate` method will "fix
  // itself" two calls later).
  {
    uint8_t bad_ciphertext[16] = {0};
    int len;

    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(
        EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kKey, kIV));
    ASSERT_TRUE(EVP_DecryptUpdate(ctx.get(), out, &len, bad_ciphertext,
                                  sizeof(bad_ciphertext)));
    // EVP_DecryptFinal_ex fails due to bad padding.
    EXPECT_FALSE(EVP_DecryptFinal_ex(ctx.get(), out, &len));
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER, CIPHER_R_BAD_DECRYPT));

    // The context is not poisoned: a subsequent call returns
    // CIPHER_R_BAD_DECRYPT rather than ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED.
    EXPECT_FALSE(EVP_DecryptFinal_ex(ctx.get(), out, &len));
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER, CIPHER_R_BAD_DECRYPT));
  }
}

TEST(CipherTest, PoisoningErrors) {
  const uint8_t kKey[16] = {1, 2,  3,  4,  5,  6,  7,  8,
                            9, 10, 11, 12, 13, 14, 15, 16};
  const uint8_t kIV[16] = {0};
  uint8_t in[32] = {0};
  uint8_t out[64];
  size_t out_len;

  // A cipher whose `cipher_update` callback fails mid-operation.
  EVP_CIPHER failing_update_cipher = {};
  failing_update_cipher.block_size = 16;
  failing_update_cipher.key_len = 16;
  failing_update_cipher.iv_len = 16;
  failing_update_cipher.init = [](EVP_CIPHER_CTX *ctx, const uint8_t *key,
                                  const uint8_t *iv, int enc) { return 1; };
  failing_update_cipher.cipher_update = [](EVP_CIPHER_CTX *ctx,
                                           uint8_t *out_arg,
                                           const uint8_t *in_arg, size_t len) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
    return 0;
  };

  {
    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), &failing_update_cipher, nullptr,
                                   kKey, kIV));
    // EVP_EncryptUpdate_ex fails because the underlying cipher_update fails.
    EXPECT_FALSE(EVP_EncryptUpdate_ex(ctx.get(), out, &out_len, sizeof(out), in,
                                      sizeof(in)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            CIPHER_R_AES_KEY_SETUP_FAILED));

    // The context is poisoned: subsequent operations fail with
    // ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED.
    EXPECT_FALSE(EVP_EncryptUpdate_ex(ctx.get(), out, &out_len, sizeof(out), in,
                                      sizeof(in)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED));

    EXPECT_FALSE(EVP_EncryptFinal_ex2(ctx.get(), out, &out_len, sizeof(out)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED));

    // Re-initializing the context clears the poison flag.
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), &failing_update_cipher, nullptr,
                                   kKey, kIV));
    EXPECT_FALSE(EVP_EncryptUpdate_ex(ctx.get(), out, &out_len, sizeof(out), in,
                                      sizeof(in)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            CIPHER_R_AES_KEY_SETUP_FAILED));
  }

  // A custom cipher whose `cipher_final` callback fails.
  EVP_CIPHER failing_final_cipher = {};
  failing_final_cipher.block_size = 1;
  failing_final_cipher.key_len = 16;
  failing_final_cipher.iv_len = 16;
  failing_final_cipher.flags = EVP_CIPH_FLAG_CUSTOM_CIPHER;
  failing_final_cipher.init = [](EVP_CIPHER_CTX *ctx, const uint8_t *key,
                                 const uint8_t *iv, int enc) { return 1; };
  failing_final_cipher.cipher_update = [](EVP_CIPHER_CTX *ctx, uint8_t *out_arg,
                                          const uint8_t *in_arg,
                                          size_t len) { return 1; };
  failing_final_cipher.cipher_final = [](EVP_CIPHER_CTX *ctx) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
    return 0;
  };

  {
    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), &failing_final_cipher, nullptr,
                                   kKey, kIV));
    // EVP_EncryptFinal_ex2 fails because cipher_final fails.
    EXPECT_FALSE(EVP_EncryptFinal_ex2(ctx.get(), out, &out_len, sizeof(out)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            CIPHER_R_AES_KEY_SETUP_FAILED));

    // The context is poisoned: subsequent operations fail with
    // ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED.
    EXPECT_FALSE(EVP_EncryptFinal_ex2(ctx.get(), out, &out_len, sizeof(out)));
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER,
                            ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED));
  }
}

}  // namespace
BSSL_NAMESPACE_END
