1 // Copyright 2014 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.
17 type hkdfTest struct {
25 var hkdfTests = []hkdfTest{
26 // Tests from RFC 5869
30 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
31 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
32 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
35 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
36 0x08, 0x09, 0x0a, 0x0b, 0x0c,
39 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
43 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
44 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
45 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
46 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
47 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
54 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
55 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
56 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
57 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
58 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
59 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
60 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
61 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
62 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
63 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
66 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
67 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
68 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
69 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
70 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
71 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
72 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
73 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
74 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
75 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
78 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
79 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
80 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
81 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
82 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
83 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
84 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
85 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
86 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
87 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
90 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
91 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
92 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
93 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
94 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
95 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
96 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
97 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
98 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
99 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
106 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
107 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
108 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
113 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
114 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
115 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
116 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
117 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
124 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
128 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
129 0x08, 0x09, 0x0a, 0x0b, 0x0c,
132 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
136 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69,
137 0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81,
138 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
139 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2,
140 0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3,
147 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
148 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
149 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
150 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
151 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
152 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
153 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
154 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
155 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
156 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
159 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
160 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
161 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
162 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
163 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
164 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
165 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
166 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
167 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
168 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
171 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
172 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
173 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
174 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
175 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
176 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
177 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
178 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
179 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
180 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
183 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7,
184 0xc9, 0xf1, 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb,
185 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
186 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe,
187 0x8f, 0xa3, 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3,
188 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
189 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed,
190 0x03, 0x4c, 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e,
191 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
192 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52,
199 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
200 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
201 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
206 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61,
207 0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06,
208 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
209 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0,
210 0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3,
217 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
218 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
219 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
224 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3,
225 0x50, 0x0d, 0x63, 0x6a, 0x62, 0xf6, 0x4f, 0x0a,
226 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
227 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5,
228 0x67, 0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac,
234 func TestHKDF(t *testing.T) {
235 for i, tt := range hkdfTests {
236 hkdf := New(tt.hash, tt.master, tt.salt, tt.info)
237 out := make([]byte, len(tt.out))
239 n, err := io.ReadFull(hkdf, out)
240 if n != len(tt.out) || err != nil {
241 t.Errorf("test %d: not enough output bytes: %d.", i, n)
244 if !bytes.Equal(out, tt.out) {
245 t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out)
250 func TestHKDFMultiRead(t *testing.T) {
251 for i, tt := range hkdfTests {
252 hkdf := New(tt.hash, tt.master, tt.salt, tt.info)
253 out := make([]byte, len(tt.out))
255 for b := 0; b < len(tt.out); b++ {
256 n, err := io.ReadFull(hkdf, out[b:b+1])
257 if n != 1 || err != nil {
258 t.Errorf("test %d.%d: not enough output bytes: have %d, need %d .", i, b, n, len(tt.out))
262 if !bytes.Equal(out, tt.out) {
263 t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out)
268 func TestHKDFLimit(t *testing.T) {
270 master := []byte{0x00, 0x01, 0x02, 0x03}
273 hkdf := New(hash, master, nil, info)
274 limit := hash().Size() * 255
275 out := make([]byte, limit)
277 // The maximum output bytes should be extractable
278 n, err := io.ReadFull(hkdf, out)
279 if n != limit || err != nil {
280 t.Errorf("not enough output bytes: %d, %v.", n, err)
283 // Reading one more should fail
284 n, err = io.ReadFull(hkdf, make([]byte, 1))
285 if n > 0 || err == nil {
286 t.Errorf("key expansion overflowed: n = %d, err = %v", n, err)
290 func Benchmark16ByteMD5Single(b *testing.B) {
291 benchmarkHKDFSingle(md5.New, 16, b)
294 func Benchmark20ByteSHA1Single(b *testing.B) {
295 benchmarkHKDFSingle(sha1.New, 20, b)
298 func Benchmark32ByteSHA256Single(b *testing.B) {
299 benchmarkHKDFSingle(sha256.New, 32, b)
302 func Benchmark64ByteSHA512Single(b *testing.B) {
303 benchmarkHKDFSingle(sha512.New, 64, b)
306 func Benchmark8ByteMD5Stream(b *testing.B) {
307 benchmarkHKDFStream(md5.New, 8, b)
310 func Benchmark16ByteMD5Stream(b *testing.B) {
311 benchmarkHKDFStream(md5.New, 16, b)
314 func Benchmark8ByteSHA1Stream(b *testing.B) {
315 benchmarkHKDFStream(sha1.New, 8, b)
318 func Benchmark20ByteSHA1Stream(b *testing.B) {
319 benchmarkHKDFStream(sha1.New, 20, b)
322 func Benchmark8ByteSHA256Stream(b *testing.B) {
323 benchmarkHKDFStream(sha256.New, 8, b)
326 func Benchmark32ByteSHA256Stream(b *testing.B) {
327 benchmarkHKDFStream(sha256.New, 32, b)
330 func Benchmark8ByteSHA512Stream(b *testing.B) {
331 benchmarkHKDFStream(sha512.New, 8, b)
334 func Benchmark64ByteSHA512Stream(b *testing.B) {
335 benchmarkHKDFStream(sha512.New, 64, b)
338 func benchmarkHKDFSingle(hasher func() hash.Hash, block int, b *testing.B) {
339 master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
340 salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}
341 info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27}
342 out := make([]byte, block)
344 b.SetBytes(int64(block))
347 for i := 0; i < b.N; i++ {
348 hkdf := New(hasher, master, salt, info)
349 io.ReadFull(hkdf, out)
353 func benchmarkHKDFStream(hasher func() hash.Hash, block int, b *testing.B) {
354 master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
355 salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}
356 info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27}
357 out := make([]byte, block)
359 b.SetBytes(int64(block))
362 hkdf := New(hasher, master, salt, info)
363 for i := 0; i < b.N; i++ {
364 _, err := io.ReadFull(hkdf, out)
366 hkdf = New(hasher, master, salt, info)