// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "crypto/symmetric_key.h"

#include <memory>
#include <string>

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "testing/gtest/include/gtest/gtest.h"

TEST(SymmetricKeyTest, GenerateRandomKey) {
  std::unique_ptr<crypto::SymmetricKey> key(
      crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
  ASSERT_TRUE(key);
  std::string raw_key;
  EXPECT_TRUE(key->GetRawKey(&raw_key));
  EXPECT_EQ(32U, raw_key.size());

  // Do it again and check that the keys are different.
  // (Note: this has a one-in-10^77 chance of failure!)
  std::unique_ptr<crypto::SymmetricKey> key2(
      crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
  ASSERT_TRUE(key2);
  std::string raw_key2;
  EXPECT_TRUE(key2->GetRawKey(&raw_key2));
  EXPECT_EQ(32U, raw_key2.size());
  EXPECT_NE(raw_key, raw_key2);
}

TEST(SymmetricKeyTest, ImportGeneratedKey) {
  std::unique_ptr<crypto::SymmetricKey> key1(
      crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
  ASSERT_TRUE(key1);
  std::string raw_key1;
  EXPECT_TRUE(key1->GetRawKey(&raw_key1));

  std::unique_ptr<crypto::SymmetricKey> key2(
      crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, raw_key1));
  ASSERT_TRUE(key2);

  std::string raw_key2;
  EXPECT_TRUE(key2->GetRawKey(&raw_key2));

  EXPECT_EQ(raw_key1, raw_key2);
}

TEST(SymmetricKeyTest, ImportDerivedKey) {
  std::unique_ptr<crypto::SymmetricKey> key1(
      crypto::SymmetricKey::DeriveKeyFromPassword(
          crypto::SymmetricKey::HMAC_SHA1, "password", "somesalt", 1024, 160));
  ASSERT_TRUE(key1);
  std::string raw_key1;
  EXPECT_TRUE(key1->GetRawKey(&raw_key1));

  std::unique_ptr<crypto::SymmetricKey> key2(
      crypto::SymmetricKey::Import(crypto::SymmetricKey::HMAC_SHA1, raw_key1));
  ASSERT_TRUE(key2);

  std::string raw_key2;
  EXPECT_TRUE(key2->GetRawKey(&raw_key2));

  EXPECT_EQ(raw_key1, raw_key2);
}

struct PBKDF2TestVector {
  crypto::SymmetricKey::Algorithm algorithm;
  const char* password;
  const char* salt;
  unsigned int rounds;
  unsigned int key_size_in_bits;
  const char* expected;  // ASCII encoded hex bytes
};

class SymmetricKeyDeriveKeyFromPasswordTest
    : public testing::TestWithParam<PBKDF2TestVector> {
};

TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) {
  PBKDF2TestVector test_data(GetParam());
  std::unique_ptr<crypto::SymmetricKey> key(
      crypto::SymmetricKey::DeriveKeyFromPassword(
          test_data.algorithm, test_data.password, test_data.salt,
          test_data.rounds, test_data.key_size_in_bits));
  ASSERT_TRUE(key);

  std::string raw_key;
  key->GetRawKey(&raw_key);
  EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size());
  EXPECT_EQ(test_data.expected,
            base::ToLowerASCII(base::HexEncode(raw_key.data(),
                                               raw_key.size())));
}

static const PBKDF2TestVector kTestVectors[] = {
  // These tests come from
  // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "salt",
    1,
    160,
    "0c60c80f961f0e71f3a9b524af6012062fe037a6",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "salt",
    2,
    160,
    "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "salt",
    4096,
    160,
    "4b007901b765489abead49d926f721d065a429c1",
  },
  // This test takes over 30s to run on the trybots.
#if 0
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "salt",
    16777216,
    160,
    "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984",
  },
#endif

  // These tests come from RFC 3962, via BSD source code at
  // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "ATHENA.MIT.EDUraeburn",
    1,
    160,
    "cdedb5281bb2f801565a1122b25635150ad1f7a0",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "ATHENA.MIT.EDUraeburn",
    2,
    160,
    "01dbee7f4a9e243e988b62c73cda935da05378b9",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "ATHENA.MIT.EDUraeburn",
    1200,
    160,
    "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "password",
    "\022" "4VxxV4\022", /* 0x1234567878563412 */
    5,
    160,
    "d1daa78615f287e6a1c8b120d7062a493f98d203",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "pass phrase equals block size",
    1200,
    160,
    "139c30c0966bc32ba55fdbf212530ac9c5ec59f1",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "pass phrase exceeds block size",
    1200,
    160,
    "9ccad6d468770cd51b10e6a68721be611a8b4d28",
  },
  {
    crypto::SymmetricKey::HMAC_SHA1,
    "\360\235\204\236", /* g-clef (0xf09d849e) */
    "EXAMPLE.COMpianist",
    50,
    160,
    "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0",
  },

  // Regression tests for AES keys, derived from the Linux NSS implementation.
  {
    crypto::SymmetricKey::AES,
    "A test password",
    "saltsalt",
    1,
    256,
    "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de",
  },
  {
    crypto::SymmetricKey::AES,
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "pass phrase exceeds block size",
    20,
    256,
    "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c",
  },
};

INSTANTIATE_TEST_CASE_P(, SymmetricKeyDeriveKeyFromPasswordTest,
                        testing::ValuesIn(kTestVectors));
