// Copyright 2025 The BoringSSL Authors
//
// 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 <stdio.h>

#include <vector>

#include <gtest/gtest.h>

#include <openssl/crypto.h>
#include <openssl/ec.h>
#include <openssl/ec_key.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>

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


static void RunWycheproofTest(const char *path) {
  SCOPED_TRACE(path);
  FileTestGTest(path, [](FileTest *t) {
    t->IgnoreAllUnusedInstructions();

    const EC_GROUP *group = GetWycheproofCurve(t, "key.curve", true);
    ASSERT_TRUE(group);
    std::vector<uint8_t> uncompressed;
    ASSERT_TRUE(t->GetInstructionBytes(&uncompressed, "key.uncompressed"));
    bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
    ASSERT_TRUE(key);
    ASSERT_TRUE(EC_KEY_set_group(key.get(), group));
    ASSERT_TRUE(EC_KEY_oct2key(key.get(), uncompressed.data(),
                               uncompressed.size(), nullptr));

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

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

    uint8_t digest[EVP_MAX_MD_SIZE];
    unsigned int digest_len;
    ASSERT_TRUE(
        EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, nullptr));

    int ret = ECDSA_verify_p1363(digest, digest_len, sig.data(), sig.size(),
                                 key.get());
    EXPECT_EQ(ret, result.IsValid() ? 1 : 0);
  });
}

TEST(ECDSAP1363Test, WycheproofP224) {
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp224r1_sha224_p1363_test.txt");
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp224r1_sha256_p1363_test.txt");
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp224r1_sha512_p1363_test.txt");
}

TEST(ECDSAP1363Test, WycheproofP256) {
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp256r1_sha256_p1363_test.txt");
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp256r1_sha512_p1363_test.txt");
}

TEST(ECDSAP1363Test, WycheproofP384) {
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp384r1_sha384_p1363_test.txt");
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp384r1_sha512_p1363_test.txt");
}

TEST(ECDSAP1363Test, WycheproofP521) {
  RunWycheproofTest(
      "third_party/wycheproof_testvectors/"
      "ecdsa_secp521r1_sha512_p1363_test.txt");
}


static void RunSignTest(const EC_GROUP *group) {
  // Fill digest values with some random data.
  uint8_t digest[20];
  ASSERT_TRUE(RAND_bytes(digest, sizeof(digest)));

  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
  ASSERT_TRUE(key);
  ASSERT_TRUE(EC_KEY_set_group(key.get(), group));
  ASSERT_TRUE(EC_KEY_generate_key(key.get()));

  size_t sig_len = ECDSA_size_p1363(key.get());
  ASSERT_GT(sig_len, 0u);
  std::vector<uint8_t> sig(sig_len);

  size_t out_sig_len;
  ASSERT_TRUE(ECDSA_sign_p1363(digest, sizeof(digest), sig.data(), &out_sig_len,
                               sig.size(), key.get()));
  ASSERT_EQ(out_sig_len, sig_len);

  ASSERT_TRUE(ECDSA_verify_p1363(digest, sizeof(digest), sig.data(), sig.size(),
                                 key.get()));
}

TEST(ECDSAP1363Test, SignP224) {
  RunSignTest(EC_group_p224());
}

TEST(ECDSAP1363Test, SignP256) {
  RunSignTest(EC_group_p256());
}

TEST(ECDSAP1363Test, SignP384) {
  RunSignTest(EC_group_p384());
}

TEST(ECDSAP1363Test, SignP521) {
  RunSignTest(EC_group_p521());
}

TEST(ECDSAP1363Test, SignFailsWithSmallBuffer) {
  // Fill digest values with some random data.
  uint8_t digest[20];
  ASSERT_TRUE(RAND_bytes(digest, sizeof(digest)));

  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
  ASSERT_TRUE(key);
  ASSERT_TRUE(EC_KEY_set_group(key.get(), EC_group_p256()));
  ASSERT_TRUE(EC_KEY_generate_key(key.get()));

  size_t sig_len = ECDSA_size_p1363(key.get());
  ASSERT_GT(sig_len, 0u);
  std::vector<uint8_t> sig(sig_len - 1);

  size_t out_sig_len;
  ASSERT_FALSE(ECDSA_sign_p1363(digest, sizeof(digest), sig.data(),
                                &out_sig_len, sig.size(), key.get()));
}

TEST(ECDSAP1363Test, SignSucceedsWithLargeBuffer) {
  // Fill digest values with some random data.
  uint8_t digest[20];
  ASSERT_TRUE(RAND_bytes(digest, sizeof(digest)));

  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
  ASSERT_TRUE(key);
  ASSERT_TRUE(EC_KEY_set_group(key.get(), EC_group_p256()));
  ASSERT_TRUE(EC_KEY_generate_key(key.get()));

  size_t sig_len = ECDSA_size_p1363(key.get());
  ASSERT_GT(sig_len, 0u);
  std::vector<uint8_t> sig(sig_len + 1, 'x');

  size_t out_sig_len;
  ASSERT_TRUE(ECDSA_sign_p1363(digest, sizeof(digest), sig.data(),
                                &out_sig_len, sig.size(), key.get()));
  ASSERT_EQ(out_sig_len, sig_len);
  // The extra byte should be untouched.
  EXPECT_EQ(sig.back(), 'x');

  ASSERT_TRUE(ECDSA_verify_p1363(digest, sizeof(digest), sig.data(),
                                 out_sig_len, key.get()));
}

TEST(ECDSAP1363Test, SizeWithoutGroup) {
  EXPECT_EQ(ECDSA_size_p1363(nullptr), 0u);

  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
  EXPECT_EQ(ECDSA_size_p1363(key.get()), 0u);
}
