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.
7 #include "crypto/hmac.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 static const size_t kSHA1DigestSize
= 20;
11 static const size_t kSHA256DigestSize
= 32;
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;
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"
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"
35 TEST(HMACTest
, HmacSafeBrowsingResponseTest
) {
36 const int kKeySize
= 16;
39 const unsigned char kClientKey
[kKeySize
] =
40 { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
41 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
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 };
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";
75 std::string
message_data(kMessage
);
77 crypto::HMAC
hmac(crypto::HMAC::SHA1
);
78 ASSERT_TRUE(hmac
.Init(kClientKey
, kKeySize
));
79 unsigned char calculated_hmac
[kSHA1DigestSize
];
81 EXPECT_TRUE(hmac
.Sign(message_data
, calculated_hmac
, kSHA1DigestSize
));
82 EXPECT_EQ(0, memcmp(kReceivedHmac
, calculated_hmac
, kSHA1DigestSize
));
85 // Test cases from RFC 2202 section 3
86 TEST(HMACTest
, RFC2202TestCases
) {
94 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
95 "\x0B\x0B\x0B\x0B", 20,
97 "\xB6\x17\x31\x86\x55\x05\x72\x64\xE2\x8B\xC0\xB6\xFB\x37\x8C\x8E"
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"
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"
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",
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",
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"
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
),
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
));
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
)
162 std::string data
= "Test Using Larger Than Block-Size Key - Hash Key First";
163 ASSERT_EQ(54U, data
.size());
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
172 crypto::HMAC
hmac(crypto::HMAC::SHA256
);
173 ASSERT_TRUE(hmac
.Init(key
, sizeof(key
)));
174 unsigned char calculated_hmac
[kSHA256DigestSize
];
176 EXPECT_EQ(kSHA256DigestSize
, hmac
.DigestLength());
177 EXPECT_TRUE(hmac
.Sign(data
, calculated_hmac
, kSHA256DigestSize
));
178 EXPECT_EQ(0, memcmp(kKnownHMACSHA256
, calculated_hmac
, kSHA256DigestSize
));
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.";
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
194 static const size_t kKnownSecretKeySize
= sizeof(kKnownSecretKey
);
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
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
211 std::string
message_data(kKnownMessage
);
213 crypto::HMAC
hmac(crypto::HMAC::SHA1
);
214 ASSERT_TRUE(hmac
.Init(kKnownSecretKey
, kKnownSecretKeySize
));
215 unsigned char calculated_hmac
[kSHA1DigestSize
];
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(
222 base::StringPiece(reinterpret_cast<const char*>(kKnownHMACSHA1
),
224 EXPECT_TRUE(hmac
.VerifyTruncated(
226 base::StringPiece(reinterpret_cast<const char*>(kKnownHMACSHA1
),
227 kSHA1DigestSize
/ 2)));
229 crypto::HMAC
hmac2(crypto::HMAC::SHA256
);
230 ASSERT_TRUE(hmac2
.Init(kKnownSecretKey
, kKnownSecretKeySize
));
231 unsigned char calculated_hmac2
[kSHA256DigestSize
];
233 EXPECT_TRUE(hmac2
.Sign(message_data
, calculated_hmac2
, kSHA256DigestSize
));
234 EXPECT_EQ(0, memcmp(kKnownHMACSHA256
, calculated_hmac2
, kSHA256DigestSize
));
237 TEST(HMACTest
, HMACObjectReuse
) {
238 crypto::HMAC
hmac(crypto::HMAC::SHA1
);
240 hmac
.Init(reinterpret_cast<const unsigned char*>(kSimpleKey
),
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
));
251 TEST(HMACTest
, Verify
) {
252 crypto::HMAC
hmac(crypto::HMAC::SHA1
);
254 hmac
.Init(reinterpret_cast<const unsigned char*>(kSimpleKey
),
256 const char empty_digest
[kSHA1DigestSize
] = { 0 };
257 for (size_t i
= 0; i
< arraysize(kSimpleHmacCases
); ++i
) {
259 EXPECT_TRUE(hmac
.Verify(
260 base::StringPiece(kSimpleHmacCases
[i
].data
,
261 kSimpleHmacCases
[i
].data_len
),
262 base::StringPiece(kSimpleHmacCases
[i
].digest
,
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
)));
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
)));
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"
284 base::StringPiece
data("");
286 crypto::HMAC
hmac(crypto::HMAC::SHA1
);
287 ASSERT_TRUE(hmac
.Init(NULL
, 0));
289 unsigned char digest
[kSHA1DigestSize
];
290 EXPECT_TRUE(hmac
.Sign(data
, digest
, kSHA1DigestSize
));
291 EXPECT_EQ(0, memcmp(kExpectedDigest
, digest
, kSHA1DigestSize
));
293 EXPECT_TRUE(hmac
.Verify(
294 data
, base::StringPiece(kExpectedDigest
, kSHA1DigestSize
)));