// 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 <openssl/evp.h>

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

#include <map>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/dh.h>
#include <openssl/digest.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/mlkem.h>
#include <openssl/obj.h>
#include <openssl/rsa.h>
#include <openssl/xwing.h>

#include "../test/der_trailing_data.h"
#include "../test/file_test.h"
#include "../test/test_util.h"
#include "../test/wycheproof_util.h"

BSSL_NAMESPACE_BEGIN
namespace {
// evp_test dispatches between multiple test types. PublicKey and PrivateKey
// tests take a key name parameter and key information. If the test is
// successful, the key is saved under that key name. Decrypt, Sign, and Verify
// tests take a previously imported key name as parameter and test their
// respective operations.

const EVP_MD *GetDigest(std::string_view name) {
  if (name == "MD5") {
    return EVP_md5();
  } else if (name == "SHA1") {
    return EVP_sha1();
  } else if (name == "SHA224") {
    return EVP_sha224();
  } else if (name == "SHA256") {
    return EVP_sha256();
  } else if (name == "SHA384") {
    return EVP_sha384();
  } else if (name == "SHA512") {
    return EVP_sha512();
  }
  ADD_FAILURE() << "Unknown digest: " << name;
  return nullptr;
}

std::optional<int> GetRSAPadding(std::string_view name) {
  if (name == "PKCS1") {
    return RSA_PKCS1_PADDING;
  }
  if (name == "PSS") {
    return RSA_PKCS1_PSS_PADDING;
  }
  if (name == "OAEP") {
    return RSA_PKCS1_OAEP_PADDING;
  }
  if (name == "None") {
    return RSA_NO_PADDING;
  }
  ADD_FAILURE() << "Unknown RSA padding mode: " << name;
  return std::nullopt;
}

struct AlgorithmInfo {
  const EVP_PKEY_ALG *alg;
  const EVP_KEM *kem;
  int pkey_id;
  bool is_default;
};

const std::map<std::string, AlgorithmInfo> kAllAlgorithms = {
    {"RSA",
     {EVP_pkey_rsa(),
      /*kem=*/nullptr, EVP_PKEY_RSA, true}},

    {"RSA-PSS-SHA-256",
     {EVP_pkey_rsa_pss_sha256(), /*kem=*/nullptr, EVP_PKEY_RSA_PSS, false}},
    {"RSA-PSS-SHA-384",
     {EVP_pkey_rsa_pss_sha384(), /*kem=*/nullptr, EVP_PKEY_RSA_PSS, false}},
    {"RSA-PSS-SHA-512",
     {EVP_pkey_rsa_pss_sha512(), /*kem=*/nullptr, EVP_PKEY_RSA_PSS, false}},

    {"EC-P-224", {EVP_pkey_ec_p224(), /*kem=*/nullptr, EVP_PKEY_EC, true}},
    {"EC-P-256", {EVP_pkey_ec_p256(), /*kem=*/nullptr, EVP_PKEY_EC, true}},
    {"EC-P-384", {EVP_pkey_ec_p384(), /*kem=*/nullptr, EVP_PKEY_EC, true}},
    {"EC-P-521", {EVP_pkey_ec_p521(), /*kem=*/nullptr, EVP_PKEY_EC, true}},

    {"X25519", {EVP_pkey_x25519(), /*kem=*/nullptr, EVP_PKEY_X25519, true}},

    {"Ed25519", {EVP_pkey_ed25519(), /*kem=*/nullptr, EVP_PKEY_ED25519, true}},

    {"DSA", {EVP_pkey_dsa(), /*kem=*/nullptr, EVP_PKEY_DSA, true}},

    {"ML-DSA-44",
     {EVP_pkey_ml_dsa_44(), /*kem=*/nullptr, EVP_PKEY_ML_DSA_44, true}},
    {"ML-DSA-65",
     {EVP_pkey_ml_dsa_65(), /*kem=*/nullptr, EVP_PKEY_ML_DSA_65, true}},
    {"ML-DSA-87",
     {EVP_pkey_ml_dsa_87(), /*kem=*/nullptr, EVP_PKEY_ML_DSA_87, true}},

    {"ML-KEM-768",
     {EVP_pkey_ml_kem_768(), EVP_kem_ml_kem_768(), EVP_PKEY_ML_KEM_768, true}},
    {"ML-KEM-1024",
     {EVP_pkey_ml_kem_1024(), EVP_kem_ml_kem_1024(), EVP_PKEY_ML_KEM_1024,
      true}},

    {"X-Wing", {EVP_pkey_xwing(), EVP_kem_xwing(), EVP_PKEY_XWING, false}},
};

using KeyMap = std::map<std::string, bssl::UniquePtr<EVP_PKEY>>;

enum class KeyRole { kPublic, kPrivate };

void CheckRSAParam(FileTest *t, std::string_view attr_name,
                   const EVP_PKEY *pkey,
                   const BIGNUM *(*rsa_getter)(const RSA *)) {
  SCOPED_TRACE(attr_name);
  if (t->HasAttribute(attr_name)) {
    bssl::UniquePtr<BIGNUM> want =
        HexToBIGNUM(t->GetAttributeOrDie(attr_name).c_str());
    ASSERT_TRUE(want);

    const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
    ASSERT_TRUE(rsa);
    const BIGNUM *got = rsa_getter(rsa);
    ASSERT_TRUE(got);
    EXPECT_EQ(BN_cmp(want.get(), got), 0)
        << "wanted: " << BIGNUMToHex(want.get())
        << "\ngot: " << BIGNUMToHex(got);
  }
  // We have many test RSA keys so, for now, don't require that all RSA keys
  // list out these parameters. That is, the absence of an RSA parameter does
  // not currently assert that we omit them.
}

bool CheckRawKey(FileTest *t, std::string_view attr_name, const EVP_PKEY *pkey,
                 int (*getter)(const EVP_PKEY *pkey, uint8_t *out,
                               size_t *out_len)) {
  if (!t->HasAttribute(attr_name)) {
    size_t len;
    EXPECT_FALSE(getter(pkey, nullptr, &len));
    return true;
  }

  std::vector<uint8_t> expected;
  if (!t->GetBytes(&expected, attr_name)) {
    return false;
  }

  std::vector<uint8_t> raw;
  size_t len;
  if (!getter(pkey, nullptr, &len)) {
    return false;
  }
  const size_t expected_len = len;
  raw.resize(len);
  if (!getter(pkey, raw.data(), &len)) {
    return false;
  }
  EXPECT_EQ(len, expected_len);
  raw.resize(len);
  EXPECT_EQ(Bytes(raw), Bytes(expected));

  // Short buffers should be rejected.
  raw.resize(expected_len - 1);
  len = raw.size();
  EXPECT_FALSE(getter(pkey, raw.data(), &len));

  // Long buffer should be accepted and the proper length written out.
  raw.resize(expected_len + 1);
  len = raw.size();
  EXPECT_TRUE(getter(pkey, raw.data(), &len));
  EXPECT_EQ(len, expected_len);
  raw.resize(len);
  EXPECT_EQ(Bytes(raw), Bytes(expected));
  return true;
}

bool ImportRawKey(FileTest *t, KeyMap *key_map, KeyRole key_role,
                  bool use_seed) {
  auto parse_func = key_role == KeyRole::kPublic
                        ? &EVP_PKEY_from_raw_public_key
                        : (use_seed ? &EVP_PKEY_from_private_seed
                                    : &EVP_PKEY_from_raw_private_key);
  auto getter = key_role == KeyRole::kPublic
                    ? &EVP_PKEY_get_raw_public_key
                    : (use_seed ? &EVP_PKEY_get_private_seed
                                : &EVP_PKEY_get_raw_private_key);
  std::string alg_name;
  if (!t->GetAttribute(&alg_name, "Algorithm")) {
    return false;
  }
  const auto it = kAllAlgorithms.find(alg_name);
  if (it == kAllAlgorithms.end()) {
    ADD_FAILURE() << "Unknown algorithm: " << alg_name;
    return false;
  }
  const AlgorithmInfo &alg_info = it->second;

  std::vector<uint8_t> input;
  if (!t->GetBytes(&input, "Input")) {
    return false;
  }
  UniquePtr<EVP_PKEY> pkey(
      parse_func(alg_info.alg, input.data(), input.size()));
  if (pkey == nullptr) {
    return false;
  }
  if (!CheckRawKey(t, "Input", pkey.get(), getter)) {
    return false;
  }
  // Ensure the other raw getters are consistent with the input.
  if ((t->HasAttribute("RawPrivate") &&
       !CheckRawKey(t, "RawPrivate", pkey.get(),
                    EVP_PKEY_get_raw_private_key)) ||
      (t->HasAttribute("RawPublic") &&
       !CheckRawKey(t, "RawPublic", pkey.get(), EVP_PKEY_get_raw_public_key)) ||
      (t->HasAttribute("PrivateSeed") &&
       !CheckRawKey(t, "PrivateSeed", pkey.get(), EVP_PKEY_get_private_seed))) {
    return false;
  }

  // Save the key for future tests.
  const std::string &key_name = t->GetParameter();
  EXPECT_EQ(0u, key_map->count(key_name)) << "Duplicate key: " << key_name;
  (*key_map)[key_name] = std::move(pkey);
  return true;
}

bool ImportKey(FileTest *t, KeyMap *key_map, KeyRole key_role) {
  std::string format_name = key_role == KeyRole::kPublic ? "spki" : "pkcs8";
  auto parse_func = key_role == KeyRole::kPublic
                        ? &EVP_PKEY_from_subject_public_key_info
                        : &EVP_PKEY_from_private_key_info;
  auto parse_default_func = key_role == KeyRole::kPublic
                                ? &EVP_parse_public_key
                                : &EVP_parse_private_key;
  auto marshal_func = key_role == KeyRole::kPublic ? &EVP_marshal_public_key
                                                   : &EVP_marshal_private_key;

  // This test will first import the key from all available methods, then check
  // that all properties on all keys match.
  std::vector<std::pair<std::string, bssl::UniquePtr<EVP_PKEY>>> keys;

  // Parse from SPKI or PKCS#8.
  std::vector<uint8_t> input;
  if (!t->GetBytes(&input, "Input")) {
    return false;
  }

  // First, parse the key with all algorithms active. Check this before
  // specifying an individual algorithm, so that error cases do not need to
  // specify an Algorithm key.
  std::vector<const EVP_PKEY_ALG *> algs;
  for (const auto &[name, info] : kAllAlgorithms) {
    algs.push_back(info.alg);
  }
  bssl::UniquePtr<EVP_PKEY> new_key(
      parse_func(input.data(), input.size(), algs.data(), algs.size()));
  if (new_key == nullptr) {
    return false;
  }
  keys.emplace_back(format_name + " - all algs", std::move(new_key));

  // Test that the parsers reject trailing data.
  bool ok = TestDERTrailingData(
      input, [&](bssl::Span<const uint8_t> rewritten, size_t n) {
        // We currently intentionally ignore trailing data in the outermost
        // PKCS#8 PrivateKeyInfo element because we don't parse the attributes.
        if (n == 0 && key_role == KeyRole::kPrivate) {
          return;
        }
        SCOPED_TRACE(n);
        bssl::UniquePtr<EVP_PKEY> parsed(parse_func(
            rewritten.data(), rewritten.size(), algs.data(), algs.size()));
        EXPECT_FALSE(parsed);
      });
  EXPECT_TRUE(ok);

  // Parse with just the specific algorithm.
  std::string alg_name;
  if (!t->GetAttribute(&alg_name, "Algorithm")) {
    return false;
  }
  auto it = kAllAlgorithms.find(alg_name);
  if (it == kAllAlgorithms.end()) {
    ADD_FAILURE() << "Unknown algorithm: " << alg_name;
    return false;
  }
  const AlgorithmInfo &alg_info = it->second;
  new_key.reset(parse_func(input.data(), input.size(), &alg_info.alg, 1));
  if (new_key == nullptr) {
    return false;
  }
  keys.emplace_back(format_name + " - " + alg_name + " only",
                    std::move(new_key));

  // Parsing with all other algorithms should fail. This currently assumes each
  // key can only be parsed by one algorithm. Make the field a list of
  // algorithms if this ever changes.
  algs.clear();
  for (const auto &[name, info] : kAllAlgorithms) {
    if (name != alg_name) {
      algs.push_back(info.alg);
    }
  }
  new_key.reset(
      parse_func(input.data(), input.size(), algs.data(), algs.size()));
  EXPECT_FALSE(new_key);
  ERR_clear_error();

  // Parse with the default parser.
  CBS cbs(input);
  new_key.reset(parse_default_func(&cbs));
  if (alg_info.is_default) {
    if (new_key == nullptr) {
      return false;
    }
    keys.emplace_back(format_name + " - default algorithms",
                      std::move(new_key));
  } else {
    EXPECT_FALSE(new_key);
    ERR_clear_error();
  }

  // Import as a raw key.
  if (key_role == KeyRole::kPublic && t->HasAttribute("RawPublic")) {
    std::vector<uint8_t> raw;
    if (!t->GetBytes(&raw, "RawPublic")) {
      return false;
    }
    new_key.reset(
        EVP_PKEY_from_raw_public_key(alg_info.alg, raw.data(), raw.size()));
    if (new_key == nullptr) {
      return false;
    }
    keys.emplace_back("raw public", std::move(new_key));
  }
  if (key_role == KeyRole::kPrivate && t->HasAttribute("RawPrivate")) {
    std::vector<uint8_t> raw;
    if (!t->GetBytes(&raw, "RawPrivate")) {
      return false;
    }
    new_key.reset(
        EVP_PKEY_from_raw_private_key(alg_info.alg, raw.data(), raw.size()));
    if (new_key == nullptr) {
      return false;
    }
    keys.emplace_back("raw private", std::move(new_key));
  }
  if (key_role == KeyRole::kPrivate && t->HasAttribute("PrivateSeed")) {
    std::vector<uint8_t> raw;
    if (!t->GetBytes(&raw, "PrivateSeed")) {
      return false;
    }
    new_key.reset(
        EVP_PKEY_from_private_seed(alg_info.alg, raw.data(), raw.size()));
    if (new_key == nullptr) {
      return false;
    }
    keys.emplace_back("private seed", std::move(new_key));
  }

  // Import RSA key from parameters.
  if (alg_info.pkey_id == EVP_PKEY_RSA) {
    if (key_role == KeyRole::kPublic && t->HasAttribute("RSAParamN") &&
        t->HasAttribute("RSAParamE")) {
      bssl::UniquePtr<BIGNUM> n =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamN").c_str());
      bssl::UniquePtr<BIGNUM> e =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamE").c_str());
      if (n == nullptr || e == nullptr) {
        return false;
      }
      bssl::UniquePtr<RSA> rsa(RSA_new_public_key(n.get(), e.get()));
      new_key.reset(EVP_PKEY_new());
      if (rsa == nullptr || new_key == nullptr ||
          !EVP_PKEY_set1_RSA(new_key.get(), rsa.get())) {
        return false;
      }
      keys.emplace_back("RSA public params", std::move(new_key));
    }
    if (key_role == KeyRole::kPrivate && t->HasAttribute("RSAParamN") &&
        t->HasAttribute("RSAParamE") && t->HasAttribute("RSAParamD") &&
        t->HasAttribute("RSAParamP") && t->HasAttribute("RSAParamQ") &&
        t->HasAttribute("RSAParamDMP1") && t->HasAttribute("RSAParamDMQ1") &&
        t->HasAttribute("RSAParamIQMP")) {
      bssl::UniquePtr<BIGNUM> n =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamN").c_str());
      bssl::UniquePtr<BIGNUM> e =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamE").c_str());
      bssl::UniquePtr<BIGNUM> d =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamD").c_str());
      bssl::UniquePtr<BIGNUM> p =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamP").c_str());
      bssl::UniquePtr<BIGNUM> q =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamQ").c_str());
      bssl::UniquePtr<BIGNUM> dmp1 =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamDMP1").c_str());
      bssl::UniquePtr<BIGNUM> dmq1 =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamDMQ1").c_str());
      bssl::UniquePtr<BIGNUM> iqmp =
          HexToBIGNUM(t->GetAttributeOrDie("RSAParamIQMP").c_str());
      if (n == nullptr || e == nullptr) {
        return false;
      }
      bssl::UniquePtr<RSA> rsa(RSA_new_private_key(n.get(), e.get(), d.get(),
                                                   p.get(), q.get(), dmp1.get(),
                                                   dmq1.get(), iqmp.get()));
      new_key.reset(EVP_PKEY_new());
      if (rsa == nullptr || new_key == nullptr ||
          !EVP_PKEY_set1_RSA(new_key.get(), rsa.get())) {
        return false;
      }
      keys.emplace_back("RSA private params", std::move(new_key));
    }
  }

  // Check properties of the keys.
  for (const auto &[name, pkey] : keys) {
    SCOPED_TRACE(name);

    EXPECT_EQ(alg_info.pkey_id, EVP_PKEY_id(pkey.get()));

    // In almost all cases, a non-empty key must have a public key. The only
    // exception is a private RSA key with (n, d) params only, which is tested
    // not here but elsewhere.
    EXPECT_EQ(EVP_PKEY_has_public(pkey.get()), 1);
    EXPECT_EQ(EVP_PKEY_has_private(pkey.get()), key_role == KeyRole::kPrivate);

    if (t->HasAttribute("Bits")) {
      EXPECT_EQ(EVP_PKEY_bits(pkey.get()),
                atoi(t->GetAttributeOrDie("Bits").c_str()));
    }

    if (t->HasAttribute("ECCurve")) {
      EXPECT_EQ(OBJ_nid2sn(EVP_PKEY_get_ec_curve_nid(pkey.get())),
                t->GetAttributeOrDie("ECCurve"));
    } else {
      EXPECT_EQ(EVP_PKEY_get_ec_curve_nid(pkey.get()), NID_undef);
    }

    CheckRSAParam(t, "RSAParamN", pkey.get(), RSA_get0_n);
    CheckRSAParam(t, "RSAParamE", pkey.get(), RSA_get0_e);
    CheckRSAParam(t, "RSAParamD", pkey.get(), RSA_get0_d);
    CheckRSAParam(t, "RSAParamP", pkey.get(), RSA_get0_p);
    CheckRSAParam(t, "RSAParamQ", pkey.get(), RSA_get0_q);
    CheckRSAParam(t, "RSAParamDMP1", pkey.get(), RSA_get0_dmp1);
    CheckRSAParam(t, "RSAParamDMQ1", pkey.get(), RSA_get0_dmq1);
    CheckRSAParam(t, "RSAParamIQMP", pkey.get(), RSA_get0_iqmp);

    // All keys must compare equal.
    EXPECT_EQ(EVP_PKEY_eq(pkey.get(), keys.front().second.get()), 1);

    // The key must re-encode correctly.
    bssl::ScopedCBB cbb;
    if (!CBB_init(cbb.get(), 0) || !marshal_func(cbb.get(), pkey.get())) {
      return false;
    }
    std::vector<uint8_t> output = input;
    if (t->HasAttribute("Output") && !t->GetBytes(&output, "Output")) {
      return false;
    }
    EXPECT_EQ(Bytes(output), Bytes(CBB_data(cbb.get()), CBB_len(cbb.get())))
        << "Re-encoding the key did not match.";

    if (!CheckRawKey(t, "RawPrivate", pkey.get(),
                     EVP_PKEY_get_raw_private_key) ||
        !CheckRawKey(t, "RawPublic", pkey.get(), EVP_PKEY_get_raw_public_key) ||
        !CheckRawKey(t, "PrivateSeed", pkey.get(), EVP_PKEY_get_private_seed)) {
      return false;
    }

    // Test copying the public part of the key.
    UniquePtr<EVP_PKEY> public_copy(EVP_PKEY_copy_public(pkey.get()));
    EXPECT_TRUE(public_copy);
    EXPECT_TRUE(EVP_PKEY_has_public(public_copy.get()));
    EXPECT_FALSE(EVP_PKEY_has_private(public_copy.get()));
    EXPECT_EQ(EVP_PKEY_eq(public_copy.get(), pkey.get()), 1);
    EXPECT_EQ(EVP_PKEY_parameters_eq(public_copy.get(), pkey.get()), 1);
    // Check that the copied public key serializes the same.
    bssl::ScopedCBB cbb_public, cbb_public_copy;
    if (!CBB_init(cbb_public.get(), 0) ||
        !EVP_marshal_public_key(cbb_public.get(), pkey.get()) ||
        !CBB_init(cbb_public_copy.get(), 0) ||
        !EVP_marshal_public_key(cbb_public_copy.get(), public_copy.get())) {
      return false;
    }
    EXPECT_EQ(
        Bytes(CBB_data(cbb_public.get()), CBB_len(cbb_public.get())),
        Bytes(CBB_data(cbb_public_copy.get()), CBB_len(cbb_public_copy.get())))
        << "Public copy of the key did not match.";
  }

  // Save the key for future tests.
  const std::string &key_name = t->GetParameter();
  EXPECT_EQ(0u, key_map->count(key_name)) << "Duplicate key: " << key_name;
  (*key_map)[key_name] = std::move(keys.front().second);
  return true;
}

bool GetOptionalBignum(FileTest *t, bssl::UniquePtr<BIGNUM> *out,
                       const std::string &key) {
  if (!t->HasAttribute(key)) {
    *out = nullptr;
    return true;
  }

  std::vector<uint8_t> bytes;
  if (!t->GetBytes(&bytes, key)) {
    return false;
  }

  out->reset(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
  return *out != nullptr;
}

bool ImportDHKey(FileTest *t, KeyMap *key_map) {
  bssl::UniquePtr<BIGNUM> p, q, g, pub_key, priv_key;
  if (!GetOptionalBignum(t, &p, "P") ||  //
      !GetOptionalBignum(t, &q, "Q") ||  //
      !GetOptionalBignum(t, &g, "G") ||
      !GetOptionalBignum(t, &pub_key, "Public") ||
      !GetOptionalBignum(t, &priv_key, "Private")) {
    return false;
  }

  bssl::UniquePtr<DH> dh(DH_new());
  if (dh == nullptr || !DH_set0_pqg(dh.get(), p.get(), q.get(), g.get())) {
    return false;
  }
  // `DH_set0_pqg` takes ownership on success.
  p.release();
  q.release();
  g.release();

  if (!DH_set0_key(dh.get(), pub_key.get(), priv_key.get())) {
    return false;
  }
  // `DH_set0_key` takes ownership on success.
  pub_key.release();
  priv_key.release();

  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  if (pkey == nullptr || !EVP_PKEY_set1_DH(pkey.get(), dh.get())) {
    return false;
  }

  // Save the key for future tests.
  const std::string &key_name = t->GetParameter();
  EXPECT_EQ(0u, key_map->count(key_name)) << "Duplicate key: " << key_name;
  (*key_map)[key_name] = std::move(pkey);
  return true;
}

// SetupContext configures `ctx` based on attributes in `t`, with the exception
// of the signing digest which must be configured externally.
bool SetupContext(FileTest *t, const KeyMap *key_map, EVP_PKEY_CTX *ctx) {
  if (t->HasAttribute("RSAPadding")) {
    auto padding = GetRSAPadding(t->GetAttributeOrDie("RSAPadding"));
    if (!padding || !EVP_PKEY_CTX_set_rsa_padding(ctx, *padding)) {
      return false;
    }
  }
  if (t->HasAttribute("PSSSaltLength") &&
      !EVP_PKEY_CTX_set_rsa_pss_saltlen(
          ctx, atoi(t->GetAttributeOrDie("PSSSaltLength").c_str()))) {
    return false;
  }
  if (t->HasAttribute("MGF1Digest")) {
    const EVP_MD *digest = GetDigest(t->GetAttributeOrDie("MGF1Digest"));
    if (digest == nullptr || !EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, digest)) {
      return false;
    }
  }
  if (t->HasAttribute("OAEPDigest")) {
    const EVP_MD *digest = GetDigest(t->GetAttributeOrDie("OAEPDigest"));
    if (digest == nullptr || !EVP_PKEY_CTX_set_rsa_oaep_md(ctx, digest)) {
      return false;
    }
  }
  if (t->HasAttribute("OAEPLabel")) {
    std::vector<uint8_t> label;
    if (!t->GetBytes(&label, "OAEPLabel")) {
      return false;
    }
    // For historical reasons, `EVP_PKEY_CTX_set0_rsa_oaep_label` expects to be
    // take ownership of the input.
    bssl::UniquePtr<uint8_t> buf(reinterpret_cast<uint8_t *>(
        OPENSSL_memdup(label.data(), label.size())));
    if (!buf ||
        !EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, buf.get(), label.size())) {
      return false;
    }
    buf.release();
  }
  if (t->HasAttribute("DerivePeer")) {
    std::string derive_peer = t->GetAttributeOrDie("DerivePeer");
    auto it = key_map->find(derive_peer);
    if (it == key_map->end()) {
      ADD_FAILURE() << "Could not find key " << derive_peer;
      return false;
    }
    EVP_PKEY *derive_peer_key = it->second.get();
    if (!EVP_PKEY_derive_set_peer(ctx, derive_peer_key)) {
      return false;
    }
  }
  if (t->HasAttribute("DiffieHellmanPad") && !EVP_PKEY_CTX_set_dh_pad(ctx, 1)) {
    return false;
  }
  if (t->HasAttribute("Context")) {
    std::vector<uint8_t> context;
    if (!t->GetBytes(&context, "Context") ||
        !EVP_PKEY_CTX_set1_signature_context_string(ctx, context.data(),
                                                    context.size())) {
      return false;
    }
  }
  return true;
}

