blob: 6bcd1bc2e3a4dda86406c0b6d3620d587126428c [file] [log] [blame]
[email protected]4b559b4d2011-04-14 17:37:141// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
5#include <string>
6
[email protected]4b559b4d2011-04-14 17:37:147#include "crypto/hmac.h"
[email protected]6bc9ad9d2008-08-29 12:24:068#include "testing/gtest/include/gtest/gtest.h"
initial.commitd7cae122008-07-26 21:49:389
[email protected]a5aec2e2011-04-30 18:55:1810static const size_t kSHA1DigestSize = 20;
11static const size_t kSHA256DigestSize = 32;
initial.commitd7cae122008-07-26 21:49:3812
[email protected]3292f532011-07-18 00:39:4413static 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";
[email protected]673266c42012-12-04 00:50:3519static const size_t kSimpleKeyLength = 80;
[email protected]3292f532011-07-18 00:39:4420
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
[email protected]301415e2008-09-04 19:00:3735TEST(HMACTest, HmacSafeBrowsingResponseTest) {
36 const int kKeySize = 16;
initial.commitd7cae122008-07-26 21:49:3837
[email protected]301415e2008-09-04 19:00:3738 // 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 };
initial.commitd7cae122008-07-26 21:49:3842
[email protected]301415e2008-09-04 19:00:3743 // Expected HMAC result using kMessage and kClientKey.
[email protected]db163f82010-04-02 21:01:3544 const unsigned char kReceivedHmac[kSHA1DigestSize] =
[email protected]301415e2008-09-04 19:00:3745 { 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[] =
initial.commitd7cae122008-07-26 21:49:3850"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
initial.commitd7cae122008-07-26 21:49:3875 std::string message_data(kMessage);
76
[email protected]4b559b4d2011-04-14 17:37:1477 crypto::HMAC hmac(crypto::HMAC::SHA1);
[email protected]d91f8432009-05-05 23:55:5978 ASSERT_TRUE(hmac.Init(kClientKey, kKeySize));
[email protected]db163f82010-04-02 21:01:3579 unsigned char calculated_hmac[kSHA1DigestSize];
initial.commitd7cae122008-07-26 21:49:3880
[email protected]db163f82010-04-02 21:01:3581 EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
82 EXPECT_EQ(0, memcmp(kReceivedHmac, calculated_hmac, kSHA1DigestSize));
initial.commitd7cae122008-07-26 21:49:3883}
[email protected]301415e2008-09-04 19:00:3784
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) {
[email protected]4b559b4d2011-04-14 17:37:14146 crypto::HMAC hmac(crypto::HMAC::SHA1);
[email protected]d91f8432009-05-05 23:55:59147 ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key),
148 cases[i].key_len));
[email protected]301415e2008-09-04 19:00:37149 std::string data_string(cases[i].data, cases[i].data_len);
[email protected]db163f82010-04-02 21:01:35150 unsigned char digest[kSHA1DigestSize];
151 EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
152 EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize));
[email protected]301415e2008-09-04 19:00:37153 }
154}
155
[email protected]db163f82010-04-02 21:01:35156// 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
[email protected]4b559b4d2011-04-14 17:37:14172 crypto::HMAC hmac(crypto::HMAC::SHA256);
[email protected]db163f82010-04-02 21:01:35173 ASSERT_TRUE(hmac.Init(key, sizeof(key)));
174 unsigned char calculated_hmac[kSHA256DigestSize];
175
[email protected]a5aec2e2011-04-30 18:55:18176 EXPECT_EQ(kSHA256DigestSize, hmac.DigestLength());
[email protected]db163f82010-04-02 21:01:35177 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
[email protected]4b559b4d2011-04-14 17:37:14213 crypto::HMAC hmac(crypto::HMAC::SHA1);
[email protected]db163f82010-04-02 21:01:35214 ASSERT_TRUE(hmac.Init(kKnownSecretKey, kKnownSecretKeySize));
215 unsigned char calculated_hmac[kSHA1DigestSize];
216
[email protected]a5aec2e2011-04-30 18:55:18217 EXPECT_EQ(kSHA1DigestSize, hmac.DigestLength());
[email protected]db163f82010-04-02 21:01:35218 EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
219 EXPECT_EQ(0, memcmp(kKnownHMACSHA1, calculated_hmac, kSHA1DigestSize));
[email protected]3292f532011-07-18 00:39:44220 EXPECT_TRUE(hmac.Verify(
221 message_data,
222 base::StringPiece(reinterpret_cast<const char*>(kKnownHMACSHA1),
223 kSHA1DigestSize)));
[email protected]baff1d042011-07-29 23:28:55224 EXPECT_TRUE(hmac.VerifyTruncated(
225 message_data,
226 base::StringPiece(reinterpret_cast<const char*>(kKnownHMACSHA1),
227 kSHA1DigestSize / 2)));
[email protected]db163f82010-04-02 21:01:35228
[email protected]4b559b4d2011-04-14 17:37:14229 crypto::HMAC hmac2(crypto::HMAC::SHA256);
[email protected]db163f82010-04-02 21:01:35230 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
[email protected]301415e2008-09-04 19:00:37237TEST(HMACTest, HMACObjectReuse) {
[email protected]4b559b4d2011-04-14 17:37:14238 crypto::HMAC hmac(crypto::HMAC::SHA1);
[email protected]3292f532011-07-18 00:39:44239 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);
[email protected]db163f82010-04-02 21:01:35245 unsigned char digest[kSHA1DigestSize];
246 EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
[email protected]3292f532011-07-18 00:39:44247 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)));
[email protected]301415e2008-09-04 19:00:37276 }
277}
[email protected]0e83fe8c2014-04-10 21:16:59278
279TEST(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("", 0u);
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}