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