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 <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 14 TEST(SymmetricKeyTest, GenerateRandomKey) { 15 std::unique_ptr<crypto::SymmetricKey> key( 16 crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256)); 17 ASSERT_TRUE(key); 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 std::unique_ptr<crypto::SymmetricKey> key2( 25 crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256)); 26 ASSERT_TRUE(key2); 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 std::unique_ptr<crypto::SymmetricKey> key1( 35 crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256)); 36 ASSERT_TRUE(key1); 37 std::string raw_key1; 38 EXPECT_TRUE(key1->GetRawKey(&raw_key1)); 39 40 std::unique_ptr<crypto::SymmetricKey> key2( 41 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, raw_key1)); 42 ASSERT_TRUE(key2); 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 std::unique_ptr<crypto::SymmetricKey> key1( 52 crypto::SymmetricKey::DeriveKeyFromPassword( 53 crypto::SymmetricKey::HMAC_SHA1, "password", "somesalt", 1024, 160)); 54 ASSERT_TRUE(key1); 55 std::string raw_key1; 56 EXPECT_TRUE(key1->GetRawKey(&raw_key1)); 57 58 std::unique_ptr<crypto::SymmetricKey> key2( 59 crypto::SymmetricKey::Import(crypto::SymmetricKey::HMAC_SHA1, raw_key1)); 60 ASSERT_TRUE(key2); 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 std::unique_ptr<crypto::SymmetricKey> key( 84 crypto::SymmetricKey::DeriveKeyFromPassword( 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 std::string raw_key; 90 key->GetRawKey(&raw_key); 91 EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size()); 92 EXPECT_EQ(test_data.expected, 93 base::ToLowerASCII(base::HexEncode(raw_key.data(), 94 raw_key.size()))); 95 } 96 97 static const PBKDF2TestVector kTestVectors[] = { 98 // These tests come from 99 // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt 100 { 101 crypto::SymmetricKey::HMAC_SHA1, 102 "password", 103 "salt", 104 1, 105 160, 106 "0c60c80f961f0e71f3a9b524af6012062fe037a6", 107 }, 108 { 109 crypto::SymmetricKey::HMAC_SHA1, 110 "password", 111 "salt", 112 2, 113 160, 114 "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", 115 }, 116 { 117 crypto::SymmetricKey::HMAC_SHA1, 118 "password", 119 "salt", 120 4096, 121 160, 122 "4b007901b765489abead49d926f721d065a429c1", 123 }, 124 // This test takes over 30s to run on the trybots. 125 #if 0 126 { 127 crypto::SymmetricKey::HMAC_SHA1, 128 "password", 129 "salt", 130 16777216, 131 160, 132 "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", 133 }, 134 #endif 135 136 // These tests come from RFC 3962, via BSD source code at 137 // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain 138 { 139 crypto::SymmetricKey::HMAC_SHA1, 140 "password", 141 "ATHENA.MIT.EDUraeburn", 142 1, 143 160, 144 "cdedb5281bb2f801565a1122b25635150ad1f7a0", 145 }, 146 { 147 crypto::SymmetricKey::HMAC_SHA1, 148 "password", 149 "ATHENA.MIT.EDUraeburn", 150 2, 151 160, 152 "01dbee7f4a9e243e988b62c73cda935da05378b9", 153 }, 154 { 155 crypto::SymmetricKey::HMAC_SHA1, 156 "password", 157 "ATHENA.MIT.EDUraeburn", 158 1200, 159 160, 160 "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb", 161 }, 162 { 163 crypto::SymmetricKey::HMAC_SHA1, 164 "password", 165 "\022" "4VxxV4\022", /* 0x1234567878563412 */ 166 5, 167 160, 168 "d1daa78615f287e6a1c8b120d7062a493f98d203", 169 }, 170 { 171 crypto::SymmetricKey::HMAC_SHA1, 172 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 173 "pass phrase equals block size", 174 1200, 175 160, 176 "139c30c0966bc32ba55fdbf212530ac9c5ec59f1", 177 }, 178 { 179 crypto::SymmetricKey::HMAC_SHA1, 180 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 181 "pass phrase exceeds block size", 182 1200, 183 160, 184 "9ccad6d468770cd51b10e6a68721be611a8b4d28", 185 }, 186 { 187 crypto::SymmetricKey::HMAC_SHA1, 188 "\360\235\204\236", /* g-clef (0xf09d849e) */ 189 "EXAMPLE.COMpianist", 190 50, 191 160, 192 "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0", 193 }, 194 195 // Regression tests for AES keys, derived from the Linux NSS implementation. 196 { 197 crypto::SymmetricKey::AES, 198 "A test password", 199 "saltsalt", 200 1, 201 256, 202 "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de", 203 }, 204 { 205 crypto::SymmetricKey::AES, 206 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 207 "pass phrase exceeds block size", 208 20, 209 256, 210 "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c", 211 }, 212 }; 213 214 INSTANTIATE_TEST_CASE_P(, SymmetricKeyDeriveKeyFromPasswordTest, 215 testing::ValuesIn(kTestVectors)); 216