// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include "base/types/expected.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/blink/public/platform/web_crypto_key_algorithm.h"

namespace webcrypto {

namespace {

// Creates an AES-GCM algorithm.
blink::WebCryptoAlgorithm CreateAesGcmAlgorithm(
    const std::vector<uint8_t>& iv,
    const std::vector<uint8_t>& additional_data,
    unsigned int tag_length_bits) {
  return blink::WebCryptoAlgorithm::AdoptParamsAndCreate(
      blink::kWebCryptoAlgorithmIdAesGcm,
      new blink::WebCryptoAesGcmParams(iv, true, additional_data, true,
                                       tag_length_bits));
}

blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm(
    uint16_t key_length_bits) {
  return CreateAesKeyGenAlgorithm(blink::kWebCryptoAlgorithmIdAesGcm,
                                  key_length_bits);
}

base::expected<std::vector<uint8_t>, Status> AesGcmEncrypt(
    const blink::WebCryptoKey& key,
    const std::vector<uint8_t>& iv,
    const std::vector<uint8_t>& additional_data,
    size_t tag_length_bits,
    const std::vector<uint8_t>& plain_text) {
  blink::WebCryptoAlgorithm algorithm =
      CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits);

  std::vector<uint8_t> output;
  Status status = Encrypt(algorithm, key, plain_text, &output);
  if (status.IsError()) {
    return base::unexpected(status);
  }
  return output;
}

base::expected<std::vector<uint8_t>, Status> AesGcmDecrypt(
    const blink::WebCryptoKey& key,
    const std::vector<uint8_t>& iv,
    const std::vector<uint8_t>& additional_data,
    unsigned int tag_length_bits,
    const std::vector<uint8_t>& ciphertext) {
  blink::WebCryptoAlgorithm algorithm =
      CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits);

  std::vector<uint8_t> output;
  Status status = Decrypt(algorithm, key, ciphertext, &output);
  if (status.IsError()) {
    return base::unexpected(status);
  }
  return output;
}

class WebCryptoAesGcmTest : public WebCryptoTestBase {};

TEST_F(WebCryptoAesGcmTest, GenerateKeyBadLength) {
  auto generate_key = [](size_t len) {
    blink::WebCryptoKey key;
    return GenerateSecretKey(CreateAesGcmKeyGenAlgorithm(len), true,
                             blink::kWebCryptoKeyUsageDecrypt, &key);
  };
  EXPECT_EQ(generate_key(0), Status::ErrorGenerateAesKeyLength());
  EXPECT_EQ(generate_key(127), Status::ErrorGenerateAesKeyLength());
  EXPECT_EQ(generate_key(257), Status::ErrorGenerateAesKeyLength());
}

TEST_F(WebCryptoAesGcmTest, GenerateKeyEmptyUsage) {
  blink::WebCryptoKey key;
  EXPECT_EQ(Status::ErrorCreateKeyEmptyUsages(),
            GenerateSecretKey(CreateAesGcmKeyGenAlgorithm(256), true, 0, &key));
}

TEST_F(WebCryptoAesGcmTest, ImportExportJwk) {
  const blink::WebCryptoAlgorithm algorithm =
      CreateAlgorithm(blink::kWebCryptoAlgorithmIdAesGcm);

  // AES-GCM 128
  ImportExportJwkSymmetricKey(
      128, algorithm,
      blink::kWebCryptoKeyUsageEncrypt | blink::kWebCryptoKeyUsageDecrypt,
      "A128GCM");

  // AES-GCM 256
  ImportExportJwkSymmetricKey(256, algorithm, blink::kWebCryptoKeyUsageDecrypt,
                              "A256GCM");
}

struct AesGcmKnownAnswer {
  const char* key;
  const char* iv;
  const char* plaintext;
  const char* additional;
  const char* ciphertext;
  size_t tagbits;
};

