/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

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

#include <vector>

#include <openssl/aead.h>
#include <openssl/crypto.h>
#include <openssl/err.h>

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


namespace bssl {

// This program tests an AEAD against a series of test vectors from a file,
// using the FileTest format. As an example, here's a valid test case:
//
//   KEY: 5a19f3173586b4c42f8412f4d5a786531b3231753e9e00998aec12fda8df10e4
//   NONCE: 978105dfce667bf4
//   IN: 6a4583908d
//   AD: b654574932
//   CT: 5294265a60
//   TAG: 1d45758621762e061368e68868e2f929

static bool TestAEAD(FileTest *t, void *arg) {
  const EVP_AEAD *aead = reinterpret_cast<const EVP_AEAD*>(arg);

  std::vector<uint8_t> key, nonce, in, ad, ct, tag;
  if (!t->GetBytes(&key, "KEY") ||
      !t->GetBytes(&nonce, "NONCE") ||
      !t->GetBytes(&in, "IN") ||
      !t->GetBytes(&ad, "AD") ||
      !t->GetBytes(&ct, "CT") ||
      !t->GetBytes(&tag, "TAG")) {
    return false;
  }

  ScopedEVP_AEAD_CTX ctx;
  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
                                        tag.size(), evp_aead_seal)) {
    t->PrintLine("Failed to init AEAD.");
    return false;
  }

  std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead));
  if (!t->HasAttribute("NO_SEAL")) {
    size_t out_len;
    if (!EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
                           nonce.data(), nonce.size(), in.data(), in.size(),
                           ad.data(), ad.size())) {
      t->PrintLine("Failed to run AEAD.");
      return false;
    }
    out.resize(out_len);

    if (out.size() != ct.size() + tag.size()) {
      t->PrintLine("Bad output length: %u vs %u.", (unsigned)out_len,
                   (unsigned)(ct.size() + tag.size()));
      return false;
    }
    if (!t->ExpectBytesEqual(ct.data(), ct.size(), out.data(), ct.size()) ||
        !t->ExpectBytesEqual(tag.data(), tag.size(), out.data() + ct.size(),
                             tag.size())) {
      return false;
    }
  } else {
    out.resize(ct.size() + tag.size());
    memcpy(out.data(), ct.data(), ct.size());
    memcpy(out.data() + ct.size(), tag.data(), tag.size());
  }

  // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
  // reset after each operation.
  ctx.Reset();
  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
                                        tag.size(), evp_aead_open)) {
    t->PrintLine("Failed to init AEAD.");
    return false;
  }

  std::vector<uint8_t> out2(out.size());
  size_t out2_len;
  int ret = EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
                              nonce.data(), nonce.size(), out.data(),
                              out.size(), ad.data(), ad.size());
  if (t->HasAttribute("FAILS")) {
    if (ret) {
      t->PrintLine("Decrypted bad data.");
      return false;
    }
    ERR_clear_error();
    return true;
  }

  if (!ret) {
    t->PrintLine("Failed to decrypt.");
    return false;
  }
  out2.resize(out2_len);
  if (!t->ExpectBytesEqual(in.data(), in.size(), out2.data(), out2.size())) {
    return false;
  }

  // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
  // reset after each operation.
  ctx.Reset();
  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
                                        tag.size(), evp_aead_open)) {
    t->PrintLine("Failed to init AEAD.");
    return false;
  }

  // Garbage at the end isn't ignored.
  out.push_back(0);
  out2.resize(out.size());
  if (EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
                        nonce.data(), nonce.size(), out.data(), out.size(),
                        ad.data(), ad.size())) {
    t->PrintLine("Decrypted bad data with trailing garbage.");
    return false;
  }
  ERR_clear_error();

  // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
  // reset after each operation.
  ctx.Reset();
  if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
                                        tag.size(), evp_aead_open)) {
    t->PrintLine("Failed to init AEAD.");
    return false;
  }

  // Verify integrity is checked.
  out[0] ^= 0x80;
  out.resize(out.size() - 1);
  out2.resize(out.size());
  if (EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
                        nonce.data(), nonce.size(), out.data(), out.size(),
                        ad.data(), ad.size())) {
    t->PrintLine("Decrypted bad data with corrupted byte.");
    return false;
  }
  ERR_clear_error();

  return true;
}

