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