| OLD | NEW |
| (Empty) |
| 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 <string> | |
| 6 | |
| 7 #include "crypto/hmac.h" | |
| 8 #include "testing/gtest/include/gtest/gtest.h" | |
| 9 | |
| 10 static const size_t kSHA1DigestSize = 20; | |
| 11 static const size_t kSHA256DigestSize = 32; | |
| 12 | |
| 13 static const char* kSimpleKey = | |
| 14 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 15 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 16 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 17 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 18 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"; | |
| 19 static const size_t kSimpleKeyLength = 80; | |
| 20 | |
| 21 static const struct { | |
| 22 const char *data; | |
| 23 const int data_len; | |
| 24 const char *digest; | |
| 25 } kSimpleHmacCases[] = { | |
| 26 { "Test Using Larger Than Block-Size Key - Hash Key First", 54, | |
| 27 "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55" | |
| 28 "\xED\x40\x21\x12" }, | |
| 29 { "Test Using Larger Than Block-Size Key and Larger " | |
| 30 "Than One Block-Size Data", 73, | |
| 31 "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08" | |
| 32 "\xBB\xFF\x1A\x91" } | |
| 33 }; | |
| 34 | |
| 35 TEST(HMACTest, HmacSafeBrowsingResponseTest) { | |
| 36 const int kKeySize = 16; | |
| 37 | |
| 38 // Client key. | |
| 39 const unsigned char kClientKey[kKeySize] = | |
| 40 { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd, | |
| 41 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 }; | |
| 42 | |
| 43 // Expected HMAC result using kMessage and kClientKey. | |
| 44 const unsigned char kReceivedHmac[kSHA1DigestSize] = | |
| 45 { 0xb9, 0x3c, 0xd6, 0xf0, 0x49, 0x47, 0xe2, 0x52, | |
| 46 0x59, 0x7a, 0xbd, 0x1f, 0x2b, 0x4c, 0x83, 0xad, | |
| 47 0x86, 0xd2, 0x48, 0x85 }; | |
| 48 | |
| 49 const char kMessage[] = | |
| 50 "n:1896\ni:goog-malware-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav" | |
| 51 "ar_s_445-450\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_439-444\nu:s" | |
| 52 ".ytimg.com/safebrowsing/rd/goog-malware-shavar_s_437\nu:s.ytimg.com/safebrowsi" | |
| 53 "ng/rd/goog-malware-shavar_s_436\nu:s.ytimg.com/safebrowsing/rd/goog-malware-sh" | |
| 54 "avar_s_433-435\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_431\nu:s.y" | |
| 55 "timg.com/safebrowsing/rd/goog-malware-shavar_s_430\nu:s.ytimg.com/safebrowsing" | |
| 56 "/rd/goog-malware-shavar_s_429\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav" | |
| 57 "ar_s_428\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_426\nu:s.ytimg.c" | |
| 58 "om/safebrowsing/rd/goog-malware-shavar_s_424\nu:s.ytimg.com/safebrowsing/rd/go" | |
| 59 "og-malware-shavar_s_423\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_4" | |
| 60 "22\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_420\nu:s.ytimg.com/saf" | |
| 61 "ebrowsing/rd/goog-malware-shavar_s_419\nu:s.ytimg.com/safebrowsing/rd/goog-mal" | |
| 62 "ware-shavar_s_414\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_409-411" | |
| 63 "\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_405\nu:s.ytimg.com/safeb" | |
| 64 "rowsing/rd/goog-malware-shavar_s_404\nu:s.ytimg.com/safebrowsing/rd/goog-malwa" | |
| 65 "re-shavar_s_402\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_401\nu:s." | |
| 66 "ytimg.com/safebrowsing/rd/goog-malware-shavar_a_973-978\nu:s.ytimg.com/safebro" | |
| 67 "wsing/rd/goog-malware-shavar_a_937-972\nu:s.ytimg.com/safebrowsing/rd/goog-mal" | |
| 68 "ware-shavar_a_931-936\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_925" | |
| 69 "-930\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_919-924\ni:goog-phis" | |
| 70 "h-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2633\nu:s.ytimg.co" | |
| 71 "m/safebrowsing/rd/goog-phish-shavar_a_2632\nu:s.ytimg.com/safebrowsing/rd/goog" | |
| 72 "-phish-shavar_a_2629-2631\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2" | |
| 73 "626-2628\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2625\n"; | |
| 74 | |
| 75 std::string message_data(kMessage); | |
| 76 | |
| 77 crypto::HMAC hmac(crypto::HMAC::SHA1); | |
| 78 ASSERT_TRUE(hmac.Init(kClientKey, kKeySize)); | |
| 79 unsigned char calculated_hmac[kSHA1DigestSize]; | |
| 80 | |
| 81 EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize)); | |
| 82 EXPECT_EQ(0, memcmp(kReceivedHmac, calculated_hmac, kSHA1DigestSize)); | |
| 83 } | |
| 84 | |
| 85 // Test cases from RFC 2202 section 3 | |
| 86 TEST(HMACTest, RFC2202TestCases) { | |
| 87 const struct { | |
| 88 const char *key; | |
| 89 const int key_len; | |
| 90 const char *data; | |
| 91 const int data_len; | |
| 92 const char *digest; | |
| 93 } cases[] = { | |
| 94 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" | |
| 95 "\x0B\x0B\x0B\x0B", 20, | |
| 96 "Hi There", 8, | |
| 97 "\xB6\x17\x31\x86\x55\x05\x72\x64\xE2\x8B\xC0\xB6\xFB\x37\x8C\x8E" | |
| 98 "\xF1\x46\xBE\x00" }, | |
| 99 { "Jefe", 4, | |
| 100 "what do ya want for nothing?", 28, | |
| 101 "\xEF\xFC\xDF\x6A\xE5\xEB\x2F\xA2\xD2\x74\x16\xD5\xF1\x84\xDF\x9C" | |
| 102 "\x25\x9A\x7C\x79" }, | |
| 103 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 104 "\xAA\xAA\xAA\xAA", 20, | |
| 105 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" | |
| 106 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" | |
| 107 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" | |
| 108 "\xDD\xDD", 50, | |
| 109 "\x12\x5D\x73\x42\xB9\xAC\x11\xCD\x91\xA3\x9A\xF4\x8A\xA1\x7B\x4F" | |
| 110 "\x63\xF1\x75\xD3" }, | |
| 111 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" | |
| 112 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25, | |
| 113 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" | |
| 114 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" | |
| 115 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" | |
| 116 "\xCD\xCD", 50, | |
| 117 "\x4C\x90\x07\xF4\x02\x62\x50\xC6\xBC\x84\x14\xF9\xBF\x50\xC8\x6C" | |
| 118 "\x2D\x72\x35\xDA" }, | |
| 119 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" | |
| 120 "\x0C\x0C\x0C\x0C", 20, | |
| 121 "Test With Truncation", 20, | |
| 122 "\x4C\x1A\x03\x42\x4B\x55\xE0\x7F\xE7\xF2\x7B\xE1\xD5\x8B\xB9\x32" | |
| 123 "\x4A\x9A\x5A\x04" }, | |
| 124 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 125 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 126 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 127 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 128 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", | |
| 129 80, | |
| 130 "Test Using Larger Than Block-Size Key - Hash Key First", 54, | |
| 131 "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55" | |
| 132 "\xED\x40\x21\x12" }, | |
| 133 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 134 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 135 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 136 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" | |
| 137 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", | |
| 138 80, | |
| 139 "Test Using Larger Than Block-Size Key and Larger " | |
| 140 "Than One Block-Size Data", 73, | |
| 141 "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08" | |
| 142 "\xBB\xFF\x1A\x91" } | |
| 143 }; | |
| 144 | |
| 145 for (size_t i = 0; i < arraysize(cases); ++i) { | |
| 146 crypto::HMAC hmac(crypto::HMAC::SHA1); | |
| 147 ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key), | |
| 148 cases[i].key_len)); | |
| 149 std::string data_string(cases[i].data, cases[i].data_len); | |
| 150 unsigned char digest[kSHA1DigestSize]; | |
| 151 EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize)); | |
| 152 EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize)); | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 // TODO(wtc): add other test vectors from RFC 4231. | |
| 157 TEST(HMACTest, RFC4231TestCase6) { | |
| 158 unsigned char key[131]; | |
| 159 for (size_t i = 0; i < sizeof(key); ++i) | |
| 160 key[i] = 0xaa; | |
| 161 | |
| 162 std::string data = "Test Using Larger Than Block-Size Key - Hash Key First"; | |
| 163 ASSERT_EQ(54U, data.size()); | |
| 164 | |
| 165 static unsigned char kKnownHMACSHA256[] = { | |
| 166 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, | |
| 167 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, | |
| 168 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, | |
| 169 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 | |
| 170 }; | |
| 171 | |
| 172 crypto::HMAC hmac(crypto::HMAC::SHA256); | |
| 173 ASSERT_TRUE(hmac.Init(key, sizeof(key))); | |
| 174 unsigned char calculated_hmac[kSHA256DigestSize]; | |
| 175 | |
| 176 EXPECT_EQ(kSHA256DigestSize, hmac.DigestLength()); | |
| 177 EXPECT_TRUE(hmac.Sign(data, calculated_hmac, kSHA256DigestSize)); | |
| 178 EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac, kSHA256DigestSize)); | |
| 179 } | |
| 180 | |
| 181 // Based on NSS's FIPS HMAC power-up self-test. | |
| 182 TEST(HMACTest, NSSFIPSPowerUpSelfTest) { | |
| 183 static const char kKnownMessage[] = | |
| 184 "The test message for the MD2, MD5, and SHA-1 hashing algorithms."; | |
| 185 | |
| 186 static const unsigned char kKnownSecretKey[] = { | |
| 187 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x20, | |
| 188 0x61, 0x6e, 0x64, 0x20, 0x54, 0x68, 0x75, 0x6e, | |
| 189 0x64, 0x65, 0x72, 0x42, 0x69, 0x72, 0x64, 0x20, | |
| 190 0x61, 0x72, 0x65, 0x20, 0x61, 0x77, 0x65, 0x73, | |
| 191 0x6f, 0x6d, 0x65, 0x21, 0x00 | |
| 192 }; | |
| 193 | |
| 194 static const size_t kKnownSecretKeySize = sizeof(kKnownSecretKey); | |
| 195 | |
| 196 // HMAC-SHA-1 known answer (20 bytes). | |
| 197 static const unsigned char kKnownHMACSHA1[] = { | |
| 198 0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05, | |
| 199 0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e, | |
| 200 0x5d, 0x0e, 0x1e, 0x11 | |
| 201 }; | |
| 202 | |
| 203 // HMAC-SHA-256 known answer (32 bytes). | |
| 204 static const unsigned char kKnownHMACSHA256[] = { | |
| 205 0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44, | |
| 206 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0, | |
| 207 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9, | |
| 208 0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48 | |
| 209 }; | |
| 210 | |
| 211 std::string message_data(kKnownMessage); | |
| 212 | |
| 213 crypto::HMAC hmac(crypto::HMAC::SHA1); | |
| 214 ASSERT_TRUE(hmac.Init(kKnownSecretKey, kKnownSecretKeySize)); | |
| 215 unsigned char calculated_hmac[kSHA1DigestSize]; | |
| 216 | |
| 217 EXPECT_EQ(kSHA1DigestSize, hmac.DigestLength()); | |
| 218 EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize)); | |
| 219 EXPECT_EQ(0, memcmp(kKnownHMACSHA1, calculated_hmac, kSHA1DigestSize)); | |
| 220 EXPECT_TRUE(hmac.Verify( | |
| 221 message_data, | |
| 222 base::StringPiece(reinterpret_cast<const char*>(kKnownHMACSHA1), | |
| 223 kSHA1DigestSize))); | |
| 224 EXPECT_TRUE(hmac.VerifyTruncated( | |
| 225 message_data, | |
| 226 base::StringPiece(reinterpret_cast<const char*>(kKnownHMACSHA1), | |
| 227 kSHA1DigestSize / 2))); | |
| 228 | |
| 229 crypto::HMAC hmac2(crypto::HMAC::SHA256); | |
| 230 ASSERT_TRUE(hmac2.Init(kKnownSecretKey, kKnownSecretKeySize)); | |
| 231 unsigned char calculated_hmac2[kSHA256DigestSize]; | |
| 232 | |
| 233 EXPECT_TRUE(hmac2.Sign(message_data, calculated_hmac2, kSHA256DigestSize)); | |
| 234 EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac2, kSHA256DigestSize)); | |
| 235 } | |
| 236 | |
| 237 TEST(HMACTest, HMACObjectReuse) { | |
| 238 crypto::HMAC hmac(crypto::HMAC::SHA1); | |
| 239 ASSERT_TRUE( | |
| 240 hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey), | |
| 241 kSimpleKeyLength)); | |
| 242 for (size_t i = 0; i < arraysize(kSimpleHmacCases); ++i) { | |
| 243 std::string data_string(kSimpleHmacCases[i].data, | |
| 244 kSimpleHmacCases[i].data_len); | |
| 245 unsigned char digest[kSHA1DigestSize]; | |
| 246 EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize)); | |
| 247 EXPECT_EQ(0, memcmp(kSimpleHmacCases[i].digest, digest, kSHA1DigestSize)); | |
| 248 } | |
| 249 } | |
| 250 | |
| 251 TEST(HMACTest, Verify) { | |
| 252 crypto::HMAC hmac(crypto::HMAC::SHA1); | |
| 253 ASSERT_TRUE( | |
| 254 hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey), | |
| 255 kSimpleKeyLength)); | |
| 256 const char empty_digest[kSHA1DigestSize] = { 0 }; | |
| 257 for (size_t i = 0; i < arraysize(kSimpleHmacCases); ++i) { | |
| 258 // Expected results | |
| 259 EXPECT_TRUE(hmac.Verify( | |
| 260 base::StringPiece(kSimpleHmacCases[i].data, | |
| 261 kSimpleHmacCases[i].data_len), | |
| 262 base::StringPiece(kSimpleHmacCases[i].digest, | |
| 263 kSHA1DigestSize))); | |
| 264 // Mismatched size | |
| 265 EXPECT_FALSE(hmac.Verify( | |
| 266 base::StringPiece(kSimpleHmacCases[i].data, | |
| 267 kSimpleHmacCases[i].data_len), | |
| 268 base::StringPiece(kSimpleHmacCases[i].data, | |
| 269 kSimpleHmacCases[i].data_len))); | |
| 270 | |
| 271 // Expected size, mismatched data | |
| 272 EXPECT_FALSE(hmac.Verify( | |
| 273 base::StringPiece(kSimpleHmacCases[i].data, | |
| 274 kSimpleHmacCases[i].data_len), | |
| 275 base::StringPiece(empty_digest, kSHA1DigestSize))); | |
| 276 } | |
| 277 } | |
| 278 | |
| 279 TEST(HMACTest, EmptyKey) { | |
| 280 // Test vector from https://en.wikipedia.org/wiki/HMAC | |
| 281 const char* kExpectedDigest = | |
| 282 "\xFB\xDB\x1D\x1B\x18\xAA\x6C\x08\x32\x4B\x7D\x64\xB7\x1F\xB7\x63" | |
| 283 "\x70\x69\x0E\x1D"; | |
| 284 base::StringPiece data(""); | |
| 285 | |
| 286 crypto::HMAC hmac(crypto::HMAC::SHA1); | |
| 287 ASSERT_TRUE(hmac.Init(NULL, 0)); | |
| 288 | |
| 289 unsigned char digest[kSHA1DigestSize]; | |
| 290 EXPECT_TRUE(hmac.Sign(data, digest, kSHA1DigestSize)); | |
| 291 EXPECT_EQ(0, memcmp(kExpectedDigest, digest, kSHA1DigestSize)); | |
| 292 | |
| 293 EXPECT_TRUE(hmac.Verify( | |
| 294 data, base::StringPiece(kExpectedDigest, kSHA1DigestSize))); | |
| 295 } | |
| OLD | NEW |