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 <linux/crypto.h>
49#include <linux/module.h>
50#include <linux/err.h>
51#include <linux/uwb.h>
52#include <linux/slab.h>
53#include <linux/usb/wusb.h>
54#include <linux/scatterlist.h>
55
56static int debug_crypto_verify = 0;
57
58module_param(debug_crypto_verify, int, 0);
59MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms");
60
61static void wusb_key_dump(const void *buf, size_t len)
62{
63 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_OFFSET, 16, 1,
64 buf, len, 0);
65}
66
67
68
69
70
71
72
73
74struct aes_ccm_block {
75 u8 data[16];
76} __attribute__((packed));
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95struct aes_ccm_b0 {
96 u8 flags;
97 struct aes_ccm_nonce ccm_nonce;
98 __be16 lm;
99} __attribute__((packed));
100
101
102struct aes_ccm_b1 {
103 __be16 la;
104 u8 mac_header[10];
105 __le16 eo;
106 u8 security_reserved;
107 u8 padding;
108} __attribute__((packed));
109
110
111
112
113
114
115
116
117
118
119struct aes_ccm_a {
120 u8 flags;
121 struct aes_ccm_nonce ccm_nonce;
122 __be16 counter;
123} __attribute__((packed));
124
125static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2,
126 size_t size)
127{
128 u8 *bo = _bo;
129 const u8 *bi1 = _bi1, *bi2 = _bi2;
130 size_t itr;
131 for (itr = 0; itr < size; itr++)
132 bo[itr] = bi1[itr] ^ bi2[itr];
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
199 struct crypto_cipher *tfm_aes, void *mic,
200 const struct aes_ccm_nonce *n,
201 const struct aes_ccm_label *a, const void *b,
202 size_t blen)
203{
204 int result = 0;
205 struct blkcipher_desc desc;
206 struct aes_ccm_b0 b0;
207 struct aes_ccm_b1 b1;
208 struct aes_ccm_a ax;
209 struct scatterlist sg[4], sg_dst;
210 void *iv, *dst_buf;
211 size_t ivsize, dst_size;
212 const u8 bzero[16] = { 0 };
213 size_t zero_padding;
214
215
216
217
218
219 WARN_ON(sizeof(*a) != sizeof(b1) - sizeof(b1.la));
220 WARN_ON(sizeof(b0) != sizeof(struct aes_ccm_block));
221 WARN_ON(sizeof(b1) != sizeof(struct aes_ccm_block));
222 WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block));
223
224 result = -ENOMEM;
225 zero_padding = sizeof(struct aes_ccm_block)
226 - blen % sizeof(struct aes_ccm_block);
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 iv = crypto_blkcipher_crt(tfm_cbc)->iv;
238 ivsize = crypto_blkcipher_ivsize(tfm_cbc);
239 memset(iv, 0, ivsize);
240
241
242 b0.flags = 0x59;
243 b0.ccm_nonce = *n;
244 b0.lm = cpu_to_be16(0);
245
246
247
248
249
250
251
252
253 b1.la = cpu_to_be16(blen + 14);
254 memcpy(&b1.mac_header, a, sizeof(*a));
255
256 sg_init_table(sg, ARRAY_SIZE(sg));
257 sg_set_buf(&sg[0], &b0, sizeof(b0));
258 sg_set_buf(&sg[1], &b1, sizeof(b1));
259 sg_set_buf(&sg[2], b, blen);
260
261 sg_set_buf(&sg[3], bzero, zero_padding);
262 sg_init_one(&sg_dst, dst_buf, dst_size);
263
264 desc.tfm = tfm_cbc;
265 desc.flags = 0;
266 result = crypto_blkcipher_encrypt(&desc, &sg_dst, sg, dst_size);
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_blkcipher *tfm_cbc;
307 struct crypto_cipher *tfm_aes;
308 u64 sfn = 0;
309 __le64 sfn_le;
310
311 tfm_cbc = crypto_alloc_blkcipher("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_blkcipher_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_blkcipher(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