bool MaybeReplaceWithCopy(bssl::UniquePtr<EVP_PKEY_CTX> *ctx, bool copy_ctx) {
  if (!copy_ctx) {
    return true;
  }
  bssl::UniquePtr<EVP_PKEY_CTX> copy(EVP_PKEY_CTX_dup(ctx->get()));
  if (!copy) {
    return false;
  }
  *ctx = std::move(copy);
  return true;
}

bool MaybeReplaceWithCopy(bssl::UniquePtr<EVP_MD_CTX> *ctx, EVP_PKEY_CTX **pctx,
                          bool copy_ctx) {
  if (!copy_ctx) {
    return true;
  }
  bssl::UniquePtr<EVP_MD_CTX> copy(EVP_MD_CTX_new());
  if (ctx == nullptr || !EVP_MD_CTX_copy_ex(copy.get(), ctx->get())) {
    return false;
  }
  *ctx = std::move(copy);
  *pctx = EVP_MD_CTX_pkey_ctx(ctx->get());
  return true;
}

bool TestDerive(FileTest *t, const KeyMap *key_map, EVP_PKEY *key,
                bool copy_ctx) {
  bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
  if (!ctx ||  //
      !EVP_PKEY_derive_init(ctx.get()) ||
      !MaybeReplaceWithCopy(&ctx, copy_ctx) ||
      !SetupContext(t, key_map, ctx.get()) ||
      !MaybeReplaceWithCopy(&ctx, copy_ctx)) {
    return false;
  }

  size_t len;
  std::vector<uint8_t> actual, output;
  if (!EVP_PKEY_derive(ctx.get(), nullptr, &len)) {
    return false;
  }
  actual.resize(len);
  if (!EVP_PKEY_derive(ctx.get(), actual.data(), &len)) {
    return false;
  }
  actual.resize(len);

  // Defer looking up the attribute so Error works properly.
  if (!t->GetBytes(&output, "Output")) {
    return false;
  }
  EXPECT_EQ(Bytes(output), Bytes(actual));

  // Test when the buffer is too large.
  actual.resize(len + 1);
  len = actual.size();
  if (!EVP_PKEY_derive(ctx.get(), actual.data(), &len)) {
    return false;
  }
  actual.resize(len);
  EXPECT_EQ(Bytes(output), Bytes(actual));

  // Test when the buffer is too small.
  actual.resize(len - 1);
  len = actual.size();
  if (t->HasAttribute("SmallBufferTruncates")) {
    if (!EVP_PKEY_derive(ctx.get(), actual.data(), &len)) {
      return false;
    }
    actual.resize(len);
    EXPECT_EQ(Bytes(output.data(), len), Bytes(actual));
  } else {
    EXPECT_FALSE(EVP_PKEY_derive(ctx.get(), actual.data(), &len));
    ERR_clear_error();
  }
  return true;
}