static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
  EVP_AEAD_CTX ctx;
  uint8_t key[128];

  memset(key, 0, sizeof(key));
  const size_t key_len = EVP_AEAD_key_length(aead);
  if (key_len > sizeof(key)) {
    fprintf(stderr, "Key length of AEAD too long.\n");
    return 0;
  }

  if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
                        9999 /* a silly tag length to trigger an error */,
                        NULL /* ENGINE */) != 0) {
    fprintf(stderr, "A silly tag length didn't trigger an error!\n");
    return 0;
  }
  ERR_clear_error();

  /* Running a second, failed _init should not cause a memory leak. */
  if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
                        9999 /* a silly tag length to trigger an error */,
                        NULL /* ENGINE */) != 0) {
    fprintf(stderr, "A silly tag length didn't trigger an error!\n");
    return 0;
  }
  ERR_clear_error();

  /* Calling _cleanup on an |EVP_AEAD_CTX| after a failed _init should be a
   * no-op. */
  EVP_AEAD_CTX_cleanup(&ctx);
  return 1;
}

static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
  const size_t key_len = EVP_AEAD_key_length(aead);
  const size_t nonce_len = EVP_AEAD_nonce_length(aead);
  const size_t max_overhead = EVP_AEAD_max_overhead(aead);

  std::vector<uint8_t> key(key_len, 'a');
  ScopedEVP_AEAD_CTX ctx;
  if (!EVP_AEAD_CTX_init(ctx.get(), aead, key.data(), key_len,
                         EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
    return false;
  }

  static const uint8_t kPlaintext[260] =
      "testing123456testing123456testing123456testing123456testing123456testing"
      "123456testing123456testing123456testing123456testing123456testing123456t"
      "esting123456testing123456testing123456testing123456testing123456testing1"
      "23456testing123456testing123456testing12345";
  const std::vector<size_t> offsets = {
      0,  1,  2,  8,  15, 16,  17,  31,  32,  33,  63,
      64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
  };

  std::vector<uint8_t> nonce(nonce_len, 'b');
  std::vector<uint8_t> valid_encryption(sizeof(kPlaintext) + max_overhead);
  size_t valid_encryption_len;
  if (!EVP_AEAD_CTX_seal(
          ctx.get(), valid_encryption.data(), &valid_encryption_len,
          sizeof(kPlaintext) + max_overhead, nonce.data(), nonce_len,
          kPlaintext, sizeof(kPlaintext), nullptr, 0)) {
    fprintf(stderr, "EVP_AEAD_CTX_seal failed with disjoint buffers.\n");
    return false;
  }

  // Test with out != in which we expect to fail.
  std::vector<uint8_t> buffer(2 + valid_encryption_len);
  uint8_t *in = buffer.data() + 1;
  uint8_t *out1 = buffer.data();
  uint8_t *out2 = buffer.data() + 2;

  memcpy(in, kPlaintext, sizeof(kPlaintext));
  size_t out_len;
  if (EVP_AEAD_CTX_seal(ctx.get(), out1, &out_len,
                        sizeof(kPlaintext) + max_overhead, nonce.data(),
                        nonce_len, in, sizeof(kPlaintext), nullptr, 0) ||
      EVP_AEAD_CTX_seal(ctx.get(), out2, &out_len,
                        sizeof(kPlaintext) + max_overhead, nonce.data(),
                        nonce_len, in, sizeof(kPlaintext), nullptr, 0)) {
    fprintf(stderr, "EVP_AEAD_CTX_seal unexpectedly succeeded.\n");
    return false;
  }
  ERR_clear_error();

  memcpy(in, valid_encryption.data(), valid_encryption_len);
  if (EVP_AEAD_CTX_open(ctx.get(), out1, &out_len, valid_encryption_len,
                        nonce.data(), nonce_len, in, valid_encryption_len,
                        nullptr, 0) ||
      EVP_AEAD_CTX_open(ctx.get(), out2, &out_len, valid_encryption_len,
                        nonce.data(), nonce_len, in, valid_encryption_len,
                        nullptr, 0)) {
    fprintf(stderr, "EVP_AEAD_CTX_open unexpectedly succeeded.\n");
    return false;
  }
  ERR_clear_error();

  // Test with out == in, which we expect to work.
  memcpy(in, kPlaintext, sizeof(kPlaintext));

  if (!EVP_AEAD_CTX_seal(ctx.get(), in, &out_len,
                         sizeof(kPlaintext) + max_overhead, nonce.data(),
                         nonce_len, in, sizeof(kPlaintext), nullptr, 0)) {
    fprintf(stderr, "EVP_AEAD_CTX_seal failed in-place.\n");
    return false;
  }

  if (out_len != valid_encryption_len ||
      memcmp(in, valid_encryption.data(), out_len) != 0) {
    fprintf(stderr, "EVP_AEAD_CTX_seal produced bad output in-place.\n");
    return false;
  }

  memcpy(in, valid_encryption.data(), valid_encryption_len);
  if (!EVP_AEAD_CTX_open(ctx.get(), in, &out_len, valid_encryption_len,
                         nonce.data(), nonce_len, in, valid_encryption_len,
                         nullptr, 0)) {
    fprintf(stderr, "EVP_AEAD_CTX_open failed in-place.\n");
    return false;
  }

  if (out_len != sizeof(kPlaintext) ||
      memcmp(in, kPlaintext, out_len) != 0) {
    fprintf(stderr, "EVP_AEAD_CTX_open produced bad output in-place.\n");
    return false;
  }

  return true;
}