// NIST GCM test vectors:
// http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
const AesGcmKnownAnswer kAesGcmKnownAnswers[] = {
    {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
     "72ac8493e3a5228b5d130a69d2510e42", 128},
    {"6dfa1a07c14f978020ace450ad663d18", "34edfa462a14c6969a680ec1", "",
     "2a35c7f5f8578e919a581c60500c04f6", "751f3098d59cf4ea1d2fb0853bde1c", 120},
    {"ed6cd876ceba555706674445c229c12d", "92ecbf74b765bc486383ca2e",
     "bfaaaea3880d72d4378561e2597a9b35", "95bd10d77dbe0e87fb34217f1a2e5efe",
     "bdd2ed6c66fa087dce617d7fd1ff6d93ba82e49c55a22ed02ca67da4ec6f", 112},
    {"e03548984a7ec8eaf0870637df0ac6bc17f7159315d0ae26a764fd224e483810",
     "f4feb26b846be4cd224dbc5133a5ae13814ebe19d3032acdd3a006463fdb71e83a9d5d966"
     "79f26cc1719dd6b4feb3bab5b4b7993d0c0681f36d105ad3002fb66b201538e2b7479838a"
     "b83402b0d816cd6e0fe5857e6f4adf92de8ee72b122ba1ac81795024943b7d0151bbf84ce"
     "87c8911f512c397d14112296da7ecdd0da52a",
     "69fd0c9da10b56ec6786333f8d76d4b74f8a434195f2f241f088b2520fb5fa29455df9893"
     "164fb1638abe6617915d9497a8fe2",
     "aab26eb3e7acd09a034a9e2651636ab3868e51281590ecc948355e457da42b7ad1391c7be"
     "0d9e82895e506173a81857c3226829fbd6dfb3f9657a71a2934445d7c05fa9401cddd5109"
     "016ba32c3856afaadc48de80b8a01b57cb",
     "fda718aa1ec163487e21afc34f5a3a34795a9ee71dd3e7ee9a18fdb24181dc982b29c6ec7"
     "23294a130ca2234952bb0ef68c0f34795fbe0",
     32},
};

// TODO(eroman):
//   * Test decryption when the tag length exceeds input size
//   * Test decryption with empty input
//   * Test decryption with tag length of 0.
TEST_F(WebCryptoAesGcmTest, KnownAnswers) {
  // Note that WebCrypto appends the authentication tag to the ciphertext.
  for (const auto& test : kAesGcmKnownAnswers) {
    SCOPED_TRACE(&test - &kAesGcmKnownAnswers[0]);

    auto key_bytes = HexStringToBytes(test.key);
    auto iv_bytes = HexStringToBytes(test.iv);
    auto plaintext_bytes = HexStringToBytes(test.plaintext);
    auto additional_bytes = HexStringToBytes(test.additional);
    auto ciphertext_bytes = HexStringToBytes(test.ciphertext);

    blink::WebCryptoKey key = ImportSecretKeyFromRaw(
        key_bytes, CreateAlgorithm(blink::kWebCryptoAlgorithmIdAesGcm),
        blink::kWebCryptoKeyUsageEncrypt | blink::kWebCryptoKeyUsageDecrypt);

    {
      std::vector<uint8_t> exported_key;
      EXPECT_EQ(Status::Success(),
                ExportKey(blink::kWebCryptoKeyFormatRaw, key, &exported_key));
      EXPECT_BYTES_EQ(key_bytes, exported_key);
    }

    auto encrypt_result = AesGcmEncrypt(key, iv_bytes, additional_bytes,
                                        test.tagbits, plaintext_bytes);
    ASSERT_TRUE(encrypt_result.has_value())
        << encrypt_result.error().error_details();
    EXPECT_BYTES_EQ(encrypt_result.value(), ciphertext_bytes);

    auto decrypt_result = AesGcmDecrypt(key, iv_bytes, additional_bytes,
                                        test.tagbits, ciphertext_bytes);
    ASSERT_TRUE(decrypt_result.has_value())
        << decrypt_result.error().error_details();
    EXPECT_BYTES_EQ(decrypt_result.value(), plaintext_bytes);

    // Decryption should fail if any of the inputs are tampered with.
    EXPECT_EQ(base::unexpected(Status::OperationError()),
              AesGcmDecrypt(key, Corrupted(iv_bytes), additional_bytes,
                            test.tagbits, ciphertext_bytes));
    EXPECT_EQ(base::unexpected(Status::OperationError()),
              AesGcmDecrypt(key, iv_bytes, Corrupted(additional_bytes),
                            test.tagbits, ciphertext_bytes));
    EXPECT_EQ(base::unexpected(Status::OperationError()),
              AesGcmDecrypt(key, iv_bytes, additional_bytes, test.tagbits,
                            Corrupted(ciphertext_bytes)));

    // Try different incorrect tag lengths
    for (unsigned int length : {0, 8, 96, 120, 128, 160, 255}) {
      if (test.tagbits == length)
        continue;
      EXPECT_FALSE(AesGcmDecrypt(key, iv_bytes, additional_bytes, length,
                                 ciphertext_bytes)
                       .has_value());
    }
  }
}

}  // namespace

}  // namespace webcrypto