// Tests encapsulation and/or decapsulation. If performing both, this checks
// that the output of encapsulation is successfully decapsulated to the same
// shared secret value. If only performing decapsulation, this reads ciphertext
// input from the test vectors file and checks the decapsulation result against
// known output. If only performing encapsulation, this only checks that the
// operation succeeds.
bool TestKem(FileTest *t, EVP_PKEY *pkey, bool copy_ctx, bool encapsulate,
             bool decapsulate) {
  std::string alg_name;
  if (!t->GetAttribute(&alg_name, "Algorithm")) {
    ADD_FAILURE() << "Algorithm not specified.";
    return false;
  }
  auto it = kAllAlgorithms.find(alg_name);
  if (it == kAllAlgorithms.end()) {
    ADD_FAILURE() << "Unknown algorithm: " << alg_name;
    return false;
  }
  const AlgorithmInfo &alg_info = it->second;
  if (alg_info.alg == nullptr || alg_info.kem == nullptr) {
    ADD_FAILURE() << "Method not defined: " << alg_name;
    return false;
  }

  size_t expected_ciphertext_len;
  size_t expected_secret_len;
  if (alg_info.kem == EVP_kem_ml_kem_768()) {
    expected_ciphertext_len = MLKEM768_CIPHERTEXT_BYTES;
    expected_secret_len = MLKEM_SHARED_SECRET_BYTES;
  } else if (alg_info.kem == EVP_kem_ml_kem_1024()) {
    expected_ciphertext_len = MLKEM1024_CIPHERTEXT_BYTES;
    expected_secret_len = MLKEM_SHARED_SECRET_BYTES;
  } else if (alg_info.kem == EVP_kem_xwing()) {
    expected_ciphertext_len = XWING_CIPHERTEXT_BYTES;
    expected_secret_len = XWING_SHARED_SECRET_BYTES;
  } else {
    ADD_FAILURE() << "KEM not found: " << alg_name;
    return false;
  }

  bssl::UniquePtr<EVP_PKEY_CTX> ctx;
  std::vector<uint8_t> ciphertext, secret, decapsulated_secret;
  size_t ciphertext_size, secret_size;

  const auto resize_output_buffers =
      [&](std::optional<size_t> new_ciphertext_len,
          std::optional<size_t> new_secret_len,
          bool resize_decap_buffer_only = false) {
        if (new_ciphertext_len) {
          ciphertext_size = *new_ciphertext_len;
          ciphertext.resize(ciphertext_size);
        }
        if (new_secret_len) {
          secret_size = *new_secret_len;
          if (!resize_decap_buffer_only) {
            secret.resize(secret_size);
          }
          decapsulated_secret.resize(secret_size);
        }
      };

  const auto reset_test_state = [&]() {
    ctx.reset(EVP_PKEY_CTX_new(pkey, nullptr));
    resize_output_buffers(0, 0);

    // Read values from the test vector file.
    if (decapsulate && !encapsulate) {
      if (!t->GetBytes(&ciphertext, "Input")) {
        ADD_FAILURE() << "Input not found.";
      }
      if (!t->HasAttribute("DecapsulateFail") &&
          !t->GetBytes(&secret, "Output")) {
        ADD_FAILURE() << "Output not found.";
      }
    }
  };

  reset_test_state();

  // Perform encapsulation.
  if (encapsulate) {
    if (!ctx ||  //
        !EVP_PKEY_encapsulate_init(ctx.get(), nullptr) ||
        !MaybeReplaceWithCopy(&ctx, copy_ctx)) {
      return false;
    }

    // Test the mode that writes the output size.
    EXPECT_EQ(EVP_PKEY_encapsulate(ctx.get(), nullptr, &ciphertext_size,
                                   nullptr, &secret_size),
              1);
    EXPECT_EQ(ciphertext_size, expected_ciphertext_len);
    EXPECT_EQ(secret_size, expected_secret_len);

    // If insufficient space is supplied, the function will fail.
    resize_output_buffers(ciphertext_size - 1, secret_size - 1);
    EXPECT_EQ(
        EVP_PKEY_encapsulate(ctx.get(), ciphertext.data(), &ciphertext_size,
                             secret.data(), &secret_size),
        0);
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL));
    ERR_clear_error();

    // Test the mode that actually performs the operation.
    resize_output_buffers(expected_ciphertext_len + 1, expected_secret_len + 1);
    EXPECT_EQ(
        EVP_PKEY_encapsulate(ctx.get(), ciphertext.data(), &ciphertext_size,
                             secret.data(), &secret_size),
        1);
    // The correct output sizes are written out.
    EXPECT_EQ(ciphertext_size, expected_ciphertext_len);
    EXPECT_EQ(secret_size, expected_secret_len);
    resize_output_buffers(ciphertext_size, secret_size);
  }

  const auto check_decapsulate_result = [&](int result) {
    if (t->HasAttribute("DecapsulateFail")) {
      EXPECT_EQ(result, 0);
      return;
    }
    EXPECT_EQ(result, 1);
    // The correct output size was writen out.
    EXPECT_EQ(secret_size, expected_secret_len);
    decapsulated_secret.resize(secret_size);
    EXPECT_EQ(secret, decapsulated_secret);
  };

  // Perform decapsulation.
  if (decapsulate) {
    ctx.reset(EVP_PKEY_CTX_new(pkey, nullptr));
    if (!ctx ||  //
        !EVP_PKEY_decapsulate_init(ctx.get(), nullptr) ||
        !MaybeReplaceWithCopy(&ctx, copy_ctx)) {
      return false;
    }

    // Test the mode that writes the output size.
    secret_size = 0;
    EXPECT_EQ(EVP_PKEY_decapsulate(ctx.get(), nullptr, &secret_size,
                                   ciphertext.data(), ciphertext.size()),
              1);
    EXPECT_EQ(secret_size, expected_secret_len);

    // If insufficient space is supplied, the function will fail.
    resize_output_buffers(std::nullopt, secret_size - 1, true);
    EXPECT_EQ(EVP_PKEY_decapsulate(ctx.get(), decapsulated_secret.data(),
                                   &secret_size, ciphertext.data(),
                                   ciphertext.size()),
              0);
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL));
    ERR_clear_error();

    // Test the mode that actually performs the operation.
    resize_output_buffers(std::nullopt, secret_size + 1, true);
    check_decapsulate_result(EVP_PKEY_decapsulate(
        ctx.get(), decapsulated_secret.data(), &secret_size, ciphertext.data(),
        ciphertext.size()));
  }

  // Repeat everything the EVP_KEM way, which is simpler.
  reset_test_state();

  EXPECT_EQ(EVP_KEM_ciphertext_len(alg_info.kem), expected_ciphertext_len);
  EXPECT_EQ(EVP_KEM_secret_len(alg_info.kem), expected_secret_len);

  if (encapsulate) {
    ciphertext.resize(ciphertext_size);

    // Passing the wrong sizes fails (even if larger than required).
    resize_output_buffers(expected_ciphertext_len - 1, expected_secret_len);
    EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(),
                            secret.data(), secret.size(), pkey),
              0);
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_EVP,
                            EVP_R_INVALID_CIPHERTEXT_LENGTH));
    ERR_clear_error();
    resize_output_buffers(expected_ciphertext_len + 1, expected_secret_len);
    EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(),
                            secret.data(), secret.size(), pkey),
              0);
    EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_EVP,
                            EVP_R_INVALID_CIPHERTEXT_LENGTH));
    ERR_clear_error();
    resize_output_buffers(expected_ciphertext_len, expected_secret_len - 1);
    EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(),
                            secret.data(), secret.size(), pkey),
              0);
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH));
    ERR_clear_error();
    resize_output_buffers(expected_ciphertext_len, expected_secret_len + 1);
    EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(),
                            secret.data(), secret.size(), pkey),
              0);
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH));
    ERR_clear_error();

    // Only the correct sizes are accepted.
    resize_output_buffers(expected_ciphertext_len, expected_secret_len);
    EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(),
                            secret.data(), secret.size(), pkey),
              1);
  }

  if (decapsulate) {
    // Passing the wrong sizes fails (even if larger than required).
    resize_output_buffers(std::nullopt, expected_secret_len - 1, true);
    EXPECT_EQ(EVP_KEM_decap(alg_info.kem, decapsulated_secret.data(),
                            decapsulated_secret.size(), ciphertext.data(),
                            ciphertext.size(), pkey),
              0);
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH));
    ERR_clear_error();
    resize_output_buffers(std::nullopt, expected_secret_len + 1, true);
    EXPECT_EQ(EVP_KEM_decap(alg_info.kem, decapsulated_secret.data(),
                            decapsulated_secret.size(), ciphertext.data(),
                            ciphertext.size(), pkey),
              0);
    EXPECT_TRUE(
        ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH));
    ERR_clear_error();

    resize_output_buffers(std::nullopt, expected_secret_len, true);
    check_decapsulate_result(EVP_KEM_decap(
        alg_info.kem, decapsulated_secret.data(), decapsulated_secret.size(),
        ciphertext.data(), ciphertext.size(), pkey));
  }

  return true;
}

