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