1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package hmac
6
7import (
8	"crypto/internal/boring"
9	"crypto/internal/cryptotest"
10	"crypto/md5"
11	"crypto/sha1"
12	"crypto/sha256"
13	"crypto/sha512"
14	"fmt"
15	"hash"
16	"testing"
17)
18
19type hmacTest struct {
20	hash      func() hash.Hash
21	key       []byte
22	in        []byte
23	out       string
24	size      int
25	blocksize int
26}
27
28var hmacTests = []hmacTest{
29	// Tests from US FIPS 198
30	// https://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
31	{
32		sha1.New,
33		[]byte{
34			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
35			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
36			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
37			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
38			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
39			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
40			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
41			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
42		},
43		[]byte("Sample #1"),
44		"4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a",
45		sha1.Size,
46		sha1.BlockSize,
47	},
48	{
49		sha1.New,
50		[]byte{
51			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
52			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
53			0x40, 0x41, 0x42, 0x43,
54		},
55		[]byte("Sample #2"),
56		"0922d3405faa3d194f82a45830737d5cc6c75d24",
57		sha1.Size,
58		sha1.BlockSize,
59	},
60	{
61		sha1.New,
62		[]byte{
63			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
64			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
65			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
66			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
67			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
68			0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
69			0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
70			0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
71			0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
72			0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
73			0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
74			0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
75			0xb0, 0xb1, 0xb2, 0xb3,
76		},
77		[]byte("Sample #3"),
78		"bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa",
79		sha1.Size,
80		sha1.BlockSize,
81	},
82
83	// Test from Plan 9.
84	{
85		md5.New,
86		[]byte("Jefe"),
87		[]byte("what do ya want for nothing?"),
88		"750c783e6ab0b503eaa86e310a5db738",
89		md5.Size,
90		md5.BlockSize,
91	},
92
93	// Tests from RFC 4231
94	{
95		sha256.New,
96		[]byte{
97			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
98			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
99			0x0b, 0x0b, 0x0b, 0x0b,
100		},
101		[]byte("Hi There"),
102		"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
103		sha256.Size,
104		sha256.BlockSize,
105	},
106	{
107		sha256.New,
108		[]byte("Jefe"),
109		[]byte("what do ya want for nothing?"),
110		"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
111		sha256.Size,
112		sha256.BlockSize,
113	},
114	{
115		sha256.New,
116		[]byte{
117			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
118			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
119			0xaa, 0xaa, 0xaa, 0xaa,
120		},
121		[]byte{
122			0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
123			0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
124			0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
125			0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
126			0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
127			0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
128			0xdd, 0xdd,
129		},
130		"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
131		sha256.Size,
132		sha256.BlockSize,
133	},
134	{
135		sha256.New,
136		[]byte{
137			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
138			0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
139			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
140			0x19,
141		},
142		[]byte{
143			0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
144			0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
145			0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
146			0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
147			0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
148			0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
149			0xcd, 0xcd,
150		},
151		"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
152		sha256.Size,
153		sha256.BlockSize,
154	},
155	{
156		sha256.New,
157		[]byte{
158			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
159			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
160			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
161			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
162			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
163			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
164			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
165			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
166			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
167			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
168			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
169			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
170			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
171			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
172			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
173			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
174			0xaa, 0xaa, 0xaa,
175		},
176		[]byte("Test Using Larger Than Block-Size Key - Hash Key First"),
177		"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
178		sha256.Size,
179		sha256.BlockSize,
180	},
181	{
182		sha256.New,
183		[]byte{
184			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
185			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
186			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
187			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
188			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
189			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
190			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
191			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
192			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
193			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
194			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
195			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
196			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
197			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
198			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
199			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
200			0xaa, 0xaa, 0xaa,
201		},
202		[]byte("This is a test using a larger than block-size key " +
203			"and a larger than block-size data. The key needs to " +
204			"be hashed before being used by the HMAC algorithm."),
205		"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
206		sha256.Size,
207		sha256.BlockSize,
208	},
209
210	// Tests from https://csrc.nist.gov/groups/ST/toolkit/examples.html
211	// (truncated tag tests are left out)
212	{
213		sha1.New,
214		[]byte{
215			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
216			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
217			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
218			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
219			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
220			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
221			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
222			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
223		},
224		[]byte("Sample message for keylen=blocklen"),
225		"5fd596ee78d5553c8ff4e72d266dfd192366da29",
226		sha1.Size,
227		sha1.BlockSize,
228	},
229	{
230		sha1.New,
231		[]byte{
232			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
233			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
234			0x10, 0x11, 0x12, 0x13,
235		},
236		[]byte("Sample message for keylen<blocklen"),
237		"4c99ff0cb1b31bd33f8431dbaf4d17fcd356a807",
238		sha1.Size,
239		sha1.BlockSize,
240	},
241	{
242		sha1.New,
243		[]byte{
244			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
245			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
246			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
247			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
248			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
249			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
250			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
251			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
252			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
253			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
254			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
255			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
256			0x60, 0x61, 0x62, 0x63,
257		},
258		[]byte("Sample message for keylen=blocklen"),
259		"2d51b2f7750e410584662e38f133435f4c4fd42a",
260		sha1.Size,
261		sha1.BlockSize,
262	},
263	{
264		sha256.New224,
265		[]byte{
266			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
267			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
268			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
269			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
270			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
271			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
272			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
273			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
274		},
275		[]byte("Sample message for keylen=blocklen"),
276		"c7405e3ae058e8cd30b08b4140248581ed174cb34e1224bcc1efc81b",
277		sha256.Size224,
278		sha256.BlockSize,
279	},
280	{
281		sha256.New224,
282		[]byte{
283			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
284			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
285			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
286			0x18, 0x19, 0x1a, 0x1b,
287		},
288		[]byte("Sample message for keylen<blocklen"),
289		"e3d249a8cfb67ef8b7a169e9a0a599714a2cecba65999a51beb8fbbe",
290		sha256.Size224,
291		sha256.BlockSize,
292	},
293	{
294		sha256.New224,
295		[]byte{
296			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
297			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
298			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
299			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
300			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
301			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
302			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
303			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
304			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
305			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
306			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
307			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
308			0x60, 0x61, 0x62, 0x63,
309		},
310		[]byte("Sample message for keylen=blocklen"),
311		"91c52509e5af8531601ae6230099d90bef88aaefb961f4080abc014d",
312		sha256.Size224,
313		sha256.BlockSize,
314	},
315	{
316		sha256.New,
317		[]byte{
318			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
319			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
320			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
321			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
322			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
323			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
324			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
325			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
326		},
327		[]byte("Sample message for keylen=blocklen"),
328		"8bb9a1db9806f20df7f77b82138c7914d174d59e13dc4d0169c9057b133e1d62",
329		sha256.Size,
330		sha256.BlockSize,
331	},
332	{
333		sha256.New,
334		[]byte{
335			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
336			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
337			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
338			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
339		},
340		[]byte("Sample message for keylen<blocklen"),
341		"a28cf43130ee696a98f14a37678b56bcfcbdd9e5cf69717fecf5480f0ebdf790",
342		sha256.Size,
343		sha256.BlockSize,
344	},
345	{
346		sha256.New,
347		[]byte{
348			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
349			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
350			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
351			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
352			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
353			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
354			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
355			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
356			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
357			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
358			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
359			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
360			0x60, 0x61, 0x62, 0x63,
361		},
362		[]byte("Sample message for keylen=blocklen"),
363		"bdccb6c72ddeadb500ae768386cb38cc41c63dbb0878ddb9c7a38a431b78378d",
364		sha256.Size,
365		sha256.BlockSize,
366	},
367	{
368		sha512.New384,
369		[]byte{
370			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
371			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
372			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
373			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
374			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
375			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
376			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
377			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
378			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
379			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
380			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
381			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
382			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
383			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
384			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
385			0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
386		},
387		[]byte("Sample message for keylen=blocklen"),
388		"63c5daa5e651847ca897c95814ab830bededc7d25e83eef9195cd45857a37f448947858f5af50cc2b1b730ddf29671a9",
389		sha512.Size384,
390		sha512.BlockSize,
391	},
392	{
393		sha512.New384,
394		[]byte{
395			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
396			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
397			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
398			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
399			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
400			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
401		},
402		[]byte("Sample message for keylen<blocklen"),
403		"6eb242bdbb582ca17bebfa481b1e23211464d2b7f8c20b9ff2201637b93646af5ae9ac316e98db45d9cae773675eeed0",
404		sha512.Size384,
405		sha512.BlockSize,
406	},
407	{
408		sha512.New384,
409		[]byte{
410			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
411			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
412			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
413			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
414			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
415			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
416			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
417			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
418			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
419			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
420			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
421			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
422			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
423			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
424			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
425			0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
426			0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
427			0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
428			0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
429			0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
430			0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
431			0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
432			0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
433			0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
434			0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
435		},
436		[]byte("Sample message for keylen=blocklen"),
437		"5b664436df69b0ca22551231a3f0a3d5b4f97991713cfa84bff4d0792eff96c27dccbbb6f79b65d548b40e8564cef594",
438		sha512.Size384,
439		sha512.BlockSize,
440	},
441	{
442		sha512.New,
443		[]byte{
444			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
445			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
446			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
447			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
448			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
449			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
450			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
451			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
452			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
453			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
454			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
455			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
456			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
457			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
458			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
459			0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
460		},
461		[]byte("Sample message for keylen=blocklen"),
462		"fc25e240658ca785b7a811a8d3f7b4ca" +
463			"48cfa26a8a366bf2cd1f836b05fcb024bd36853081811d6c" +
464			"ea4216ebad79da1cfcb95ea4586b8a0ce356596a55fb1347",
465		sha512.Size,
466		sha512.BlockSize,
467	},
468	{
469		sha512.New,
470		[]byte{
471			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
472			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
473			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
474			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
475			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
476			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
477			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
478			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
479		},
480		[]byte("Sample message for keylen<blocklen"),
481		"fd44c18bda0bb0a6ce0e82b031bf2818" +
482			"f6539bd56ec00bdc10a8a2d730b3634de2545d639b0f2cf7" +
483			"10d0692c72a1896f1f211c2b922d1a96c392e07e7ea9fedc",
484		sha512.Size,
485		sha512.BlockSize,
486	},
487	{
488		sha512.New,
489		[]byte{
490			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
491			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
492			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
493			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
494			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
495			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
496			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
497			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
498			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
499			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
500			0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
501			0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
502			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
503			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
504			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
505			0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
506			0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
507			0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
508			0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
509			0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
510			0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
511			0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
512			0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
513			0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
514			0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
515		},
516		[]byte("Sample message for keylen=blocklen"),
517		"d93ec8d2de1ad2a9957cb9b83f14e76a" +
518			"d6b5e0cce285079a127d3b14bccb7aa7286d4ac0d4ce6421" +
519			"5f2bc9e6870b33d97438be4aaa20cda5c5a912b48b8e27f3",
520		sha512.Size,
521		sha512.BlockSize,
522	},
523	// HMAC without key is dumb but should probably not fail.
524	{
525		sha1.New,
526		[]byte{},
527		[]byte("message"),
528		"d5d1ed05121417247616cfc8378f360a39da7cfa",
529		sha1.Size,
530		sha1.BlockSize,
531	},
532	{
533		sha256.New,
534		[]byte{},
535		[]byte("message"),
536		"eb08c1f56d5ddee07f7bdf80468083da06b64cf4fac64fe3a90883df5feacae4",
537		sha256.Size,
538		sha256.BlockSize,
539	},
540	{
541		sha512.New,
542		[]byte{},
543		[]byte("message"),
544		"08fce52f6395d59c2a3fb8abb281d74ad6f112b9a9c787bcea290d94dadbc82b2ca3e5e12bf2277c7fedbb0154d5493e41bb7459f63c8e39554ea3651b812492",
545		sha512.Size,
546		sha512.BlockSize,
547	},
548}
549
550func TestHMAC(t *testing.T) {
551	for i, tt := range hmacTests {
552		h := New(tt.hash, tt.key)
553		if s := h.Size(); s != tt.size {
554			t.Errorf("Size: got %v, want %v", s, tt.size)
555		}
556		if b := h.BlockSize(); b != tt.blocksize {
557			t.Errorf("BlockSize: got %v, want %v", b, tt.blocksize)
558		}
559		for j := 0; j < 4; j++ {
560			n, err := h.Write(tt.in)
561			if n != len(tt.in) || err != nil {
562				t.Errorf("test %d.%d: Write(%d) = %d, %v", i, j, len(tt.in), n, err)
563				continue
564			}
565
566			// Repetitive Sum() calls should return the same value
567			for k := 0; k < 2; k++ {
568				sum := fmt.Sprintf("%x", h.Sum(nil))
569				if sum != tt.out {
570					t.Errorf("test %d.%d.%d: have %s want %s\n", i, j, k, sum, tt.out)
571				}
572			}
573
574			// Second iteration: make sure reset works.
575			h.Reset()
576
577			// Third and fourth iteration: make sure hmac works on
578			// hashes without MarshalBinary/UnmarshalBinary
579			if j == 1 {
580				h = New(func() hash.Hash { return justHash{tt.hash()} }, tt.key)
581			}
582		}
583	}
584}
585
586func TestNonUniqueHash(t *testing.T) {
587	if boring.Enabled {
588		t.Skip("hash.Hash provided by boringcrypto are not comparable")
589	}
590	sha := sha256.New()
591	defer func() {
592		err := recover()
593		if err == nil {
594			t.Error("expected panic when calling New with a non-unique hash generation function")
595		}
596	}()
597	New(func() hash.Hash { return sha }, []byte("bytes"))
598}
599
600// justHash implements just the hash.Hash methods and nothing else
601type justHash struct {
602	hash.Hash
603}
604
605func TestEqual(t *testing.T) {
606	a := []byte("test")
607	b := []byte("test1")
608	c := []byte("test2")
609
610	if !Equal(b, b) {
611		t.Error("Equal failed with equal arguments")
612	}
613	if Equal(a, b) {
614		t.Error("Equal accepted a prefix of the second argument")
615	}
616	if Equal(b, a) {
617		t.Error("Equal accepted a prefix of the first argument")
618	}
619	if Equal(b, c) {
620		t.Error("Equal accepted unequal slices")
621	}
622}
623
624func TestHMACHash(t *testing.T) {
625	for i, test := range hmacTests {
626		baseHash := test.hash
627		key := test.key
628
629		t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) {
630			cryptotest.TestHash(t, func() hash.Hash { return New(baseHash, key) })
631		})
632	}
633}
634
635func BenchmarkHMACSHA256_1K(b *testing.B) {
636	key := make([]byte, 32)
637	buf := make([]byte, 1024)
638	h := New(sha256.New, key)
639	b.SetBytes(int64(len(buf)))
640	for i := 0; i < b.N; i++ {
641		h.Write(buf)
642		mac := h.Sum(nil)
643		h.Reset()
644		buf[0] = mac[0]
645	}
646}
647
648func BenchmarkHMACSHA256_32(b *testing.B) {
649	key := make([]byte, 32)
650	buf := make([]byte, 32)
651	h := New(sha256.New, key)
652	b.SetBytes(int64(len(buf)))
653	for i := 0; i < b.N; i++ {
654		h.Write(buf)
655		mac := h.Sum(nil)
656		h.Reset()
657		buf[0] = mac[0]
658	}
659}
660
661func BenchmarkNewWriteSum(b *testing.B) {
662	buf := make([]byte, 32)
663	b.SetBytes(int64(len(buf)))
664	for i := 0; i < b.N; i++ {
665		h := New(sha256.New, make([]byte, 32))
666		h.Write(buf)
667		mac := h.Sum(nil)
668		buf[0] = mac[0]
669	}
670}
671