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