bool TestEVPOperation(FileTest *t, const KeyMap *key_map, bool copy_ctx) {
  SCOPED_TRACE(copy_ctx);
  // Load the key.
  const std::string &key_name = t->GetParameter();
  auto it = key_map->find(key_name);
  if (it == key_map->end()) {
    ADD_FAILURE() << "Could not find key " << key_name;
    return false;
  }
  EVP_PKEY *key = it->second.get();

  int (*key_op_init)(EVP_PKEY_CTX *ctx) = nullptr;
  int (*key_op)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
                const uint8_t *in, size_t in_len) = nullptr;
  int (*md_op_init)(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
                    ENGINE *e, EVP_PKEY *pkey) = nullptr;
  bool is_verify = false;
  if (t->GetType() == "Decrypt") {
    key_op_init = EVP_PKEY_decrypt_init;
    key_op = EVP_PKEY_decrypt;
  } else if (t->GetType() == "Sign") {
    key_op_init = EVP_PKEY_sign_init;
    key_op = EVP_PKEY_sign;
  } else if (t->GetType() == "Verify") {
    key_op_init = EVP_PKEY_verify_init;
    is_verify = true;
  } else if (t->GetType() == "SignMessage") {
    md_op_init = EVP_DigestSignInit;
  } else if (t->GetType() == "VerifyMessage") {
    md_op_init = EVP_DigestVerifyInit;
    is_verify = true;
  } else if (t->GetType() == "Encrypt") {
    key_op_init = EVP_PKEY_encrypt_init;
    key_op = EVP_PKEY_encrypt;
  } else if (t->GetType() == "Derive") {
    return TestDerive(t, key_map, key, copy_ctx);
  } else if (t->GetType() == "Encapsulate") {
    return TestKem(t, key, copy_ctx, true, false);
  } else if (t->GetType() == "EncapsulateDecapsulate") {
    return TestKem(t, key, copy_ctx, true, true);
  } else if (t->GetType() == "Decapsulate") {
    return TestKem(t, key, copy_ctx, false, true);
  } else {
    ADD_FAILURE() << "Unknown test " << t->GetType();
    return false;
  }

  const EVP_MD *digest = nullptr;
  if (t->HasAttribute("Digest")) {
    digest = GetDigest(t->GetAttributeOrDie("Digest"));
    if (digest == nullptr) {
      return false;
    }
  }

  // For verify tests, the "output" is the signature. Read it now so that, for
  // tests which expect a failure in SetupContext, the attribute is still
  // consumed.
  std::vector<uint8_t> input, actual, output;
  if (!t->GetBytes(&input, "Input") ||
      (is_verify && !t->GetBytes(&output, "Output"))) {
    return false;
  }

  if (md_op_init) {
    bssl::UniquePtr<EVP_MD_CTX> ctx(EVP_MD_CTX_new());
    EVP_PKEY_CTX *pctx;
    if (ctx == nullptr ||  //
        !md_op_init(ctx.get(), &pctx, digest, nullptr, key) ||
        !MaybeReplaceWithCopy(&ctx, &pctx, copy_ctx) ||
        !SetupContext(t, key_map, pctx) ||
        !MaybeReplaceWithCopy(&ctx, &pctx, copy_ctx)) {
      return false;
    }

    if (is_verify) {
      return EVP_DigestVerify(ctx.get(), output.data(), output.size(),
                              input.data(), input.size());
    }

    size_t len;
    if (!EVP_DigestSign(ctx.get(), nullptr, &len, input.data(), input.size())) {
      return false;
    }
    actual.resize(len);
    if (!EVP_DigestSign(ctx.get(), actual.data(), &len, input.data(),
                        input.size())) {
      return false;
    }
    actual.resize(len);

    if (t->HasAttribute("CheckVerify")) {
      // Some signature schemes are non-deterministic, so we check by verifying.
      bssl::UniquePtr<EVP_MD_CTX> verify_ctx(EVP_MD_CTX_new());
      EVP_PKEY_CTX *verify_pctx;
      if (verify_ctx == nullptr ||
          !EVP_DigestVerifyInit(verify_ctx.get(), &verify_pctx, digest, nullptr,
                                key) ||
          !MaybeReplaceWithCopy(&verify_ctx, &verify_pctx, copy_ctx) ||
          !SetupContext(t, key_map, verify_pctx) ||
          !MaybeReplaceWithCopy(&verify_ctx, &verify_pctx, copy_ctx)) {
        return false;
      }
      EXPECT_TRUE(EVP_DigestVerify(verify_ctx.get(), actual.data(),
                                   actual.size(), input.data(), input.size()))
          << "Could not verify result.";
      return true;
    }

    if (!t->GetBytes(&output, "Output")) {
      return false;
    }
    EXPECT_EQ(Bytes(output), Bytes(actual));
    return true;
  }

  bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
  if (!ctx || !key_op_init(ctx.get()) ||
      !MaybeReplaceWithCopy(&ctx, copy_ctx) ||
      (digest != nullptr &&
       !EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
      !SetupContext(t, key_map, ctx.get()) ||
      !MaybeReplaceWithCopy(&ctx, copy_ctx)) {
    return false;
  }

  if (is_verify) {
    return EVP_PKEY_verify(ctx.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;
  }

  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()) ||
        !MaybeReplaceWithCopy(&decrypt_ctx, copy_ctx) ||
        (digest != nullptr &&
         !EVP_PKEY_CTX_set_signature_md(decrypt_ctx.get(), digest)) ||
        !SetupContext(t, key_map, decrypt_ctx.get()) ||
        !MaybeReplaceWithCopy(&decrypt_ctx, copy_ctx) ||
        !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()) ||
        !MaybeReplaceWithCopy(&verify_ctx, copy_ctx) ||
        (digest != nullptr &&
         !EVP_PKEY_CTX_set_signature_md(verify_ctx.get(), digest)) ||
        !SetupContext(t, key_map, verify_ctx.get()) ||
        !MaybeReplaceWithCopy(&verify_ctx, copy_ctx)) {
      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));
  }
  return true;
}

