This source file includes following definitions.
- wusb_key_dump
- wusb_ccm_mac
- wusb_prf
- wusb_oob_mic_verify
- wusb_key_derive_verify
- wusb_crypto_init
- wusb_crypto_exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <crypto/aes.h>
35 #include <crypto/algapi.h>
36 #include <crypto/hash.h>
37 #include <crypto/skcipher.h>
38 #include <linux/crypto.h>
39 #include <linux/module.h>
40 #include <linux/err.h>
41 #include <linux/slab.h>
42 #include <linux/scatterlist.h>
43 #include "../uwb/uwb.h"
44 #include "include/wusb.h"
45
46 static int debug_crypto_verify;
47
48 module_param(debug_crypto_verify, int, 0);
49 MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms");
50
51 static void wusb_key_dump(const void *buf, size_t len)
52 {
53 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_OFFSET, 16, 1,
54 buf, len, 0);
55 }
56
57
58
59
60
61
62
63
64 struct aes_ccm_block {
65 u8 data[16];
66 } __attribute__((packed));
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 struct aes_ccm_b0 {
86 u8 flags;
87 struct aes_ccm_nonce ccm_nonce;
88 __be16 lm;
89 } __attribute__((packed));
90
91
92 struct aes_ccm_b1 {
93 __be16 la;
94 u8 mac_header[10];
95 __le16 eo;
96 u8 security_reserved;
97 u8 padding;
98 } __attribute__((packed));
99
100
101
102
103
104
105
106
107
108
109 struct aes_ccm_a {
110 u8 flags;
111 struct aes_ccm_nonce ccm_nonce;
112 __be16 counter;
113 } __attribute__((packed));
114
115
116 struct wusb_mac_scratch {
117 struct aes_ccm_b0 b0;
118 struct aes_ccm_b1 b1;
119 struct aes_ccm_a ax;
120 };
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 static int wusb_ccm_mac(struct crypto_shash *tfm_cbcmac,
179 struct wusb_mac_scratch *scratch,
180 void *mic,
181 const struct aes_ccm_nonce *n,
182 const struct aes_ccm_label *a, const void *b,
183 size_t blen)
184 {
185 SHASH_DESC_ON_STACK(desc, tfm_cbcmac);
186 u8 iv[AES_BLOCK_SIZE];
187
188
189
190
191
192 BUILD_BUG_ON(sizeof(*a) != sizeof(scratch->b1) - sizeof(scratch->b1.la));
193 BUILD_BUG_ON(sizeof(scratch->b0) != sizeof(struct aes_ccm_block));
194 BUILD_BUG_ON(sizeof(scratch->b1) != sizeof(struct aes_ccm_block));
195 BUILD_BUG_ON(sizeof(scratch->ax) != sizeof(struct aes_ccm_block));
196
197
198 scratch->b0.flags = 0x59;
199 scratch->b0.ccm_nonce = *n;
200 scratch->b0.lm = cpu_to_be16(0);
201
202
203
204
205
206
207
208
209 scratch->b1.la = cpu_to_be16(blen + 14);
210 memcpy(&scratch->b1.mac_header, a, sizeof(*a));
211
212 desc->tfm = tfm_cbcmac;
213 crypto_shash_init(desc);
214 crypto_shash_update(desc, (u8 *)&scratch->b0, sizeof(scratch->b0) +
215 sizeof(scratch->b1));
216 crypto_shash_finup(desc, b, blen, iv);
217
218
219
220
221
222
223 scratch->ax.flags = 0x01;
224 scratch->ax.ccm_nonce = *n;
225 scratch->ax.counter = 0;
226
227
228 crypto_shash_digest(desc, (u8 *)&scratch->ax, sizeof(scratch->ax),
229 (u8 *)&scratch->ax);
230
231 crypto_xor_cpy(mic, (u8 *)&scratch->ax, iv, 8);
232
233 return 8;
234 }
235
236
237
238
239
240
241
242 ssize_t wusb_prf(void *out, size_t out_size,
243 const u8 key[16], const struct aes_ccm_nonce *_n,
244 const struct aes_ccm_label *a,
245 const void *b, size_t blen, size_t len)
246 {
247 ssize_t result, bytes = 0, bitr;
248 struct aes_ccm_nonce n = *_n;
249 struct crypto_shash *tfm_cbcmac;
250 struct wusb_mac_scratch scratch;
251 u64 sfn = 0;
252 __le64 sfn_le;
253
254 tfm_cbcmac = crypto_alloc_shash("cbcmac(aes)", 0, 0);
255 if (IS_ERR(tfm_cbcmac)) {
256 result = PTR_ERR(tfm_cbcmac);
257 printk(KERN_ERR "E: can't load CBCMAC-AES: %d\n", (int)result);
258 goto error_alloc_cbcmac;
259 }
260
261 result = crypto_shash_setkey(tfm_cbcmac, key, AES_BLOCK_SIZE);
262 if (result < 0) {
263 printk(KERN_ERR "E: can't set CBCMAC-AES key: %d\n", (int)result);
264 goto error_setkey_cbcmac;
265 }
266
267 for (bitr = 0; bitr < (len + 63) / 64; bitr++) {
268 sfn_le = cpu_to_le64(sfn++);
269 memcpy(&n.sfn, &sfn_le, sizeof(n.sfn));
270 result = wusb_ccm_mac(tfm_cbcmac, &scratch, out + bytes,
271 &n, a, b, blen);
272 if (result < 0)
273 goto error_ccm_mac;
274 bytes += result;
275 }
276 result = bytes;
277
278 error_ccm_mac:
279 error_setkey_cbcmac:
280 crypto_free_shash(tfm_cbcmac);
281 error_alloc_cbcmac:
282 return result;
283 }
284
285
286 static const u8 stv_hsmic_key[16] = {
287 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
288 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
289 };
290
291 static const struct aes_ccm_nonce stv_hsmic_n = {
292 .sfn = { 0 },
293 .tkid = { 0x76, 0x98, 0x01, },
294 .dest_addr = { .data = { 0xbe, 0x00 } },
295 .src_addr = { .data = { 0x76, 0x98 } },
296 };
297
298
299
300
301
302 static int wusb_oob_mic_verify(void)
303 {
304 int result;
305 u8 mic[8];
306
307 static const struct usb_handshake stv_hsmic_hs = {
308 .bMessageNumber = 2,
309 .bStatus = 00,
310 .tTKID = { 0x76, 0x98, 0x01 },
311 .bReserved = 00,
312 .CDID = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
313 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
314 0x3c, 0x3d, 0x3e, 0x3f },
315 .nonce = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
316 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
317 0x2c, 0x2d, 0x2e, 0x2f },
318 .MIC = { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
319 0x14, 0x7b },
320 };
321 size_t hs_size;
322
323 result = wusb_oob_mic(mic, stv_hsmic_key, &stv_hsmic_n, &stv_hsmic_hs);
324 if (result < 0)
325 printk(KERN_ERR "E: WUSB OOB MIC test: failed: %d\n", result);
326 else if (memcmp(stv_hsmic_hs.MIC, mic, sizeof(mic))) {
327 printk(KERN_ERR "E: OOB MIC test: "
328 "mismatch between MIC result and WUSB1.0[A2]\n");
329 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC);
330 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size);
331 wusb_key_dump(&stv_hsmic_hs, hs_size);
332 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n",
333 sizeof(stv_hsmic_n));
334 wusb_key_dump(&stv_hsmic_n, sizeof(stv_hsmic_n));
335 printk(KERN_ERR "E: MIC out:\n");
336 wusb_key_dump(mic, sizeof(mic));
337 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n");
338 wusb_key_dump(stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC));
339 result = -EINVAL;
340 } else
341 result = 0;
342 return result;
343 }
344
345
346
347
348
349
350
351 static const u8 stv_key_a1[16] __attribute__ ((__aligned__(4))) = {
352 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
353 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
354 };
355
356 static const struct aes_ccm_nonce stv_keydvt_n_a1 = {
357 .sfn = { 0 },
358 .tkid = { 0x76, 0x98, 0x01, },
359 .dest_addr = { .data = { 0xbe, 0x00 } },
360 .src_addr = { .data = { 0x76, 0x98 } },
361 };
362
363 static const struct wusb_keydvt_out stv_keydvt_out_a1 = {
364 .kck = {
365 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
366 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
367 },
368 .ptk = {
369 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06,
370 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d
371 }
372 };
373
374
375
376
377
378 static int wusb_key_derive_verify(void)
379 {
380 int result = 0;
381 struct wusb_keydvt_out keydvt_out;
382
383 static const struct wusb_keydvt_in stv_keydvt_in_a1 = {
384 .hnonce = {
385 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
386 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
387 },
388 .dnonce = {
389 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
390 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
391 }
392 };
393
394 result = wusb_key_derive(&keydvt_out, stv_key_a1, &stv_keydvt_n_a1,
395 &stv_keydvt_in_a1);
396 if (result < 0)
397 printk(KERN_ERR "E: WUSB key derivation test: "
398 "derivation failed: %d\n", result);
399 if (memcmp(&stv_keydvt_out_a1, &keydvt_out, sizeof(keydvt_out))) {
400 printk(KERN_ERR "E: WUSB key derivation test: "
401 "mismatch between key derivation result "
402 "and WUSB1.0[A1] Errata 2006/12\n");
403 printk(KERN_ERR "E: keydvt in: key\n");
404 wusb_key_dump(stv_key_a1, sizeof(stv_key_a1));
405 printk(KERN_ERR "E: keydvt in: nonce\n");
406 wusb_key_dump(&stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
407 printk(KERN_ERR "E: keydvt in: hnonce & dnonce\n");
408 wusb_key_dump(&stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
409 printk(KERN_ERR "E: keydvt out: KCK\n");
410 wusb_key_dump(&keydvt_out.kck, sizeof(keydvt_out.kck));
411 printk(KERN_ERR "E: keydvt out: PTK\n");
412 wusb_key_dump(&keydvt_out.ptk, sizeof(keydvt_out.ptk));
413 result = -EINVAL;
414 } else
415 result = 0;
416 return result;
417 }
418
419
420
421
422
423
424
425 int wusb_crypto_init(void)
426 {
427 int result;
428
429 if (debug_crypto_verify) {
430 result = wusb_key_derive_verify();
431 if (result < 0)
432 return result;
433 return wusb_oob_mic_verify();
434 }
435 return 0;
436 }
437
438 void wusb_crypto_exit(void)
439 {
440
441 }