1 // Copyright (c) 2010 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.
5 #include "base/crypto/symmetric_key.h"
9 #include "base/scoped_ptr.h"
10 #include "base/string_util.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 TEST(SymmetricKeyTest
, GenerateRandomKey
) {
14 scoped_ptr
<base::SymmetricKey
> key(
15 base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES
, 256));
16 ASSERT_TRUE(NULL
!= key
.get());
18 EXPECT_TRUE(key
->GetRawKey(&raw_key
));
19 EXPECT_EQ(32U, raw_key
.size());
21 // Do it again and check that the keys are different.
22 // (Note: this has a one-in-10^77 chance of failure!)
23 scoped_ptr
<base::SymmetricKey
> key2(
24 base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES
, 256));
25 ASSERT_TRUE(NULL
!= key2
.get());
27 EXPECT_TRUE(key2
->GetRawKey(&raw_key2
));
28 EXPECT_EQ(32U, raw_key2
.size());
29 EXPECT_NE(raw_key
, raw_key2
);
32 // TODO(albertb): Port this test to Mac.
33 #if defined(USE_NSS) || defined(OS_WIN)
34 TEST(SymmetricKeyTest
, ImportGeneratedKey
) {
35 scoped_ptr
<base::SymmetricKey
> key1(
36 base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES
, 256));
37 ASSERT_TRUE(NULL
!= key1
.get());
39 EXPECT_TRUE(key1
->GetRawKey(&raw_key1
));
41 scoped_ptr
<base::SymmetricKey
> key2(
42 base::SymmetricKey::Import(base::SymmetricKey::AES
, raw_key1
));
43 ASSERT_TRUE(NULL
!= key2
.get());
46 EXPECT_TRUE(key2
->GetRawKey(&raw_key2
));
48 EXPECT_EQ(raw_key1
, raw_key2
);
50 #endif // USE_NSS || OS_WIN
52 // TODO(albertb): Port this test to Win and Mac.
54 TEST(SymmetricKeyTest
, ImportDerivedKey
) {
55 scoped_ptr
<base::SymmetricKey
> key1(
56 base::SymmetricKey::DeriveKeyFromPassword(base::SymmetricKey::HMAC_SHA1
,
57 "password", "salt", 1024, 160));
58 ASSERT_TRUE(NULL
!= key1
.get());
60 EXPECT_TRUE(key1
->GetRawKey(&raw_key1
));
62 scoped_ptr
<base::SymmetricKey
> key2(
63 base::SymmetricKey::Import(base::SymmetricKey::HMAC_SHA1
, raw_key1
));
64 ASSERT_TRUE(NULL
!= key2
.get());
67 EXPECT_TRUE(key2
->GetRawKey(&raw_key2
));
69 EXPECT_EQ(raw_key1
, raw_key2
);
73 struct PBKDF2TestVector
{
77 unsigned int key_size_in_bits
;
78 const uint8 expected
[21]; // string literals need 1 extra NUL byte
81 static const PBKDF2TestVector test_vectors
[] = {
82 // These tests come from
83 // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt
89 "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
90 "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6",
97 "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
98 "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57",
105 "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
106 "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1",
108 // This test takes over 30s to run on the trybots.
115 "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
116 "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84",
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
124 "ATHENA.MIT.EDUraeburn",
128 0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01,
129 0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15,
130 0x0a, 0xd1, 0xf7, 0xa0
135 "ATHENA.MIT.EDUraeburn",
139 0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e,
140 0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d,
141 0xa0, 0x53, 0x78, 0xb9
146 "ATHENA.MIT.EDUraeburn",
150 0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e,
151 0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b,
152 0xa7, 0xe5, 0x2d, 0xdb
157 "\0224VxxV4\022", /* 0x1234567878563412 */
161 0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,
162 0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49,
163 0x3f, 0x98, 0xd2, 0x03
167 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
168 "pass phrase equals block size",
172 0x13, 0x9c, 0x30, 0xc0, 0x96, 0x6b, 0xc3, 0x2b,
173 0xa5, 0x5f, 0xdb, 0xf2, 0x12, 0x53, 0x0a, 0xc9,
174 0xc5, 0xec, 0x59, 0xf1
178 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
179 "pass phrase exceeds block size",
183 0x9c, 0xca, 0xd6, 0xd4, 0x68, 0x77, 0x0c, 0xd5,
184 0x1b, 0x10, 0xe6, 0xa6, 0x87, 0x21, 0xbe, 0x61,
185 0x1a, 0x8b, 0x4d, 0x28
189 "\360\235\204\236", /* g-clef (0xf09d849e) */
190 "EXAMPLE.COMpianist",
194 0x6b, 0x9c, 0xf2, 0x6d, 0x45, 0x45, 0x5a, 0x43,
195 0xa5, 0xb8, 0xbb, 0x27, 0x6a, 0x40, 0x3b, 0x39,
196 0xe7, 0xfe, 0x37, 0xa0
201 TEST(SymmetricKeyTest
, DeriveKeyFromPassword
) {
202 for (unsigned int i
= 0; i
< ARRAYSIZE_UNSAFE(test_vectors
); ++i
) {
203 SCOPED_TRACE(StringPrintf("Test[%u]", i
));
204 #if defined(OS_MACOSX)
205 // The OS X crypto libraries have minimum salt and iteration requirements
206 // so some of the above tests will cause them to barf. Skip these.
207 if (strlen(test_vectors
[i
].salt
) < 8 || test_vectors
[i
].rounds
< 1000) {
208 LOG(INFO
) << "Skipped test vector #" << i
;
212 scoped_ptr
<base::SymmetricKey
> key(
213 base::SymmetricKey::DeriveKeyFromPassword(
214 base::SymmetricKey::HMAC_SHA1
,
215 test_vectors
[i
].password
, test_vectors
[i
].salt
,
216 test_vectors
[i
].rounds
, test_vectors
[i
].key_size_in_bits
));
217 ASSERT_TRUE(NULL
!= key
.get());
220 key
->GetRawKey(&raw_key
);
221 EXPECT_EQ(test_vectors
[i
].key_size_in_bits
/ 8, raw_key
.size());
222 EXPECT_EQ(0, memcmp(test_vectors
[i
].expected
,