/* Copyright (c) 2017, 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. */

// cavp_aes_test processes a NIST CAVP AES test vector request file and emits
// the corresponding response. An optional sample vector file can be passed to
// verify the result.

#include <stdlib.h>

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

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


struct TestCtx {
  const EVP_CIPHER *cipher;
  std::unique_ptr<FileTest> response_sample;
  bool has_iv;
};

static bool TestCipher(FileTest *t, void *arg) {
  TestCtx *ctx = reinterpret_cast<TestCtx *>(arg);

  if (t->HasInstruction("ENCRYPT") == t->HasInstruction("DECRYPT")) {
    t->PrintLine("Want either ENCRYPT or DECRYPT");
    return false;
  }
  enum {
    kEncrypt,
    kDecrypt,
  } operation = t->HasInstruction("ENCRYPT") ? kEncrypt : kDecrypt;

  std::string count;
  std::vector<uint8_t> key, iv, in, result;
  if (!t->GetAttribute(&count, "COUNT") ||
      !t->GetBytes(&key, "KEY") ||
      (ctx->has_iv && !t->GetBytes(&iv, "IV"))) {
    return false;
  }

  const EVP_CIPHER *cipher = ctx->cipher;
  if (operation == kEncrypt) {
    if (!t->GetBytes(&in, "PLAINTEXT") ||
        !CipherOperation(cipher, &result, true /* encrypt */, key, iv, in)) {
      return false;
    }
    printf("%sCIPHERTEXT = %s\r\n\r\n", t->CurrentTestToString().c_str(),
           EncodeHex(result.data(), result.size()).c_str());
  } else {
    if (!t->GetBytes(&in, "CIPHERTEXT") ||
        !CipherOperation(cipher, &result, false /* decrypt */, key, iv, in)) {
      return false;
    }
    printf("%sPLAINTEXT = %s\r\n\r\n", t->CurrentTestToString().c_str(),
           EncodeHex(result.data(), result.size()).c_str());
  }

  // Check if sample response file matches.
  if (ctx->response_sample) {
    if (ctx->response_sample->ReadNext() != FileTest::kReadSuccess) {
      t->PrintLine("invalid sample file");
      return false;
    }
    std::string expected_count;
    std::vector<uint8_t> expected_result;
    if (!ctx->response_sample->GetAttribute(&expected_count, "COUNT") ||
        count != expected_count ||
        (operation == kEncrypt &&
         (!ctx->response_sample->GetBytes(&expected_result, "CIPHERTEXT") ||
          !t->ExpectBytesEqual(expected_result.data(), expected_result.size(),
                               result.data(), result.size()))) ||
        (operation == kDecrypt &&
         (!ctx->response_sample->GetBytes(&expected_result, "PLAINTEXT") ||
          !t->ExpectBytesEqual(expected_result.data(), expected_result.size(),
                               result.data(), result.size())))) {
      t->PrintLine("result doesn't match");
      return false;
    }
  }

  return true;
}

int main(int argc, char **argv) {
  CRYPTO_library_init();

  if (argc < 3 || argc > 4) {
    fprintf(stderr, "usage: %s <cipher> <test file> [<sample response file>]\n",
            argv[0]);
    return 1;
  }

  const EVP_CIPHER *cipher = GetCipher(argv[1]);
  if (cipher == nullptr) {
    fprintf(stderr, "invalid cipher: %s\n", argv[1]);
    return 1;
  }
  const std::string cipher_name(argv[1]);
  const bool has_iv =
      (cipher_name != "aes-128-ecb" &&
       cipher_name != "aes-192-ecb" &&
       cipher_name != "aes-256-ecb");

  TestCtx ctx = {cipher, nullptr, has_iv};

  if (argc == 4) {
    ctx.response_sample.reset(new FileTest(argv[3]));
    if (!ctx.response_sample->is_open()) {
      return 1;
    }
    ctx.response_sample->SetIgnoreUnusedAttributes(true);
  }

  printf("# Generated by");
  for (int i = 0; i < argc; i++) {
    printf(" %s", argv[i]);
  }
  printf("\r\n\r\n");

  return FileTestMainSilent(TestCipher, &ctx, argv[2]);
}
