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