Source file
src/crypto/hkdf/hkdf_test.go
1
2
3
4
5 package hkdf
6
7 import (
8 "bytes"
9 "crypto/internal/boring"
10 "crypto/internal/fips140"
11 "crypto/md5"
12 "crypto/sha1"
13 "crypto/sha256"
14 "crypto/sha512"
15 "hash"
16 "testing"
17 )
18
19 type hkdfTest struct {
20 hash func() hash.Hash
21 master []byte
22 salt []byte
23 prk []byte
24 info []byte
25 out []byte
26 }
27
28 var hkdfTests = []hkdfTest{
29
30 {
31 sha256.New,
32 []byte{
33 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
34 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
35 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
36 },
37 []byte{
38 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
39 0x08, 0x09, 0x0a, 0x0b, 0x0c,
40 },
41 []byte{
42 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
43 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
44 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
45 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5,
46 },
47 []byte{
48 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
49 0xf8, 0xf9,
50 },
51 []byte{
52 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
53 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
54 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
55 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
56 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
57 0x58, 0x65,
58 },
59 },
60 {
61 sha256.New,
62 []byte{
63 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
64 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
65 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
66 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
67 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
68 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
69 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
70 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
71 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
72 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
73 },
74 []byte{
75 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
76 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
77 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
78 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
79 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
80 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
81 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
82 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
83 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
84 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
85 },
86 []byte{
87 0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a,
88 0x06, 0x10, 0x4c, 0x9c, 0xeb, 0x35, 0xb4, 0x5c,
89 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
90 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44,
91 },
92 []byte{
93 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
94 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
95 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
96 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
97 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
98 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
99 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
100 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
101 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
102 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
103 },
104 []byte{
105 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
106 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
107 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
108 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
109 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
110 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
111 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
112 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
113 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
114 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
115 0x1d, 0x87,
116 },
117 },
118 {
119 sha256.New,
120 []byte{
121 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
122 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
123 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
124 },
125 []byte{},
126 []byte{
127 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16,
128 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
129 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
130 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04,
131 },
132 []byte{},
133 []byte{
134 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
135 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
136 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
137 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
138 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
139 0x96, 0xc8,
140 },
141 },
142 {
143 sha256.New,
144 []byte{
145 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
146 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
147 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
148 },
149 nil,
150 []byte{
151 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16,
152 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
153 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
154 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04,
155 },
156 nil,
157 []byte{
158 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
159 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
160 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
161 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
162 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
163 0x96, 0xc8,
164 },
165 },
166 {
167 sha1.New,
168 []byte{
169 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
170 0x0b, 0x0b, 0x0b,
171 },
172 []byte{
173 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
174 0x08, 0x09, 0x0a, 0x0b, 0x0c,
175 },
176 []byte{
177 0x9b, 0x6c, 0x18, 0xc4, 0x32, 0xa7, 0xbf, 0x8f,
178 0x0e, 0x71, 0xc8, 0xeb, 0x88, 0xf4, 0xb3, 0x0b,
179 0xaa, 0x2b, 0xa2, 0x43,
180 },
181 []byte{
182 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
183 0xf8, 0xf9,
184 },
185 []byte{
186 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69,
187 0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81,
188 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
189 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2,
190 0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3,
191 0xf8, 0x96,
192 },
193 },
194 {
195 sha1.New,
196 []byte{
197 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
198 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
199 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
200 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
201 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
202 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
203 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
204 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
205 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
206 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
207 },
208 []byte{
209 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
210 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
211 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
212 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
213 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
214 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
215 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
216 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
217 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
218 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
219 },
220 []byte{
221 0x8a, 0xda, 0xe0, 0x9a, 0x2a, 0x30, 0x70, 0x59,
222 0x47, 0x8d, 0x30, 0x9b, 0x26, 0xc4, 0x11, 0x5a,
223 0x22, 0x4c, 0xfa, 0xf6,
224 },
225 []byte{
226 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
227 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
228 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
229 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
230 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
231 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
232 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
233 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
234 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
235 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
236 },
237 []byte{
238 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7,
239 0xc9, 0xf1, 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb,
240 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
241 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe,
242 0x8f, 0xa3, 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3,
243 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
244 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed,
245 0x03, 0x4c, 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e,
246 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
247 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52,
248 0xd3, 0xb4,
249 },
250 },
251 {
252 sha1.New,
253 []byte{
254 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
255 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
256 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
257 },
258 []byte{},
259 []byte{
260 0xda, 0x8c, 0x8a, 0x73, 0xc7, 0xfa, 0x77, 0x28,
261 0x8e, 0xc6, 0xf5, 0xe7, 0xc2, 0x97, 0x78, 0x6a,
262 0xa0, 0xd3, 0x2d, 0x01,
263 },
264 []byte{},
265 []byte{
266 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61,
267 0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06,
268 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
269 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0,
270 0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3,
271 0x49, 0x18,
272 },
273 },
274 {
275 sha1.New,
276 []byte{
277 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
278 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
279 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
280 },
281 nil,
282 []byte{
283 0x2a, 0xdc, 0xca, 0xda, 0x18, 0x77, 0x9e, 0x7c,
284 0x20, 0x77, 0xad, 0x2e, 0xb1, 0x9d, 0x3f, 0x3e,
285 0x73, 0x13, 0x85, 0xdd,
286 },
287 nil,
288 []byte{
289 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3,
290 0x50, 0x0d, 0x63, 0x6a, 0x62, 0xf6, 0x4f, 0x0a,
291 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
292 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5,
293 0x67, 0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac,
294 0xfc, 0x48,
295 },
296 },
297 }
298
299 func TestHKDF(t *testing.T) {
300 for i, tt := range hkdfTests {
301 prk, err := Extract(tt.hash, tt.master, tt.salt)
302 if err != nil {
303 t.Errorf("test %d: PRK extraction failed: %v", i, err)
304 }
305 if !bytes.Equal(prk, tt.prk) {
306 t.Errorf("test %d: incorrect PRK: have %v, need %v.", i, prk, tt.prk)
307 }
308
309 key, err := Key(tt.hash, tt.master, tt.salt, string(tt.info), len(tt.out))
310 if err != nil {
311 t.Errorf("test %d: key derivation failed: %v", i, err)
312 }
313
314 if !bytes.Equal(key, tt.out) {
315 t.Errorf("test %d: incorrect output: have %v, need %v.", i, key, tt.out)
316 }
317
318 expanded, err := Expand(tt.hash, prk, string(tt.info), len(tt.out))
319 if err != nil {
320 t.Errorf("test %d: key expansion failed: %v", i, err)
321 }
322
323 if !bytes.Equal(expanded, tt.out) {
324 t.Errorf("test %d: incorrect output from Expand: have %v, need %v.", i, expanded, tt.out)
325 }
326 }
327 }
328
329 func TestHKDFLimit(t *testing.T) {
330 hash := sha1.New
331 master := []byte{0x00, 0x01, 0x02, 0x03}
332 info := ""
333 limit := hash().Size() * 255
334
335
336 out, err := Key(hash, master, nil, info, limit)
337 if err != nil || len(out) != limit {
338 t.Errorf("key derivation failed: %v", err)
339 }
340
341
342 _, err = Key(hash, master, nil, info, limit+1)
343 if err == nil {
344 t.Error("expected key derivation to fail, but it succeeded")
345 }
346 }
347
348 func Benchmark16ByteMD5Single(b *testing.B) {
349 benchmarkHKDF(md5.New, 16, b)
350 }
351
352 func Benchmark20ByteSHA1Single(b *testing.B) {
353 benchmarkHKDF(sha1.New, 20, b)
354 }
355
356 func Benchmark32ByteSHA256Single(b *testing.B) {
357 benchmarkHKDF(sha256.New, 32, b)
358 }
359
360 func Benchmark64ByteSHA512Single(b *testing.B) {
361 benchmarkHKDF(sha512.New, 64, b)
362 }
363
364 func benchmarkHKDF(hasher func() hash.Hash, block int, b *testing.B) {
365 master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
366 salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}
367 info := string([]byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27})
368
369 b.SetBytes(int64(block))
370 b.ResetTimer()
371
372 for i := 0; i < b.N; i++ {
373 _, err := Key(hasher, master, salt, info, hasher().Size())
374 if err != nil {
375 b.Errorf("failed to derive key: %v", err)
376 }
377 }
378 }
379
380 func TestFIPSServiceIndicator(t *testing.T) {
381 if boring.Enabled {
382 t.Skip("in BoringCrypto mode HMAC is not from the Go FIPS module")
383 }
384
385 fips140.ResetServiceIndicator()
386 _, err := Key(sha256.New, []byte("YELLOW SUBMARINE"), nil, "", 32)
387 if err != nil {
388 panic(err)
389 }
390 if !fips140.ServiceIndicator() {
391 t.Error("FIPS service indicator should be set")
392 }
393
394
395 fips140.ResetServiceIndicator()
396 _, err = Key(sha256.New, []byte("key"), nil, "", 32)
397 if err != nil {
398 panic(err)
399 }
400 if fips140.ServiceIndicator() {
401 t.Error("FIPS service indicator should not be set")
402 }
403
404
405 fips140.ResetServiceIndicator()
406 _, err = Key(sha256.New, []byte("YELLOW SUBMARINE"), []byte("salt"), "info", 32)
407 if !fips140.ServiceIndicator() {
408 t.Error("FIPS service indicator should be set")
409 }
410 }
411
View as plain text