blob: f0844a9186c9d661273483266408dcb9b2e1a3c1 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
10static const size_t kSHA1DigestSize = 20;
11static const size_t kSHA256DigestSize = 32;
12
13static 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";
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000019static const size_t kSimpleKeyLength = 80;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000020
21static 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
35TEST(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
86TEST(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_UNSAFE(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.
157TEST(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.
182TEST(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
237TEST(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_UNSAFE(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
251TEST(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_UNSAFE(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}