symmetric_key_unittest.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "crypto/symmetric_key.h"
  5. #include <memory>
  6. #include <string>
  7. #include "base/strings/string_number_conversions.h"
  8. #include "base/strings/string_util.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. TEST(SymmetricKeyTest, GenerateRandomKey) {
  11. std::unique_ptr<crypto::SymmetricKey> key(
  12. crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
  13. ASSERT_TRUE(key);
  14. EXPECT_EQ(32U, key->key().size());
  15. // Do it again and check that the keys are different.
  16. // (Note: this has a one-in-10^77 chance of failure!)
  17. std::unique_ptr<crypto::SymmetricKey> key2(
  18. crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
  19. ASSERT_TRUE(key2);
  20. EXPECT_EQ(32U, key2->key().size());
  21. EXPECT_NE(key->key(), key2->key());
  22. }
  23. TEST(SymmetricKeyTest, ImportGeneratedKey) {
  24. std::unique_ptr<crypto::SymmetricKey> key1(
  25. crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
  26. ASSERT_TRUE(key1);
  27. std::unique_ptr<crypto::SymmetricKey> key2(
  28. crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key1->key()));
  29. ASSERT_TRUE(key2);
  30. EXPECT_EQ(key1->key(), key2->key());
  31. }
  32. TEST(SymmetricKeyTest, ImportDerivedKey) {
  33. std::unique_ptr<crypto::SymmetricKey> key1(
  34. crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
  35. crypto::SymmetricKey::HMAC_SHA1, "password", "somesalt", 1024, 160));
  36. ASSERT_TRUE(key1);
  37. std::unique_ptr<crypto::SymmetricKey> key2(crypto::SymmetricKey::Import(
  38. crypto::SymmetricKey::HMAC_SHA1, key1->key()));
  39. ASSERT_TRUE(key2);
  40. EXPECT_EQ(key1->key(), key2->key());
  41. }
  42. struct PBKDF2TestVector {
  43. crypto::SymmetricKey::Algorithm algorithm;
  44. const char* password;
  45. const char* salt;
  46. unsigned int rounds;
  47. unsigned int key_size_in_bits;
  48. const char* expected; // ASCII encoded hex bytes.
  49. };
  50. struct ScryptTestVector {
  51. crypto::SymmetricKey::Algorithm algorithm;
  52. const char* password;
  53. const char* salt;
  54. unsigned int cost_parameter;
  55. unsigned int block_size;
  56. unsigned int parallelization_parameter;
  57. unsigned int key_size_in_bits;
  58. const char* expected; // ASCII encoded hex bytes.
  59. };
  60. class SymmetricKeyDeriveKeyFromPasswordUsingPbkdf2Test
  61. : public testing::TestWithParam<PBKDF2TestVector> {};
  62. class SymmetricKeyDeriveKeyFromPasswordUsingScryptTest
  63. : public testing::TestWithParam<ScryptTestVector> {};
  64. TEST_P(SymmetricKeyDeriveKeyFromPasswordUsingPbkdf2Test,
  65. DeriveKeyFromPasswordUsingPbkdf2) {
  66. PBKDF2TestVector test_data(GetParam());
  67. std::unique_ptr<crypto::SymmetricKey> key(
  68. crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
  69. test_data.algorithm, test_data.password, test_data.salt,
  70. test_data.rounds, test_data.key_size_in_bits));
  71. ASSERT_TRUE(key);
  72. const std::string& raw_key = key->key();
  73. EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size());
  74. EXPECT_EQ(test_data.expected,
  75. base::ToLowerASCII(base::HexEncode(raw_key.data(),
  76. raw_key.size())));
  77. }
  78. TEST_P(SymmetricKeyDeriveKeyFromPasswordUsingScryptTest,
  79. DeriveKeyFromPasswordUsingScrypt) {
  80. const int kScryptMaxMemoryBytes = 128 * 1024 * 1024; // 128 MiB.
  81. ScryptTestVector test_data(GetParam());
  82. std::unique_ptr<crypto::SymmetricKey> key(
  83. crypto::SymmetricKey::DeriveKeyFromPasswordUsingScrypt(
  84. test_data.algorithm, test_data.password, test_data.salt,
  85. test_data.cost_parameter, test_data.block_size,
  86. test_data.parallelization_parameter, kScryptMaxMemoryBytes,
  87. test_data.key_size_in_bits));
  88. ASSERT_TRUE(key);
  89. const std::string& raw_key = key->key();
  90. EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size());
  91. EXPECT_EQ(test_data.expected, base::ToLowerASCII(base::HexEncode(
  92. raw_key.data(), raw_key.size())));
  93. }
  94. static const PBKDF2TestVector kTestVectorsPbkdf2[] = {
  95. // These tests come from
  96. // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt.
  97. {
  98. crypto::SymmetricKey::HMAC_SHA1, "password", "salt", 1, 160,
  99. "0c60c80f961f0e71f3a9b524af6012062fe037a6",
  100. },
  101. {
  102. crypto::SymmetricKey::HMAC_SHA1, "password", "salt", 2, 160,
  103. "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957",
  104. },
  105. {
  106. crypto::SymmetricKey::HMAC_SHA1, "password", "salt", 4096, 160,
  107. "4b007901b765489abead49d926f721d065a429c1",
  108. },
  109. // This test takes over 30s to run on the trybots.
  110. #if 0
  111. {
  112. crypto::SymmetricKey::HMAC_SHA1,
  113. "password",
  114. "salt",
  115. 16777216,
  116. 160,
  117. "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984",
  118. },
  119. #endif
  120. // These tests come from RFC 3962, via BSD source code at
  121. // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain.
  122. {
  123. crypto::SymmetricKey::HMAC_SHA1, "password", "ATHENA.MIT.EDUraeburn", 1,
  124. 160, "cdedb5281bb2f801565a1122b25635150ad1f7a0",
  125. },
  126. {
  127. crypto::SymmetricKey::HMAC_SHA1, "password", "ATHENA.MIT.EDUraeburn", 2,
  128. 160, "01dbee7f4a9e243e988b62c73cda935da05378b9",
  129. },
  130. {
  131. crypto::SymmetricKey::HMAC_SHA1, "password", "ATHENA.MIT.EDUraeburn",
  132. 1200, 160, "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb",
  133. },
  134. {
  135. crypto::SymmetricKey::HMAC_SHA1, "password",
  136. "\022"
  137. "4VxxV4\022", /* 0x1234567878563412 */
  138. 5, 160, "d1daa78615f287e6a1c8b120d7062a493f98d203",
  139. },
  140. {
  141. crypto::SymmetricKey::HMAC_SHA1,
  142. "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  143. "pass phrase equals block size", 1200, 160,
  144. "139c30c0966bc32ba55fdbf212530ac9c5ec59f1",
  145. },
  146. {
  147. crypto::SymmetricKey::HMAC_SHA1,
  148. "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  149. "pass phrase exceeds block size", 1200, 160,
  150. "9ccad6d468770cd51b10e6a68721be611a8b4d28",
  151. },
  152. {
  153. crypto::SymmetricKey::HMAC_SHA1,
  154. "\360\235\204\236", /* g-clef (0xf09d849e) */
  155. "EXAMPLE.COMpianist", 50, 160,
  156. "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0",
  157. },
  158. // Regression tests for AES keys, derived from the Linux NSS implementation.
  159. {
  160. crypto::SymmetricKey::AES, "A test password", "saltsalt", 1, 256,
  161. "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de",
  162. },
  163. {
  164. crypto::SymmetricKey::AES,
  165. "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  166. "pass phrase exceeds block size", 20, 256,
  167. "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c",
  168. },
  169. };
  170. static const ScryptTestVector kTestVectorsScrypt[] = {
  171. // From RFC 7914, "The scrypt Password-Based Key Derivation Function",
  172. // https://tools.ietf.org/html/rfc7914.html. The fourth test vector is
  173. // intentionally not used, as it would make the test significantly slower,
  174. // due to the very high cost parameter.
  175. {crypto::SymmetricKey::HMAC_SHA1, "", "", 16, 1, 1, 512,
  176. "77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069de"
  177. "d0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906"},
  178. {crypto::SymmetricKey::HMAC_SHA1, "password", "NaCl", 1024, 8, 16, 512,
  179. "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92"
  180. "e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640"},
  181. {crypto::SymmetricKey::HMAC_SHA1, "pleaseletmein", "SodiumChloride", 16384,
  182. 8, 1, 512,
  183. "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d54329556"
  184. "13f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887"}};
  185. INSTANTIATE_TEST_SUITE_P(All,
  186. SymmetricKeyDeriveKeyFromPasswordUsingPbkdf2Test,
  187. testing::ValuesIn(kTestVectorsPbkdf2));
  188. INSTANTIATE_TEST_SUITE_P(All,
  189. SymmetricKeyDeriveKeyFromPasswordUsingScryptTest,
  190. testing::ValuesIn(kTestVectorsScrypt));