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
35
36
37
38
39
40
41
42
43
44
45
46
47
48#include <crypto/skcipher.h>
49#include <linux/crypto.h>
50#include <linux/module.h>
51#include <linux/err.h>
52#include <linux/uwb.h>
53#include <linux/slab.h>
54#include <linux/usb/wusb.h>
55#include <linux/scatterlist.h>
56
57static int debug_crypto_verify;
58
59module_param(debug_crypto_verify, int, 0);
60MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms");
61
62static void wusb_key_dump(const void *buf, size_t len)
63{
64 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_OFFSET, 16, 1,
65 buf, len, 0);
66}
67
68
69
70
71
72
73
74
75struct aes_ccm_block {
76 u8 data[16];
77} __attribute__((packed));
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96struct aes_ccm_b0 {
97 u8 flags;
98 struct aes_ccm_nonce ccm_nonce;
99 __be16 lm;
100} __attribute__((packed));
101
102
103struct aes_ccm_b1 {
104 __be16 la;
105 u8 mac_header[10];
106 __le16 eo;
107 u8 security_reserved;
108 u8 padding;
109} __attribute__((packed));
110
111
112
113
114
115
116
117
118
119
120struct aes_ccm_a {
121 u8 flags;
122 struct aes_ccm_nonce ccm_nonce;
123 __be16 counter;
124} __attribute__((packed));
125
126static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2,
127 size_t size)
128{
129 u8 *bo = _bo;
130 const u8 *bi1 = _bi1, *bi2 = _bi2;
131 size_t itr;
132 for (itr = 0; itr < size; itr++)
133 bo[itr] = bi1[itr] ^ bi2[itr];
134}
135
136
137struct wusb_mac_scratch {
138 struct aes_ccm_b0 b0;
139 struct aes_ccm_b1 b1;
140 struct aes_ccm_a ax;
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc,
207 struct crypto_cipher *tfm_aes,
208 struct wusb_mac_scratch *scratch,
209 void *mic,
210 const struct aes_ccm_nonce *n,
211 const struct aes_ccm_label *a, const void *b,
212 size_t blen)
213{
214 int result = 0;
215 SKCIPHER_REQUEST_ON_STACK(req, tfm_cbc);
216 struct scatterlist sg[4], sg_dst;
217 void *dst_buf;
218 size_t dst_size;
219 const u8 bzero[16] = { 0 };
220 u8 iv[crypto_skcipher_ivsize(tfm_cbc)];
221 size_t zero_padding;
222
223
224
225
226
227 WARN_ON(sizeof(*a) != sizeof(scratch->b1) - sizeof(scratch->b1.la));
228 WARN_ON(sizeof(scratch->b0) != sizeof(struct aes_ccm_block));
229 WARN_ON(sizeof(scratch->b1) != sizeof(struct aes_ccm_block));
230 WARN_ON(sizeof(scratch->ax) != sizeof(struct aes_ccm_block));
231
232 result = -ENOMEM;
233 zero_padding = blen % sizeof(struct aes_ccm_block);
234 if (zero_padding)
235 zero_padding = sizeof(struct aes_ccm_block) - zero_padding;
236 dst_size = blen + sizeof(scratch->b0) + sizeof(scratch->b1) +
237 zero_padding;
238 dst_buf = kzalloc(dst_size, GFP_KERNEL);
239 if (!dst_buf)
240 goto error_dst_buf;
241
242 memset(iv, 0, sizeof(iv));
243
244
245 scratch->b0.flags = 0x59;
246 scratch->b0.ccm_nonce = *n;
247 scratch->b0.lm = cpu_to_be16(0);
248
249
250
251
252
253
254
255
256 scratch->b1.la = cpu_to_be16(blen + 14);
257 memcpy(&scratch->b1.mac_header, a, sizeof(*a));
258
259 sg_init_table(sg, ARRAY_SIZE(sg));
260 sg_set_buf(&sg[0], &scratch->b0, sizeof(scratch->b0));
261 sg_set_buf(&sg[1], &scratch->b1, sizeof(scratch->b1));
262 sg_set_buf(&sg[2], b, blen);
263
264 sg_set_buf(&sg[3], bzero, zero_padding);
265 sg_init_one(&sg_dst, dst_buf, dst_size);
266
267 skcipher_request_set_tfm(req, tfm_cbc);
268 skcipher_request_set_callback(req, 0, NULL, NULL);
269 skcipher_request_set_crypt(req, sg, &sg_dst, dst_size, iv);
270 result = crypto_skcipher_encrypt(req);
271 skcipher_request_zero(req);
272 if (result < 0) {
273 printk(KERN_ERR "E: can't compute CBC-MAC tag (MIC): %d\n",
274 result);
275 goto error_cbc_crypt;
276 }
277
278
279
280
281
282
283
284
285
286 scratch->ax.flags = 0x01;
287 scratch->ax.ccm_nonce = *n;
288 scratch->ax.counter = 0;
289 crypto_cipher_encrypt_one(tfm_aes, (void *)&scratch->ax,
290 (void *)&scratch->ax);
291 bytewise_xor(mic, &scratch->ax, iv, 8);
292 result = 8;
293error_cbc_crypt:
294 kfree(dst_buf);
295error_dst_buf:
296 return result;
297}
298
299
300
301
302
303
304
305ssize_t wusb_prf(void *out, size_t out_size,
306 const u8 key[16], const struct aes_ccm_nonce *_n,
307 const struct aes_ccm_label *a,
308 const void *b, size_t blen, size_t len)
309{
310 ssize_t result, bytes = 0, bitr;
311 struct aes_ccm_nonce n = *_n;
312 struct crypto_skcipher *tfm_cbc;
313 struct crypto_cipher *tfm_aes;
314 struct wusb_mac_scratch *scratch;
315 u64 sfn = 0;
316 __le64 sfn_le;
317
318 tfm_cbc = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
319 if (IS_ERR(tfm_cbc)) {
320 result = PTR_ERR(tfm_cbc);
321 printk(KERN_ERR "E: can't load CBC(AES): %d\n", (int)result);
322 goto error_alloc_cbc;
323 }
324 result = crypto_skcipher_setkey(tfm_cbc, key, 16);
325 if (result < 0) {
326 printk(KERN_ERR "E: can't set CBC key: %d\n", (int)result);
327 goto error_setkey_cbc;
328 }
329
330 tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
331 if (IS_ERR(tfm_aes)) {
332 result = PTR_ERR(tfm_aes);
333 printk(KERN_ERR "E: can't load AES: %d\n", (int)result);
334 goto error_alloc_aes;
335 }
336 result = crypto_cipher_setkey(tfm_aes, key, 16);
337 if (result < 0) {
338 printk(KERN_ERR "E: can't set AES key: %d\n", (int)result);
339 goto error_setkey_aes;
340 }
341 scratch = kmalloc(sizeof(*scratch), GFP_KERNEL);
342 if (!scratch) {
343 result = -ENOMEM;
344 goto error_alloc_scratch;
345 }
346
347 for (bitr = 0; bitr < (len + 63) / 64; bitr++) {
348 sfn_le = cpu_to_le64(sfn++);
349 memcpy(&n.sfn, &sfn_le, sizeof(n.sfn));
350 result = wusb_ccm_mac(tfm_cbc, tfm_aes, scratch, out + bytes,
351 &n, a, b, blen);
352 if (result < 0)
353 goto error_ccm_mac;
354 bytes += result;
355 }
356 result = bytes;
357
358 kfree(scratch);
359error_alloc_scratch:
360error_ccm_mac:
361error_setkey_aes:
362 crypto_free_cipher(tfm_aes);
363error_alloc_aes:
364error_setkey_cbc:
365 crypto_free_skcipher(tfm_cbc);
366error_alloc_cbc:
367 return result;
368}
369
370
371static const u8 stv_hsmic_key[16] = {
372 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
373 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
374};
375
376static const struct aes_ccm_nonce stv_hsmic_n = {
377 .sfn = { 0 },
378 .tkid = { 0x76, 0x98, 0x01, },
379 .dest_addr = { .data = { 0xbe, 0x00 } },
380 .src_addr = { .data = { 0x76, 0x98 } },
381};
382
383
384
385
386
387static int wusb_oob_mic_verify(void)
388{
389 int result;
390 u8 mic[8];
391
392
393
394
395
396 struct usb_handshake stv_hsmic_hs = {
397 .bMessageNumber = 2,
398 .bStatus = 00,
399 .tTKID = { 0x76, 0x98, 0x01 },
400 .bReserved = 00,
401 .CDID = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
402 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
403 0x3c, 0x3d, 0x3e, 0x3f },
404 .nonce = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
405 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
406 0x2c, 0x2d, 0x2e, 0x2f },
407 .MIC = { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
408 0x14, 0x7b },
409 };
410 size_t hs_size;
411
412 result = wusb_oob_mic(mic, stv_hsmic_key, &stv_hsmic_n, &stv_hsmic_hs);
413 if (result < 0)
414 printk(KERN_ERR "E: WUSB OOB MIC test: failed: %d\n", result);
415 else if (memcmp(stv_hsmic_hs.MIC, mic, sizeof(mic))) {
416 printk(KERN_ERR "E: OOB MIC test: "
417 "mismatch between MIC result and WUSB1.0[A2]\n");
418 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC);
419 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size);
420 wusb_key_dump(&stv_hsmic_hs, hs_size);
421 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n",
422 sizeof(stv_hsmic_n));
423 wusb_key_dump(&stv_hsmic_n, sizeof(stv_hsmic_n));
424 printk(KERN_ERR "E: MIC out:\n");
425 wusb_key_dump(mic, sizeof(mic));
426 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n");
427 wusb_key_dump(stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC));
428 result = -EINVAL;
429 } else
430 result = 0;
431 return result;
432}
433
434
435
436
437
438
439
440static const u8 stv_key_a1[16] __attribute__ ((__aligned__(4))) = {
441 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
442 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
443};
444
445static const struct aes_ccm_nonce stv_keydvt_n_a1 = {
446 .sfn = { 0 },
447 .tkid = { 0x76, 0x98, 0x01, },
448 .dest_addr = { .data = { 0xbe, 0x00 } },
449 .src_addr = { .data = { 0x76, 0x98 } },
450};
451
452static const struct wusb_keydvt_out stv_keydvt_out_a1 = {
453 .kck = {
454 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
455 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
456 },
457 .ptk = {
458 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06,
459 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d
460 }
461};
462
463
464
465
466
467static int wusb_key_derive_verify(void)
468{
469 int result = 0;
470 struct wusb_keydvt_out keydvt_out;
471
472
473
474
475 struct wusb_keydvt_in stv_keydvt_in_a1 = {
476 .hnonce = {
477 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
478 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
479 },
480 .dnonce = {
481 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
482 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
483 }
484 };
485
486 result = wusb_key_derive(&keydvt_out, stv_key_a1, &stv_keydvt_n_a1,
487 &stv_keydvt_in_a1);
488 if (result < 0)
489 printk(KERN_ERR "E: WUSB key derivation test: "
490 "derivation failed: %d\n", result);
491 if (memcmp(&stv_keydvt_out_a1, &keydvt_out, sizeof(keydvt_out))) {
492 printk(KERN_ERR "E: WUSB key derivation test: "
493 "mismatch between key derivation result "
494 "and WUSB1.0[A1] Errata 2006/12\n");
495 printk(KERN_ERR "E: keydvt in: key\n");
496 wusb_key_dump(stv_key_a1, sizeof(stv_key_a1));
497 printk(KERN_ERR "E: keydvt in: nonce\n");
498 wusb_key_dump(&stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
499 printk(KERN_ERR "E: keydvt in: hnonce & dnonce\n");
500 wusb_key_dump(&stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
501 printk(KERN_ERR "E: keydvt out: KCK\n");
502 wusb_key_dump(&keydvt_out.kck, sizeof(keydvt_out.kck));
503 printk(KERN_ERR "E: keydvt out: PTK\n");
504 wusb_key_dump(&keydvt_out.ptk, sizeof(keydvt_out.ptk));
505 result = -EINVAL;
506 } else
507 result = 0;
508 return result;
509}
510
511
512
513
514
515
516
517int wusb_crypto_init(void)
518{
519 int result;
520
521 if (debug_crypto_verify) {
522 result = wusb_key_derive_verify();
523 if (result < 0)
524 return result;
525 return wusb_oob_mic_verify();
526 }
527 return 0;
528}
529
530void wusb_crypto_exit(void)
531{
532
533}
534