Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / crypto / symmetric_key_unittest.cc
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
5 #include "crypto/symmetric_key.h"
6
7 #include <string>
8
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 TEST(SymmetricKeyTest, GenerateRandomKey) {
15   scoped_ptr<crypto::SymmetricKey> key(
16       crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
17   ASSERT_TRUE(NULL != key.get());
18   std::string raw_key;
19   EXPECT_TRUE(key->GetRawKey(&raw_key));
20   EXPECT_EQ(32U, raw_key.size());
21
22   // Do it again and check that the keys are different.
23   // (Note: this has a one-in-10^77 chance of failure!)
24   scoped_ptr<crypto::SymmetricKey> key2(
25       crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
26   ASSERT_TRUE(NULL != key2.get());
27   std::string raw_key2;
28   EXPECT_TRUE(key2->GetRawKey(&raw_key2));
29   EXPECT_EQ(32U, raw_key2.size());
30   EXPECT_NE(raw_key, raw_key2);
31 }
32
33 TEST(SymmetricKeyTest, ImportGeneratedKey) {
34   scoped_ptr<crypto::SymmetricKey> key1(
35       crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256));
36   ASSERT_TRUE(NULL != key1.get());
37   std::string raw_key1;
38   EXPECT_TRUE(key1->GetRawKey(&raw_key1));
39
40   scoped_ptr<crypto::SymmetricKey> key2(
41       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, raw_key1));
42   ASSERT_TRUE(NULL != key2.get());
43
44   std::string raw_key2;
45   EXPECT_TRUE(key2->GetRawKey(&raw_key2));
46
47   EXPECT_EQ(raw_key1, raw_key2);
48 }
49
50 TEST(SymmetricKeyTest, ImportDerivedKey) {
51   scoped_ptr<crypto::SymmetricKey> key1(
52       crypto::SymmetricKey::DeriveKeyFromPassword(
53           crypto::SymmetricKey::HMAC_SHA1, "password", "somesalt", 1024, 160));
54   ASSERT_TRUE(NULL != key1.get());
55   std::string raw_key1;
56   EXPECT_TRUE(key1->GetRawKey(&raw_key1));
57
58   scoped_ptr<crypto::SymmetricKey> key2(
59       crypto::SymmetricKey::Import(crypto::SymmetricKey::HMAC_SHA1, raw_key1));
60   ASSERT_TRUE(NULL != key2.get());
61
62   std::string raw_key2;
63   EXPECT_TRUE(key2->GetRawKey(&raw_key2));
64
65   EXPECT_EQ(raw_key1, raw_key2);
66 }
67
68 struct PBKDF2TestVector {
69   crypto::SymmetricKey::Algorithm algorithm;
70   const char* password;
71   const char* salt;
72   unsigned int rounds;
73   unsigned int key_size_in_bits;
74   const char* expected;  // ASCII encoded hex bytes
75 };
76
77 class SymmetricKeyDeriveKeyFromPasswordTest
78     : public testing::TestWithParam<PBKDF2TestVector> {
79 };
80
81 TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) {
82   PBKDF2TestVector test_data(GetParam());
83 #if defined(OS_MACOSX) && !defined(OS_IOS)
84   // The OS X crypto libraries have minimum salt and iteration requirements
85   // so some of the tests below will cause them to barf. Skip these.
86   if (strlen(test_data.salt) < 8 || test_data.rounds < 1000) {
87     VLOG(1) << "Skipped test vector for " << test_data.expected;
88     return;
89   }
90 #endif  // OS_MACOSX
91
92   scoped_ptr<crypto::SymmetricKey> key(
93       crypto::SymmetricKey::DeriveKeyFromPassword(
94           test_data.algorithm,
95           test_data.password, test_data.salt,
96           test_data.rounds, test_data.key_size_in_bits));
97   ASSERT_TRUE(NULL != key.get());
98
99   std::string raw_key;
100   key->GetRawKey(&raw_key);
101   EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size());
102   EXPECT_EQ(test_data.expected,
103             base::StringToLowerASCII(base::HexEncode(raw_key.data(),
104                                                raw_key.size())));
105 }
106
107 static const PBKDF2TestVector kTestVectors[] = {
108   // These tests come from
109   // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt
110   {
111     crypto::SymmetricKey::HMAC_SHA1,
112     "password",
113     "salt",
114     1,
115     160,
116     "0c60c80f961f0e71f3a9b524af6012062fe037a6",
117   },
118   {
119     crypto::SymmetricKey::HMAC_SHA1,
120     "password",
121     "salt",
122     2,
123     160,
124     "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957",
125   },
126   {
127     crypto::SymmetricKey::HMAC_SHA1,
128     "password",
129     "salt",
130     4096,
131     160,
132     "4b007901b765489abead49d926f721d065a429c1",
133   },
134   // This test takes over 30s to run on the trybots.
135 #if 0
136   {
137     crypto::SymmetricKey::HMAC_SHA1,
138     "password",
139     "salt",
140     16777216,
141     160,
142     "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984",
143   },
144 #endif
145
146   // These tests come from RFC 3962, via BSD source code at
147   // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain
148   {
149     crypto::SymmetricKey::HMAC_SHA1,
150     "password",
151     "ATHENA.MIT.EDUraeburn",
152     1,
153     160,
154     "cdedb5281bb2f801565a1122b25635150ad1f7a0",
155   },
156   {
157     crypto::SymmetricKey::HMAC_SHA1,
158     "password",
159     "ATHENA.MIT.EDUraeburn",
160     2,
161     160,
162     "01dbee7f4a9e243e988b62c73cda935da05378b9",
163   },
164   {
165     crypto::SymmetricKey::HMAC_SHA1,
166     "password",
167     "ATHENA.MIT.EDUraeburn",
168     1200,
169     160,
170     "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb",
171   },
172   {
173     crypto::SymmetricKey::HMAC_SHA1,
174     "password",
175     "\022" "4VxxV4\022", /* 0x1234567878563412 */
176     5,
177     160,
178     "d1daa78615f287e6a1c8b120d7062a493f98d203",
179   },
180   {
181     crypto::SymmetricKey::HMAC_SHA1,
182     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
183     "pass phrase equals block size",
184     1200,
185     160,
186     "139c30c0966bc32ba55fdbf212530ac9c5ec59f1",
187   },
188   {
189     crypto::SymmetricKey::HMAC_SHA1,
190     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
191     "pass phrase exceeds block size",
192     1200,
193     160,
194     "9ccad6d468770cd51b10e6a68721be611a8b4d28",
195   },
196   {
197     crypto::SymmetricKey::HMAC_SHA1,
198     "\360\235\204\236", /* g-clef (0xf09d849e) */
199     "EXAMPLE.COMpianist",
200     50,
201     160,
202     "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0",
203   },
204
205   // Regression tests for AES keys, derived from the Linux NSS implementation.
206   {
207     crypto::SymmetricKey::AES,
208     "A test password",
209     "saltsalt",
210     1,
211     256,
212     "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de",
213   },
214   {
215     crypto::SymmetricKey::AES,
216     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
217     "pass phrase exceeds block size",
218     20,
219     256,
220     "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c",
221   },
222 };
223
224 INSTANTIATE_TEST_CASE_P(, SymmetricKeyDeriveKeyFromPasswordTest,
225                         testing::ValuesIn(kTestVectors));