bool TestEVP(FileTest *t, KeyMap *key_map) {
  if (t->GetType() == "PrivateKey") {
    return ImportKey(t, key_map, KeyRole::kPrivate);
  }

  if (t->GetType() == "PrivateKeyFromSeed") {
    return ImportRawKey(t, key_map, KeyRole::kPrivate, /*use_seed=*/true);
  }

  if (t->GetType() == "PublicKey") {
    return ImportKey(t, key_map, KeyRole::kPublic);
  }

  if (t->GetType() == "PublicKeyFromRaw") {
    return ImportRawKey(t, key_map, KeyRole::kPublic, /*use_seed=*/false);
  }

  if (t->GetType() == "DHKey") {
    return ImportDHKey(t, key_map);
  }

  // Run the test twice, once copying the context and once normally.
  return TestEVPOperation(t, key_map, /*copy_ctx=*/false) &&
         TestEVPOperation(t, key_map, /*copy_ctx=*/true);
}

void RunEVPTests(const char *path) {
  KeyMap key_map;
  FileTestGTest(path, [&](FileTest *t) {
    bool result = TestEVP(t, &key_map);
    if (t->HasAttribute("Error")) {
      ASSERT_FALSE(result) << "Operation unexpectedly succeeded.";
      uint32_t err = ERR_peek_error();
      EXPECT_EQ(t->GetAttributeOrDie("Error"), ERR_reason_error_string(err));
    } else if (!result) {
      ADD_FAILURE() << "Operation unexpectedly failed.";
    }
  });
}

