Enable cc_perftests on Mac perf bots.
[chromium-blink-merge.git] / crypto / hmac_unittest.cc
blob91eccd68e231d4cc712624678681d69c3b0b1dfd
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.
5 #include <string>
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;
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" }
35 TEST(HMACTest, HmacSafeBrowsingResponseTest) {
36 const int kKeySize = 16;
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 };
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) {
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",
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"
142 "\xBB\xFF\x1A\x91" }
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));
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;
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(
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)));
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);
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));
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)));
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"
283 "\x70\x69\x0E\x1D";
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)));