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 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 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 41 TEST(SymmetricKeyTest, ImportDerivedKey) { 42 std::unique_ptr<crypto::SymmetricKey> key1( 43 crypto::SymmetricKey::DeriveKeyFromPassword( 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 class SymmetricKeyDeriveKeyFromPasswordTest 64 : public testing::TestWithParam<PBKDF2TestVector> { 65 }; 66 67 TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) { 68 PBKDF2TestVector test_data(GetParam()); 69 std::unique_ptr<crypto::SymmetricKey> key( 70 crypto::SymmetricKey::DeriveKeyFromPassword( 71 test_data.algorithm, test_data.password, test_data.salt, 72 test_data.rounds, test_data.key_size_in_bits)); 73 ASSERT_TRUE(key); 74 75 const std::string& raw_key = key->key(); 76 EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size()); 77 EXPECT_EQ(test_data.expected, 78 base::ToLowerASCII(base::HexEncode(raw_key.data(), 79 raw_key.size()))); 80 } 81 82 static const PBKDF2TestVector kTestVectors[] = { 83 // These tests come from 84 // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt 85 { 86 crypto::SymmetricKey::HMAC_SHA1, 87 "password", 88 "salt", 89 1, 90 160, 91 "0c60c80f961f0e71f3a9b524af6012062fe037a6", 92 }, 93 { 94 crypto::SymmetricKey::HMAC_SHA1, 95 "password", 96 "salt", 97 2, 98 160, 99 "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", 100 }, 101 { 102 crypto::SymmetricKey::HMAC_SHA1, 103 "password", 104 "salt", 105 4096, 106 160, 107 "4b007901b765489abead49d926f721d065a429c1", 108 }, 109 // This test takes over 30s to run on the trybots. 110 #if 0 111 { 112 crypto::SymmetricKey::HMAC_SHA1, 113 "password", 114 "salt", 115 16777216, 116 160, 117 "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", 118 }, 119 #endif 120 121 // These tests come from RFC 3962, via BSD source code at 122 // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain 123 { 124 crypto::SymmetricKey::HMAC_SHA1, 125 "password", 126 "ATHENA.MIT.EDUraeburn", 127 1, 128 160, 129 "cdedb5281bb2f801565a1122b25635150ad1f7a0", 130 }, 131 { 132 crypto::SymmetricKey::HMAC_SHA1, 133 "password", 134 "ATHENA.MIT.EDUraeburn", 135 2, 136 160, 137 "01dbee7f4a9e243e988b62c73cda935da05378b9", 138 }, 139 { 140 crypto::SymmetricKey::HMAC_SHA1, 141 "password", 142 "ATHENA.MIT.EDUraeburn", 143 1200, 144 160, 145 "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb", 146 }, 147 { 148 crypto::SymmetricKey::HMAC_SHA1, 149 "password", 150 "\022" "4VxxV4\022", /* 0x1234567878563412 */ 151 5, 152 160, 153 "d1daa78615f287e6a1c8b120d7062a493f98d203", 154 }, 155 { 156 crypto::SymmetricKey::HMAC_SHA1, 157 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 158 "pass phrase equals block size", 159 1200, 160 160, 161 "139c30c0966bc32ba55fdbf212530ac9c5ec59f1", 162 }, 163 { 164 crypto::SymmetricKey::HMAC_SHA1, 165 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 166 "pass phrase exceeds block size", 167 1200, 168 160, 169 "9ccad6d468770cd51b10e6a68721be611a8b4d28", 170 }, 171 { 172 crypto::SymmetricKey::HMAC_SHA1, 173 "\360\235\204\236", /* g-clef (0xf09d849e) */ 174 "EXAMPLE.COMpianist", 175 50, 176 160, 177 "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0", 178 }, 179 180 // Regression tests for AES keys, derived from the Linux NSS implementation. 181 { 182 crypto::SymmetricKey::AES, 183 "A test password", 184 "saltsalt", 185 1, 186 256, 187 "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de", 188 }, 189 { 190 crypto::SymmetricKey::AES, 191 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 192 "pass phrase exceeds block size", 193 20, 194 256, 195 "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c", 196 }, 197 }; 198 199 INSTANTIATE_TEST_CASE_P(, SymmetricKeyDeriveKeyFromPasswordTest, 200 testing::ValuesIn(kTestVectors)); 201