TEST(EVPTest, GeneralTestVectors) {
  RunEVPTests("crypto/evp/test/evp_tests.txt");
}

TEST(EVPTest, DHTestVectors) { RunEVPTests("crypto/evp/test/dh_tests.txt"); }

TEST(EVPTest, ECTestVectors) { RunEVPTests("crypto/evp/test/ec_tests.txt"); }

TEST(EVPTest, Ed25519TestVectors) {
  RunEVPTests("crypto/evp/test/ed25519_tests.txt");
}

TEST(EVPTest, MLDSATestVectors) {
  RunEVPTests("crypto/evp/test/mldsa_tests.txt");
}

TEST(EVPTest, MLKEMTestVectors) {
  RunEVPTests("crypto/evp/test/mlkem_tests.txt");
}

TEST(EVPTest, RSATestVectors) { RunEVPTests("crypto/evp/test/rsa_tests.txt"); }

TEST(EVPTest, X25519TestVectors) {
  RunEVPTests("crypto/evp/test/x25519_tests.txt");
}

TEST(EVPTest, XWingTestVectors) {
  RunEVPTests("crypto/evp/test/xwing_tests.txt");
}

void RunWycheproofVerifyTest(const char *path, const EVP_PKEY_ALG *alg) {
  SCOPED_TRACE(path);
  FileTestGTest(path, [&](FileTest *t) {
    t->IgnoreAllUnusedInstructions();

    const EVP_MD *md = nullptr;
    if (t->HasInstruction("sha")) {
      md = GetWycheproofDigest(t, "sha", true);
      ASSERT_TRUE(md);
    }

    bool is_pss = t->HasInstruction("mgf");
    const EVP_MD *mgf1_md = nullptr;
    int pss_salt_len = RSA_PSS_SALTLEN_DIGEST;
    if (is_pss) {
      ASSERT_EQ("MGF1", t->GetInstructionOrDie("mgf"));
      mgf1_md = GetWycheproofDigest(t, "mgfSha", true);

      std::string s_len;
      ASSERT_TRUE(t->GetInstruction(&s_len, "sLen"));
      pss_salt_len = atoi(s_len.c_str());
    }

    std::vector<uint8_t> msg;
    ASSERT_TRUE(t->GetBytes(&msg, "msg"));
    std::vector<uint8_t> sig;
    ASSERT_TRUE(t->GetBytes(&sig, "sig"));
    std::vector<uint8_t> sig_ctx;
    if (t->HasAttribute("ctx")) {
      ASSERT_TRUE(t->GetBytes(&sig_ctx, "ctx"));
    }
    WycheproofResult result;
    ASSERT_TRUE(GetWycheproofResult(t, &result));
    // BoringSSL does not enforce policies on weak keys and leaves it to the
    // caller.
    bool expect_valid =
        result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"});

    std::vector<uint8_t> der;
    ASSERT_TRUE(t->GetInstructionBytes(&der, "publicKeyDer"));
    bssl::UniquePtr<EVP_PKEY> key(
        EVP_PKEY_from_subject_public_key_info(der.data(), der.size(), &alg, 1));
    if (!key) {
      EXPECT_FALSE(expect_valid);
      return;
    }

    if (EVP_PKEY_id(key.get()) == EVP_PKEY_DSA) {
      // DSA is deprecated and is not usable via EVP.
      DSA *dsa = EVP_PKEY_get0_DSA(key.get());
      uint8_t digest[EVP_MAX_MD_SIZE];
      unsigned digest_len;
      ASSERT_TRUE(
          EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, nullptr));
      int valid;
      bool sig_ok = DSA_check_signature(&valid, digest, digest_len, sig.data(),
                                        sig.size(), dsa) &&
                    valid;
      EXPECT_EQ(sig_ok, result.IsValid());
    } else {
      bssl::ScopedEVP_MD_CTX ctx;
      EVP_PKEY_CTX *pctx;
      ASSERT_TRUE(
          EVP_DigestVerifyInit(ctx.get(), &pctx, md, nullptr, key.get()));
      if (is_pss) {
        ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING));
        ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1_md));
        ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, pss_salt_len));
      }
      if (!sig_ctx.empty() && !EVP_PKEY_CTX_set1_signature_context_string(
                                  pctx, sig_ctx.data(), sig_ctx.size())) {
        EXPECT_FALSE(expect_valid);
        return;
      }
      int ret = EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(),
                                 msg.size());
      EXPECT_EQ(ret, expect_valid ? 1 : 0);
    }
  });
}

