/* Copyright (c) 2015, 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 <stdio.h>
#include <string.h>

#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>


// Prints out the data buffer as a sequence of hex bytes.
static void PrintDataHex(const void *data, size_t len) {
  for (size_t i = 0; i < len; ++i) {
    fprintf(stderr, "%02x", (int)((const uint8_t *)data)[i]);
  }
}

// Helper for testing that PBKDF2 derives the expected key from the given
// inputs. Returns 1 on success, 0 otherwise.
static bool TestPBKDF2(const void *password, size_t password_len,
                       const void *salt, size_t salt_len, unsigned iterations,
                       const EVP_MD *digest, size_t key_len,
                       const uint8_t *expected_key) {
  uint8_t key[64];

  if (key_len > sizeof(key)) {
    fprintf(stderr, "Output buffer is not large enough.\n");
    return false;
  }

  if (!PKCS5_PBKDF2_HMAC((const char *)password, password_len,
                         (const uint8_t *)salt, salt_len, iterations, digest,
                         key_len, key)) {
    fprintf(stderr, "Call to PKCS5_PBKDF2_HMAC failed\n");
    ERR_print_errors_fp(stderr);
    return false;
  }

  if (memcmp(key, expected_key, key_len) != 0) {
    fprintf(stderr, "Resulting key material does not match expectation\n");
    fprintf(stderr, "Expected:\n    ");
    PrintDataHex(expected_key, key_len);
    fprintf(stderr, "\nActual:\n    ");
    PrintDataHex(key, key_len);
    fprintf(stderr, "\n");
    return false;
  }

  return true;
}

// Tests deriving a key using an empty password (specified both as NULL and as
// non-NULL). Note that NULL has special meaning to HMAC initialization.
static bool TestEmptyPassword() {
  const uint8_t kKey[] = {0xa3, 0x3d, 0xdd, 0xc3, 0x04, 0x78, 0x18,
                          0x55, 0x15, 0x31, 0x1f, 0x87, 0x52, 0x89,
                          0x5d, 0x36, 0xea, 0x43, 0x63, 0xa2};

  if (!TestPBKDF2(NULL, 0, "salt", 4, 1, EVP_sha1(), sizeof(kKey), kKey) ||
      !TestPBKDF2("", 0, "salt", 4, 1, EVP_sha1(), sizeof(kKey), kKey)) {
    return false;
  }

  return true;
}

// Tests deriving a key using an empty salt. Note that the expectation was
// generated using OpenSSL itself, and hence is not verified.
static bool TestEmptySalt() {
  const uint8_t kKey[] = {0x8b, 0xc2, 0xf9, 0x16, 0x7a, 0x81, 0xcd, 0xcf,
                          0xad, 0x12, 0x35, 0xcd, 0x90, 0x47, 0xf1, 0x13,
                          0x62, 0x71, 0xc1, 0xf9, 0x78, 0xfc, 0xfc, 0xb3,
                          0x5e, 0x22, 0xdb, 0xea, 0xfa, 0x46, 0x34, 0xf6};

  if (!TestPBKDF2("password", 8, NULL, 0, 2, EVP_sha256(), sizeof(kKey),
                  kKey) ||
      !TestPBKDF2("password", 8, "", 0, 2, EVP_sha256(), sizeof(kKey), kKey)) {
    return false;
  }

  return true;
}

// Exercises test vectors taken from https://tools.ietf.org/html/rfc6070.
// Note that each of these test vectors uses SHA-1 as the digest.
static bool TestRFC6070Vectors() {
  const uint8_t kKey1[] = {0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e,
                           0x71, 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60,
                           0x12, 0x06, 0x2f, 0xe0, 0x37, 0xa6};
  const uint8_t kKey2[] = {0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f,
                           0x8c, 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d,
                           0x41, 0xf0, 0xd8, 0xde, 0x89, 0x57};
  const uint8_t kKey3[] = {0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
                           0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3};

  if (!TestPBKDF2("password", 8, "salt", 4, 1, EVP_sha1(), sizeof(kKey1),
                  kKey1) ||
      !TestPBKDF2("password", 8, "salt", 4, 2, EVP_sha1(), sizeof(kKey2),
                  kKey2) ||
      !TestPBKDF2("pass\0word", 9, "sa\0lt", 5, 4096, EVP_sha1(),
                  sizeof(kKey3), kKey3)) {
    return false;
  }

  return true;
}

// Tests key derivation using SHA-2 digests.
static bool TestSHA2() {
  // This test was taken from:
  // http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors.
  const uint8_t kKey1[] = {0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
                           0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
                           0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf,
                           0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43};

  // This test was taken from:
  // http://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors.
  const uint8_t kKey2[] = {
      0x8c, 0x05, 0x11, 0xf4, 0xc6, 0xe5, 0x97, 0xc6, 0xac, 0x63, 0x15,
      0xd8, 0xf0, 0x36, 0x2e, 0x22, 0x5f, 0x3c, 0x50, 0x14, 0x95, 0xba,
      0x23, 0xb8, 0x68, 0xc0, 0x05, 0x17, 0x4d, 0xc4, 0xee, 0x71, 0x11,
      0x5b, 0x59, 0xf9, 0xe6, 0x0c, 0xd9, 0x53, 0x2f, 0xa3, 0x3e, 0x0f,
      0x75, 0xae, 0xfe, 0x30, 0x22, 0x5c, 0x58, 0x3a, 0x18, 0x6c, 0xd8,
      0x2b, 0xd4, 0xda, 0xea, 0x97, 0x24, 0xa3, 0xd3, 0xb8};

  if (!TestPBKDF2("password", 8, "salt", 4, 2, EVP_sha256(), sizeof(kKey1),
                  kKey1) ||
      !TestPBKDF2("passwordPASSWORDpassword", 24,
                  "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096,
                  EVP_sha512(), sizeof(kKey2), kKey2)) {
    return false;
  }

  return true;
}

// Tests key derivation using iterations=0.
//
// RFC 2898 defines the iteration count (c) as a "positive integer". So doing a
// key derivation with iterations=0 is ill-defined and should result in a
// failure.
static bool TestZeroIterations() {
  static const char kPassword[] = "password";
  const size_t password_len = strlen(kPassword);
  static const uint8_t kSalt[] = {1, 2, 3, 4};
  const size_t salt_len = sizeof(kSalt);
  const EVP_MD *digest = EVP_sha1();

  uint8_t key[10] = {0};
  const size_t key_len = sizeof(key);

  // Verify that calling with iterations=1 works.
  if (!PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
                         1 /* iterations */, digest, key_len, key)) {
    fprintf(stderr, "PBKDF2 failed with iterations=1\n");
    return false;
  }

  // Flip the first key byte (so can later test if it got set).
  const uint8_t expected_first_byte = key[0];
  key[0] = ~key[0];

  // However calling it with iterations=0 fails.
  if (PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
                        0 /* iterations */, digest, key_len, key)) {
    fprintf(stderr, "PBKDF2 returned zero with iterations=0\n");
    return false;
  }

  // For backwards compatibility, the iterations == 0 case still fills in
  // the out key.
  return key[0] == expected_first_byte;
}

int main(void) {
  CRYPTO_library_init();

  if (!TestEmptyPassword()) {
    fprintf(stderr, "TestEmptyPassword failed\n");
    return 1;
  }

  if (!TestEmptySalt()) {
    fprintf(stderr, "TestEmptySalt failed\n");
    return 1;
  }

  if (!TestRFC6070Vectors()) {
    fprintf(stderr, "TestRFC6070Vectors failed\n");
    return 1;
  }

  if (!TestSHA2()) {
    fprintf(stderr, "TestSHA2 failed\n");
    return 1;
  }

  if (!TestZeroIterations()) {
    fprintf(stderr, "TestZeroIterations failed\n");
    return 1;
  }

  printf("PASS\n");
  ERR_free_strings();
  return 0;
}