struct KnownAEAD {
  const char name[40];
  const EVP_AEAD *(*func)(void);
  // limited_implementation indicates that tests that assume a generic AEAD
  // interface should not be performed. For example, the key-wrap AEADs only
  // handle inputs that are a multiple of eight bytes in length and the
  // SSLv3/TLS AEADs have the concept of “direction”.
  bool limited_implementation;
};

static const struct KnownAEAD kAEADs[] = {
  { "aes-128-gcm", EVP_aead_aes_128_gcm, false },
  { "aes-256-gcm", EVP_aead_aes_256_gcm, false },
  { "chacha20-poly1305", EVP_aead_chacha20_poly1305, false },
  { "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old, false },
  { "rc4-md5-tls", EVP_aead_rc4_md5_tls, true },
  { "rc4-sha1-tls", EVP_aead_rc4_sha1_tls, true },
  { "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls, true },
  { "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv, true },
  { "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls, true },
  { "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls, true },
  { "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv, true },
  { "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls, true },
  { "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls, true },
  { "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls, true },
  { "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv, true },
  { "rc4-md5-ssl3", EVP_aead_rc4_md5_ssl3, true },
  { "rc4-sha1-ssl3", EVP_aead_rc4_sha1_ssl3, true },
  { "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3, true },
  { "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3, true },
  { "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3, true },
  { "aes-128-key-wrap", EVP_aead_aes_128_key_wrap, true },
  { "aes-256-key-wrap", EVP_aead_aes_256_key_wrap, true },
  { "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256, false },
  { "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256, false },
  { "", NULL, false },
};

static int Main(int argc, char **argv) {
  CRYPTO_library_init();

  if (argc != 3) {
    fprintf(stderr, "%s <aead> <test file.txt>\n", argv[0]);
    return 1;
  }

  const struct KnownAEAD *known_aead;
  for (unsigned i = 0;; i++) {
    known_aead = &kAEADs[i];
    if (known_aead->func == NULL) {
      fprintf(stderr, "Unknown AEAD: %s\n", argv[1]);
      return 2;
    }
    if (strcmp(known_aead->name, argv[1]) == 0) {
      break;
    }
  }

  const EVP_AEAD *const aead = known_aead->func();

  if (!TestCleanupAfterInitFailure(aead)) {
    return 1;
  }

  if (!known_aead->limited_implementation && !TestWithAliasedBuffers(aead)) {
    fprintf(stderr, "Aliased buffers test failed for %s.\n", known_aead->name);
    return 1;
  }

  return FileTestMain(TestAEAD, const_cast<EVP_AEAD*>(aead), argv[2]);
}

}  // namespace bssl

int main(int argc, char **argv) {
  return bssl::Main(argc, argv);
}
