/* Copyright 2015 The BoringSSL Authors
 *
 * 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 <gtest/gtest.h>

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

#include "../internal.h"
#include "../test/test_util.h"


// 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.
TEST(PBKDFTest, EmptyPassword) {
  const uint8_t kKey[] = {0xa3, 0x3d, 0xdd, 0xc3, 0x04, 0x78, 0x18,
                          0x55, 0x15, 0x31, 0x1f, 0x87, 0x52, 0x89,
                          0x5d, 0x36, 0xea, 0x43, 0x63, 0xa2};
  uint8_t key[sizeof(kKey)];

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC(NULL, 0, (const uint8_t *)"salt", 4, 1,
                                EVP_sha1(), sizeof(kKey), key));
  EXPECT_EQ(Bytes(kKey), Bytes(key));

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC("", 0, (const uint8_t *)"salt", 4, 1,
                                EVP_sha1(), sizeof(kKey), key));
  EXPECT_EQ(Bytes(kKey), Bytes(key));
}

// Tests deriving a key using an empty salt. Note that the expectation was
// generated using OpenSSL itself, and hence is not verified.
TEST(PBKDFTest, EmptySalt) {
  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};
  uint8_t key[sizeof(kKey)];

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC("password", 8, NULL, 0, 2, EVP_sha256(),
                                sizeof(kKey), key));
  EXPECT_EQ(Bytes(kKey), Bytes(key));

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC("password", 8, (const uint8_t *)"", 0, 2,
                                EVP_sha256(), sizeof(kKey), key));
  EXPECT_EQ(Bytes(kKey), Bytes(key));
}

// Exercises test vectors taken from https://tools.ietf.org/html/rfc6070.
// Note that each of these test vectors uses SHA-1 as the digest.
TEST(PBKDFTest, RFC6070Vectors) {
  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};
  uint8_t key[sizeof(kKey1)];
  static_assert(sizeof(key) >= sizeof(kKey2), "output too small");
  static_assert(sizeof(key) >= sizeof(kKey3), "output too small");

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC("password", 8, (const uint8_t *)"salt", 4, 1,
                                EVP_sha1(), sizeof(kKey1), key));
  EXPECT_EQ(Bytes(kKey1), Bytes(key, sizeof(kKey1)));

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC("password", 8, (const uint8_t *)"salt", 4, 2,
                                EVP_sha1(), sizeof(kKey2), key));
  EXPECT_EQ(Bytes(kKey2), Bytes(key, sizeof(kKey2)));

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC("pass\0word", 9, (const uint8_t *)"sa\0lt", 5,
                                4096, EVP_sha1(), sizeof(kKey3), key));
  EXPECT_EQ(Bytes(kKey3), Bytes(key, sizeof(kKey3)));
}

// Tests key derivation using SHA-2 digests.
TEST(PBKDFTest, SHA2) {
  // 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};

  uint8_t key[sizeof(kKey2)];
  static_assert(sizeof(key) >= sizeof(kKey1), "output too small");

  ASSERT_TRUE(PKCS5_PBKDF2_HMAC("password", 8, (const uint8_t *)"salt", 4, 2,
                                EVP_sha256(), sizeof(kKey1), key));
  EXPECT_EQ(Bytes(kKey1), Bytes(key, sizeof(kKey1)));

  ASSERT_TRUE(
      PKCS5_PBKDF2_HMAC("passwordPASSWORDpassword", 24,
                        (const uint8_t *)"saltSALTsaltSALTsaltSALTsaltSALTsalt",
                        36, 4096, EVP_sha512(), sizeof(kKey2), key));
  EXPECT_EQ(Bytes(kKey2), Bytes(key, sizeof(kKey2)));
}

// 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.
TEST(PBKDFTest, ZeroIterations) {
  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.
  ASSERT_TRUE(PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
                                1 /* iterations */, digest, key_len, key));

  // 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.
  ASSERT_FALSE(PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
                                 0 /* iterations */, digest, key_len, key));

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