TEST(EVPTest, WycheproofDSA) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/dsa_2048_224_sha224_test.txt",
      EVP_pkey_dsa());
}

TEST(EVPTest, WycheproofECDSAP224) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt",
      EVP_pkey_ec_p224());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt",
      EVP_pkey_ec_p224());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt",
      EVP_pkey_ec_p224());
}

TEST(EVPTest, WycheproofECDSAP256) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt",
      EVP_pkey_ec_p256());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt",
      EVP_pkey_ec_p256());
}

TEST(EVPTest, WycheproofECDSAP384) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt",
      EVP_pkey_ec_p384());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt",
      EVP_pkey_ec_p384());
}

TEST(EVPTest, WycheproofECDSAP521) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt",
      EVP_pkey_ec_p521());
}

TEST(EVPTest, WycheproofEd25519) {
  RunWycheproofVerifyTest("third_party/wycheproof_testvectors/ed25519_test.txt",
                          EVP_pkey_ed25519());
}

// TODO(crbug.com/449751916): We also test these in the low-level ML-DSA code.
// The EVP-level tests are not yet redundant:
//
// * We can't yet run the signing tests with external entropy.
//
// When/if we add `EVP_PKEY`-based APIs for those, we may be able to remove the
// low-level copy.

TEST(EVPTest, WycheproofMLDSA44) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/mldsa_44_verify_test.txt",
      EVP_pkey_ml_dsa_44());
}

