1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
7 #pragma allow_unsafe_buffers
8 #endif
9
10 #include "crypto/hmac.h"
11
12 #include <stddef.h>
13 #include <string.h>
14
15 #include <string>
16 #include <string_view>
17
18 #include "base/strings/string_number_conversions.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 static const size_t kSHA1DigestSize = 20;
22 static const size_t kSHA256DigestSize = 32;
23
24 static const char* kSimpleKey =
25 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
26 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
27 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
28 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
29 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
30 static const size_t kSimpleKeyLength = 80;
31
32 static const struct {
33 const char *data;
34 const int data_len;
35 const char *digest;
36 } kSimpleHmacCases[] = {
37 { "Test Using Larger Than Block-Size Key - Hash Key First", 54,
38 "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55"
39 "\xED\x40\x21\x12" },
40 { "Test Using Larger Than Block-Size Key and Larger "
41 "Than One Block-Size Data", 73,
42 "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08"
43 "\xBB\xFF\x1A\x91" }
44 };
45
TEST(HMACTest,HmacSafeBrowsingResponseTest)46 TEST(HMACTest, HmacSafeBrowsingResponseTest) {
47 const int kKeySize = 16;
48
49 // Client key.
50 const unsigned char kClientKey[kKeySize] =
51 { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
52 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
53
54 // Expected HMAC result using kMessage and kClientKey.
55 const unsigned char kReceivedHmac[kSHA1DigestSize] =
56 { 0xb9, 0x3c, 0xd6, 0xf0, 0x49, 0x47, 0xe2, 0x52,
57 0x59, 0x7a, 0xbd, 0x1f, 0x2b, 0x4c, 0x83, 0xad,
58 0x86, 0xd2, 0x48, 0x85 };
59
60 const char kMessage[] =
61 "n:1896\ni:goog-malware-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav"
62 "ar_s_445-450\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_439-444\nu:s"
63 ".ytimg.com/safebrowsing/rd/goog-malware-shavar_s_437\nu:s.ytimg.com/safebrowsi"
64 "ng/rd/goog-malware-shavar_s_436\nu:s.ytimg.com/safebrowsing/rd/goog-malware-sh"
65 "avar_s_433-435\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_431\nu:s.y"
66 "timg.com/safebrowsing/rd/goog-malware-shavar_s_430\nu:s.ytimg.com/safebrowsing"
67 "/rd/goog-malware-shavar_s_429\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav"
68 "ar_s_428\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_426\nu:s.ytimg.c"
69 "om/safebrowsing/rd/goog-malware-shavar_s_424\nu:s.ytimg.com/safebrowsing/rd/go"
70 "og-malware-shavar_s_423\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_4"
71 "22\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_420\nu:s.ytimg.com/saf"
72 "ebrowsing/rd/goog-malware-shavar_s_419\nu:s.ytimg.com/safebrowsing/rd/goog-mal"
73 "ware-shavar_s_414\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_409-411"
74 "\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_405\nu:s.ytimg.com/safeb"
75 "rowsing/rd/goog-malware-shavar_s_404\nu:s.ytimg.com/safebrowsing/rd/goog-malwa"
76 "re-shavar_s_402\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_401\nu:s."
77 "ytimg.com/safebrowsing/rd/goog-malware-shavar_a_973-978\nu:s.ytimg.com/safebro"
78 "wsing/rd/goog-malware-shavar_a_937-972\nu:s.ytimg.com/safebrowsing/rd/goog-mal"
79 "ware-shavar_a_931-936\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_925"
80 "-930\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_919-924\ni:goog-phis"
81 "h-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2633\nu:s.ytimg.co"
82 "m/safebrowsing/rd/goog-phish-shavar_a_2632\nu:s.ytimg.com/safebrowsing/rd/goog"
83 "-phish-shavar_a_2629-2631\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2"
84 "626-2628\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2625\n";
85
86 std::string message_data(kMessage);
87
88 crypto::HMAC hmac(crypto::HMAC::SHA1);
89 ASSERT_TRUE(hmac.Init(kClientKey, kKeySize));
90 unsigned char calculated_hmac[kSHA1DigestSize];
91
92 EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
93 EXPECT_EQ(0, memcmp(kReceivedHmac, calculated_hmac, kSHA1DigestSize));
94 }
95
96 // Test cases from RFC 2202 section 3
TEST(HMACTest,RFC2202TestCases)97 TEST(HMACTest, RFC2202TestCases) {
98 const struct {
99 const char *key;
100 const int key_len;
101 const char *data;
102 const int data_len;
103 const char *digest;
104 } cases[] = {
105 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
106 "\x0B\x0B\x0B\x0B", 20,
107 "Hi There", 8,
108 "\xB6\x17\x31\x86\x55\x05\x72\x64\xE2\x8B\xC0\xB6\xFB\x37\x8C\x8E"
109 "\xF1\x46\xBE\x00" },
110 { "Jefe", 4,
111 "what do ya want for nothing?", 28,
112 "\xEF\xFC\xDF\x6A\xE5\xEB\x2F\xA2\xD2\x74\x16\xD5\xF1\x84\xDF\x9C"
113 "\x25\x9A\x7C\x79" },
114 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
115 "\xAA\xAA\xAA\xAA", 20,
116 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
117 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
118 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
119 "\xDD\xDD", 50,
120 "\x12\x5D\x73\x42\xB9\xAC\x11\xCD\x91\xA3\x9A\xF4\x8A\xA1\x7B\x4F"
121 "\x63\xF1\x75\xD3" },
122 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
123 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
124 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
125 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
126 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
127 "\xCD\xCD", 50,
128 "\x4C\x90\x07\xF4\x02\x62\x50\xC6\xBC\x84\x14\xF9\xBF\x50\xC8\x6C"
129 "\x2D\x72\x35\xDA" },
130 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
131 "\x0C\x0C\x0C\x0C", 20,
132 "Test With Truncation", 20,
133 "\x4C\x1A\x03\x42\x4B\x55\xE0\x7F\xE7\xF2\x7B\xE1\xD5\x8B\xB9\x32"
134 "\x4A\x9A\x5A\x04" },
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 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
139 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
140 80,
141 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
142 "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55"
143 "\xED\x40\x21\x12" },
144 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
145 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
146 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
147 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
148 "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
149 80,
150 "Test Using Larger Than Block-Size Key and Larger "
151 "Than One Block-Size Data", 73,
152 "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08"
153 "\xBB\xFF\x1A\x91" }
154 };
155
156 for (size_t i = 0; i < std::size(cases); ++i) {
157 crypto::HMAC hmac(crypto::HMAC::SHA1);
158 ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key),
159 cases[i].key_len));
160 std::string data_string(cases[i].data, cases[i].data_len);
161 unsigned char digest[kSHA1DigestSize];
162 EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
163 EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize));
164 }
165 }
166
167 // TODO(wtc): add other test vectors from RFC 4231.
TEST(HMACTest,RFC4231TestCase6)168 TEST(HMACTest, RFC4231TestCase6) {
169 unsigned char key[131];
170 for (size_t i = 0; i < sizeof(key); ++i)
171 key[i] = 0xaa;
172
173 std::string data = "Test Using Larger Than Block-Size Key - Hash Key First";
174 ASSERT_EQ(54U, data.size());
175
176 static unsigned char kKnownHMACSHA256[] = {
177 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
178 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
179 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
180 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54
181 };
182
183 crypto::HMAC hmac(crypto::HMAC::SHA256);
184 ASSERT_TRUE(hmac.Init(key, sizeof(key)));
185 unsigned char calculated_hmac[kSHA256DigestSize];
186
187 EXPECT_EQ(kSHA256DigestSize, hmac.DigestLength());
188 EXPECT_TRUE(hmac.Sign(data, calculated_hmac, kSHA256DigestSize));
189 EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac, kSHA256DigestSize));
190 }
191
192 // Based on NSS's FIPS HMAC power-up self-test.
TEST(HMACTest,NSSFIPSPowerUpSelfTest)193 TEST(HMACTest, NSSFIPSPowerUpSelfTest) {
194 static const char kKnownMessage[] =
195 "The test message for the MD2, MD5, and SHA-1 hashing algorithms.";
196
197 static const unsigned char kKnownSecretKey[] = {
198 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x20,
199 0x61, 0x6e, 0x64, 0x20, 0x54, 0x68, 0x75, 0x6e,
200 0x64, 0x65, 0x72, 0x42, 0x69, 0x72, 0x64, 0x20,
201 0x61, 0x72, 0x65, 0x20, 0x61, 0x77, 0x65, 0x73,
202 0x6f, 0x6d, 0x65, 0x21, 0x00
203 };
204
205 static const size_t kKnownSecretKeySize = sizeof(kKnownSecretKey);
206
207 // HMAC-SHA-1 known answer (20 bytes).
208 static const unsigned char kKnownHMACSHA1[] = {
209 0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05,
210 0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e,
211 0x5d, 0x0e, 0x1e, 0x11
212 };
213
214 // HMAC-SHA-256 known answer (32 bytes).
215 static const unsigned char kKnownHMACSHA256[] = {
216 0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44,
217 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0,
218 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9,
219 0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48
220 };
221
222 std::string message_data(kKnownMessage);
223
224 crypto::HMAC hmac(crypto::HMAC::SHA1);
225 ASSERT_TRUE(hmac.Init(kKnownSecretKey, kKnownSecretKeySize));
226 unsigned char calculated_hmac[kSHA1DigestSize];
227
228 EXPECT_EQ(kSHA1DigestSize, hmac.DigestLength());
229 EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
230 EXPECT_EQ(0, memcmp(kKnownHMACSHA1, calculated_hmac, kSHA1DigestSize));
231 EXPECT_TRUE(hmac.Verify(
232 message_data,
233 std::string_view(reinterpret_cast<const char*>(kKnownHMACSHA1),
234 kSHA1DigestSize)));
235 EXPECT_TRUE(hmac.VerifyTruncated(
236 message_data,
237 std::string_view(reinterpret_cast<const char*>(kKnownHMACSHA1),
238 kSHA1DigestSize / 2)));
239
240 crypto::HMAC hmac2(crypto::HMAC::SHA256);
241 ASSERT_TRUE(hmac2.Init(kKnownSecretKey, kKnownSecretKeySize));
242 unsigned char calculated_hmac2[kSHA256DigestSize];
243
244 EXPECT_TRUE(hmac2.Sign(message_data, calculated_hmac2, kSHA256DigestSize));
245 EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac2, kSHA256DigestSize));
246 }
247
TEST(HMACTest,HMACObjectReuse)248 TEST(HMACTest, HMACObjectReuse) {
249 crypto::HMAC hmac(crypto::HMAC::SHA1);
250 ASSERT_TRUE(
251 hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey),
252 kSimpleKeyLength));
253 for (size_t i = 0; i < std::size(kSimpleHmacCases); ++i) {
254 std::string data_string(kSimpleHmacCases[i].data,
255 kSimpleHmacCases[i].data_len);
256 unsigned char digest[kSHA1DigestSize];
257 EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
258 EXPECT_EQ(0, memcmp(kSimpleHmacCases[i].digest, digest, kSHA1DigestSize));
259 }
260 }
261
TEST(HMACTest,Verify)262 TEST(HMACTest, Verify) {
263 crypto::HMAC hmac(crypto::HMAC::SHA1);
264 ASSERT_TRUE(
265 hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey),
266 kSimpleKeyLength));
267 const char empty_digest[kSHA1DigestSize] = { 0 };
268 for (size_t i = 0; i < std::size(kSimpleHmacCases); ++i) {
269 // Expected results
270 EXPECT_TRUE(hmac.Verify(
271 std::string_view(kSimpleHmacCases[i].data,
272 kSimpleHmacCases[i].data_len),
273 std::string_view(kSimpleHmacCases[i].digest, kSHA1DigestSize)));
274 // Mismatched size
275 EXPECT_FALSE(hmac.Verify(std::string_view(kSimpleHmacCases[i].data,
276 kSimpleHmacCases[i].data_len),
277 std::string_view(kSimpleHmacCases[i].data,
278 kSimpleHmacCases[i].data_len)));
279
280 // Expected size, mismatched data
281 EXPECT_FALSE(hmac.Verify(std::string_view(kSimpleHmacCases[i].data,
282 kSimpleHmacCases[i].data_len),
283 std::string_view(empty_digest, kSHA1DigestSize)));
284 }
285 }
286
TEST(HMACTest,EmptyKey)287 TEST(HMACTest, EmptyKey) {
288 // Test vector from https://en.wikipedia.org/wiki/HMAC
289 const char* kExpectedDigest =
290 "\xFB\xDB\x1D\x1B\x18\xAA\x6C\x08\x32\x4B\x7D\x64\xB7\x1F\xB7\x63"
291 "\x70\x69\x0E\x1D";
292 std::string_view data("");
293
294 crypto::HMAC hmac(crypto::HMAC::SHA1);
295 ASSERT_TRUE(hmac.Init(nullptr, 0));
296
297 unsigned char digest[kSHA1DigestSize];
298 EXPECT_TRUE(hmac.Sign(data, digest, kSHA1DigestSize));
299 EXPECT_EQ(0, memcmp(kExpectedDigest, digest, kSHA1DigestSize));
300
301 EXPECT_TRUE(
302 hmac.Verify(data, std::string_view(kExpectedDigest, kSHA1DigestSize)));
303 }
304
TEST(HMACTest,TooLong)305 TEST(HMACTest, TooLong) {
306 // See RFC4231, section 4.7.
307 unsigned char key[131];
308 for (size_t i = 0; i < sizeof(key); ++i)
309 key[i] = 0xaa;
310
311 std::string data = "Test Using Larger Than Block-Size Key - Hash Key First";
312 static uint8_t kKnownHMACSHA256[] = {
313 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26,
314 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28,
315 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54};
316
317 crypto::HMAC hmac(crypto::HMAC::SHA256);
318 ASSERT_TRUE(hmac.Init(key, sizeof(key)));
319
320 // Attempting to write too large of an HMAC is an error.
321 uint8_t calculated_hmac[kSHA256DigestSize + 1];
322 EXPECT_FALSE(hmac.Sign(data, calculated_hmac, sizeof(calculated_hmac)));
323
324 // Attempting to verify too large of an HMAC is an error.
325 memcpy(calculated_hmac, kKnownHMACSHA256, kSHA256DigestSize);
326 calculated_hmac[kSHA256DigestSize] = 0;
327 EXPECT_FALSE(hmac.VerifyTruncated(
328 data,
329 std::string(calculated_hmac, calculated_hmac + sizeof(calculated_hmac))));
330 }
331
TEST(HMACTest,Bytes)332 TEST(HMACTest, Bytes) {
333 // See RFC4231, section 4.7.
334 std::vector<uint8_t> key(131, 0xaa);
335 std::string data_str =
336 "Test Using Larger Than Block-Size Key - Hash Key First";
337 std::vector<uint8_t> data(data_str.begin(), data_str.end());
338 static uint8_t kKnownHMACSHA256[] = {
339 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26,
340 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28,
341 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54};
342
343 crypto::HMAC hmac(crypto::HMAC::SHA256);
344 ASSERT_TRUE(hmac.Init(key));
345
346 uint8_t calculated_hmac[kSHA256DigestSize];
347 ASSERT_TRUE(hmac.Sign(data, calculated_hmac));
348 EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac, kSHA256DigestSize));
349
350 EXPECT_TRUE(hmac.Verify(data, calculated_hmac));
351 EXPECT_TRUE(hmac.VerifyTruncated(
352 data, base::span(calculated_hmac, kSHA256DigestSize / 2)));
353
354 data[0]++;
355 EXPECT_FALSE(hmac.Verify(data, calculated_hmac));
356 EXPECT_FALSE(hmac.VerifyTruncated(
357 data, base::span(calculated_hmac, kSHA256DigestSize / 2)));
358 }
359
TEST(HMACTest,OneShotSha1)360 TEST(HMACTest, OneShotSha1) {
361 // RFC 2202 test case 3:
362 std::vector<uint8_t> key(20, 0xaa);
363 std::vector<uint8_t> data(50, 0xdd);
364 std::vector<uint8_t> expected;
365 CHECK(base::HexStringToBytes("125d7342b9ac11cd91a39af48aa17b4f63f175d3",
366 &expected));
367
368 auto result = crypto::hmac::SignSha1(key, data);
369 EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
370 EXPECT_TRUE(crypto::hmac::VerifySha1(key, data, result));
371 result[0] ^= 0x01;
372 EXPECT_FALSE(crypto::hmac::VerifySha1(key, data, result));
373 }
374
TEST(HMACTest,OneShotSha256)375 TEST(HMACTest, OneShotSha256) {
376 // RFC 4231 test case 3:
377 std::vector<uint8_t> key(20, 0xaa);
378 std::vector<uint8_t> data(50, 0xdd);
379 std::vector<uint8_t> expected;
380 CHECK(base::HexStringToBytes(
381 "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
382 &expected));
383
384 auto result = crypto::hmac::SignSha256(key, data);
385 EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
386 EXPECT_TRUE(crypto::hmac::VerifySha256(key, data, result));
387 result[0] ^= 0x01;
388 EXPECT_FALSE(crypto::hmac::VerifySha256(key, data, result));
389 }
390
TEST(HMACTest,OneShotSha512)391 TEST(HMACTest, OneShotSha512) {
392 // RFC 4231 test case 3:
393 std::vector<uint8_t> key(20, 0xaa);
394 std::vector<uint8_t> data(50, 0xdd);
395 std::vector<uint8_t> expected;
396 CHECK(base::HexStringToBytes(
397 "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
398 "bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
399 &expected));
400
401 auto result = crypto::hmac::SignSha512(key, data);
402 EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
403 EXPECT_TRUE(crypto::hmac::VerifySha512(key, data, result));
404 result[0] ^= 0x01;
405 EXPECT_FALSE(crypto::hmac::VerifySha512(key, data, result));
406 }
407
TEST(HMACTest,OneShotWrongLengthDies)408 TEST(HMACTest, OneShotWrongLengthDies) {
409 std::array<uint8_t, 32> key;
410 std::array<uint8_t, 32> data;
411 std::array<uint8_t, 16> small_hmac;
412 std::array<uint8_t, 128> big_hmac;
413
414 EXPECT_DEATH_IF_SUPPORTED(crypto::hmac::Sign(crypto::hash::HashKind::kSha256,
415 key, data, small_hmac),
416 "");
417 EXPECT_DEATH_IF_SUPPORTED(
418 crypto::hmac::Sign(crypto::hash::HashKind::kSha256, key, data, big_hmac),
419 "");
420
421 EXPECT_DEATH_IF_SUPPORTED(
422 (void)crypto::hmac::Verify(crypto::hash::HashKind::kSha256, key, data,
423 small_hmac),
424 "");
425 EXPECT_DEATH_IF_SUPPORTED(
426 (void)crypto::hmac::Verify(crypto::hash::HashKind::kSha256, key, data,
427 big_hmac),
428 "");
429 }
430