TEST(EVPTest, WycheproofMLDSA65) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/mldsa_65_verify_test.txt",
      EVP_pkey_ml_dsa_65());
}

TEST(EVPTest, WycheproofMLDSA87) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/mldsa_87_verify_test.txt",
      EVP_pkey_ml_dsa_87());
}

TEST(EVPTest, WycheproofRSAPKCS1) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_4096_sha256_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_8192_sha256_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_8192_sha384_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_signature_8192_sha512_test.txt",
      EVP_pkey_rsa());
}

void RunWycheproofSignTest(FileTest *t) {
  t->IgnoreAllUnusedInstructions();

  std::vector<uint8_t> pkcs8;
  ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
  CBS cbs;
  CBS_init(&cbs, pkcs8.data(), pkcs8.size());
  bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
  ASSERT_TRUE(key);

  const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
  ASSERT_TRUE(md);

  std::vector<uint8_t> msg, sig;
  ASSERT_TRUE(t->GetBytes(&msg, "msg"));
  ASSERT_TRUE(t->GetBytes(&sig, "sig"));
  WycheproofResult result;
  ASSERT_TRUE(GetWycheproofResult(t, &result));

  bssl::ScopedEVP_MD_CTX ctx;
  EVP_PKEY_CTX *pctx;
  ASSERT_TRUE(EVP_DigestSignInit(ctx.get(), &pctx, md, nullptr, key.get()));
  std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
  size_t len = out.size();
  int ret = EVP_DigestSign(ctx.get(), out.data(), &len, msg.data(), msg.size());
  // BoringSSL does not enforce policies on weak keys and leaves it to the
  // caller.
  bool is_valid =
      result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"});
  EXPECT_EQ(ret, is_valid ? 1 : 0);
  if (is_valid) {
    out.resize(len);
    EXPECT_EQ(Bytes(sig), Bytes(out));
  }
}

TEST(EVPTest, WycheproofRSAPKCS1Sign) {
  FileTestGTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_1024_sig_gen_test.txt",
      RunWycheproofSignTest);
  FileTestGTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_1536_sig_gen_test.txt",
      RunWycheproofSignTest);
  FileTestGTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_2048_sig_gen_test.txt",
      RunWycheproofSignTest);
  FileTestGTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_3072_sig_gen_test.txt",
      RunWycheproofSignTest);
  FileTestGTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_4096_sig_gen_test.txt",
      RunWycheproofSignTest);
}

TEST(EVPTest, WycheproofRSAPSS) {
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_32_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_pss_3072_sha256_mgf1_32_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_pss_4096_sha256_mgf1_32_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_pss_4096_sha512_mgf1_32_test.txt",
      EVP_pkey_rsa());
  RunWycheproofVerifyTest(
      "third_party/wycheproof_testvectors/rsa_pss_misc_test.txt",
      EVP_pkey_rsa());
}

void RunWycheproofDecryptTest(
    const char *path,
    std::function<void(FileTest *, EVP_PKEY_CTX *)> setup_cb) {
  FileTestGTest(path, [&](FileTest *t) {
    t->IgnoreAllUnusedInstructions();

    std::vector<uint8_t> pkcs8;
    ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
    CBS cbs;
    CBS_init(&cbs, pkcs8.data(), pkcs8.size());
    bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
    ASSERT_TRUE(key);

    std::vector<uint8_t> ct, msg;
    ASSERT_TRUE(t->GetBytes(&ct, "ct"));
    ASSERT_TRUE(t->GetBytes(&msg, "msg"));
    WycheproofResult result;
    ASSERT_TRUE(GetWycheproofResult(t, &result));

    bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key.get(), nullptr));
    ASSERT_TRUE(ctx);
    ASSERT_TRUE(EVP_PKEY_decrypt_init(ctx.get()));
    ASSERT_NO_FATAL_FAILURE(setup_cb(t, ctx.get()));
    std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
    size_t len = out.size();
    int ret =
        EVP_PKEY_decrypt(ctx.get(), out.data(), &len, ct.data(), ct.size());
    // BoringSSL does not enforce policies on weak keys and leaves it to the
    // caller.
    bool is_valid =
        result.IsValid({"SmallModulus", "Constructed", "EncryptionWithLabel",
                        "SmallIntegerCiphertext"});
    EXPECT_EQ(ret, is_valid ? 1 : 0);
    if (is_valid) {
      out.resize(len);
      EXPECT_EQ(Bytes(msg), Bytes(out));
    }
  });
}

void RunWycheproofOAEPTest(const char *path) {
  RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
    const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
    ASSERT_TRUE(md);
    const EVP_MD *mgf1_md = GetWycheproofDigest(t, "mgfSha", true);
    ASSERT_TRUE(mgf1_md);
    std::vector<uint8_t> label;
    ASSERT_TRUE(t->GetBytes(&label, "label"));

    ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING));
    ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md));
    ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md));
    bssl::UniquePtr<uint8_t> label_copy(
        static_cast<uint8_t *>(OPENSSL_memdup(label.data(), label.size())));
    ASSERT_TRUE(label_copy || label.empty());
    ASSERT_TRUE(
        EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label_copy.get(), label.size()));
    // `EVP_PKEY_CTX_set0_rsa_oaep_label` takes ownership on success.
    label_copy.release();
  });
}

TEST(EVPTest, WycheproofRSAOAEP2048) {
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha1_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha224_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha224_mgf1sha224_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha256_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha256_mgf1sha256_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha384_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha384_mgf1sha384_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha512_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_2048_sha512_mgf1sha512_test.txt");
}

TEST(EVPTest, WycheproofRSAOAEP3072) {
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_3072_sha256_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_3072_sha256_mgf1sha256_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_3072_sha512_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_3072_sha512_mgf1sha512_test.txt");
}

TEST(EVPTest, WycheproofRSAOAEP4096) {
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_4096_sha256_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_4096_sha256_mgf1sha256_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_4096_sha512_mgf1sha1_test.txt");
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/"
      "rsa_oaep_4096_sha512_mgf1sha512_test.txt");
}

TEST(EVPTest, WycheproofRSAOAEPMisc) {
  RunWycheproofOAEPTest(
      "third_party/wycheproof_testvectors/rsa_oaep_misc_test.txt");
}

void RunWycheproofPKCS1DecryptTest(const char *path) {
  RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
    // No setup needed. PKCS#1 is, sadly, the default.
  });
}

TEST(EVPTest, WycheproofRSAPKCS1Decrypt) {
  RunWycheproofPKCS1DecryptTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_2048_test.txt");
  RunWycheproofPKCS1DecryptTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_3072_test.txt");
  RunWycheproofPKCS1DecryptTest(
      "third_party/wycheproof_testvectors/rsa_pkcs1_4096_test.txt");
}
}  // namespace
BSSL_NAMESPACE_END
