3 * AES-128 CCM Encryption
5 * Copyright (C) 2007 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * We don't do any encryption here; we use the Linux Kernel's AES-128
24 * crypto modules to construct keys and payload blocks in a way
25 * defined by WUSB1.0[6]. Check the erratas, as typos are are patched
28 * Thanks a zillion to John Keys for his help and clarifications over
29 * the designed-by-a-committee text.
31 * So the idea is that there is this basic Pseudo-Random-Function
32 * defined in WUSB1.0[6.5] which is the core of everything. It works
33 * by tweaking some blocks, AES crypting them and then xoring
34 * something else with them (this seems to be called CBC(AES) -- can
35 * you tell I know jack about crypto?). So we just funnel it into the
38 * We leave a crypto test module so we can verify that vectors match,
41 * Block size: 16 bytes -- AES seems to do things in 'block sizes'. I
42 * am learning a lot...
44 * Conveniently, some data structures that need to be
45 * funneled through AES are...16 bytes in size!
48 #include <linux/crypto.h>
49 #include <linux/module.h>
50 #include <linux/err.h>
51 #include <linux/uwb.h>
52 #include <linux/usb/wusb.h>
53 #include <linux/scatterlist.h>
55 #include <linux/uwb/debug.h>
57 static int debug_crypto_verify = 0;
59 module_param(debug_crypto_verify, int, 0);
60 MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms");
63 * Block of data, as understood by AES-CCM
65 * The code assumes this structure is nothing but a 16 byte array
66 * (packed in a struct to avoid common mess ups that I usually do with
67 * arrays and enforcing type checking).
69 struct aes_ccm_block {
71 } __attribute__((packed));
74 * Counter-mode Blocks (WUSB1.0[6.4])
76 * According to CCM (or so it seems), for the purpose of calculating
77 * the MIC, the message is broken in N counter-mode blocks, B0, B1,
80 * B0 contains flags, the CCM nonce and l(m).
82 * B1 contains l(a), the MAC header, the encryption offset and padding.
84 * If EO is nonzero, additional blocks are built from payload bytes
85 * until EO is exahusted (FIXME: padding to 16 bytes, I guess). The
86 * padding is not xmitted.
91 u8 flags; /* 0x59, per CCM spec */
92 struct aes_ccm_nonce ccm_nonce;
94 } __attribute__((packed));
101 u8 security_reserved; /* This is always zero */
103 } __attribute__((packed));
106 * Encryption Blocks (WUSB1.0[6.4.4])
108 * CCM uses Ax blocks to generate a keystream with which the MIC and
109 * the message's payload are encoded. A0 always encrypts/decrypts the
110 * MIC. Ax (x>0) are used for the sucesive payload blocks.
112 * The x is the counter, and is increased for each block.
115 u8 flags; /* 0x01, per CCM spec */
116 struct aes_ccm_nonce ccm_nonce;
117 __be16 counter; /* Value of x */
118 } __attribute__((packed));
120 static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2,
124 const u8 *bi1 = _bi1, *bi2 = _bi2;
126 for (itr = 0; itr < size; itr++)
127 bo[itr] = bi1[itr] ^ bi2[itr];
131 * CC-MAC function WUSB1.0[6.5]
133 * Take a data string and produce the encrypted CBC Counter-mode MIC
135 * Note the names for most function arguments are made to (more or
136 * less) match those used in the pseudo-function definition given in
139 * @tfm_cbc: CBC(AES) blkcipher handle (initialized)
141 * @tfm_aes: AES cipher handle (initialized)
143 * @mic: buffer for placing the computed MIC (Message Integrity
144 * Code). This is exactly 8 bytes, and we expect the buffer to
145 * be at least eight bytes in length.
147 * @key: 128 bit symmetric key
151 * @a: ASCII string, 14 bytes long (I guess zero padded if needed;
152 * we use exactly 14 bytes).
154 * @b: data stream to be processed; cannot be a global or const local
155 * (will confuse the scatterlists)
157 * @blen: size of b...
159 * Still not very clear how this is done, but looks like this: we
160 * create block B0 (as WUSB1.0[6.5] says), then we AES-crypt it with
161 * @key. We bytewise xor B0 with B1 (1) and AES-crypt that. Then we
162 * take the payload and divide it in blocks (16 bytes), xor them with
163 * the previous crypto result (16 bytes) and crypt it, repeat the next
164 * block with the output of the previous one, rinse wash (I guess this
165 * is what AES CBC mode means...but I truly have no idea). So we use
166 * the CBC(AES) blkcipher, that does precisely that. The IV (Initial
167 * Vector) is 16 bytes and is set to zero, so
169 * See rfc3610. Linux crypto has a CBC implementation, but the
170 * documentation is scarce, to say the least, and the example code is
171 * so intricated that is difficult to understand how things work. Most
172 * of this is guess work -- bite me.
174 * (1) Created as 6.5 says, again, using as l(a) 'Blen + 14', and
175 * using the 14 bytes of @a to fill up
176 * b1.{mac_header,e0,security_reserved,padding}.
178 * NOTE: The definiton of l(a) in WUSB1.0[6.5] vs the definition of
179 * l(m) is orthogonal, they bear no relationship, so it is not
180 * in conflict with the parameter's relation that
181 * WUSB1.0[6.4.2]) defines.
183 * NOTE: WUSB1.0[A.1]: Host Nonce is missing a nibble? (1e); fixed in
184 * first errata released on 2005/07.
186 * NOTE: we need to clean IV to zero at each invocation to make sure
187 * we start with a fresh empty Initial Vector, so that the CBC
190 * NOTE: blen is not aligned to a block size, we'll pad zeros, that's
191 * what sg[4] is for. Maybe there is a smarter way to do this.
193 static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
194 struct crypto_cipher *tfm_aes, void *mic,
195 const struct aes_ccm_nonce *n,
196 const struct aes_ccm_label *a, const void *b,
200 struct blkcipher_desc desc;
201 struct aes_ccm_b0 b0;
202 struct aes_ccm_b1 b1;
204 struct scatterlist sg[4], sg_dst;
206 size_t ivsize, dst_size;
207 const u8 bzero[16] = { 0 };
210 d_fnstart(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
211 "n %p, a %p, b %p, blen %zu)\n",
212 tfm_cbc, tfm_aes, mic, n, a, b, blen);
214 * These checks should be compile time optimized out
215 * ensure @a fills b1's mac_header and following fields
217 WARN_ON(sizeof(*a) != sizeof(b1) - sizeof(b1.la));
218 WARN_ON(sizeof(b0) != sizeof(struct aes_ccm_block));
219 WARN_ON(sizeof(b1) != sizeof(struct aes_ccm_block));
220 WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block));
223 zero_padding = sizeof(struct aes_ccm_block)
224 - blen % sizeof(struct aes_ccm_block);
225 zero_padding = blen % sizeof(struct aes_ccm_block);
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");
235 iv = crypto_blkcipher_crt(tfm_cbc)->iv;
236 ivsize = crypto_blkcipher_ivsize(tfm_cbc);
237 memset(iv, 0, ivsize);
240 b0.flags = 0x59; /* Format B0 */
242 b0.lm = cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */
246 * The WUSB spec is anything but clear! WUSB1.0[6.5]
247 * says that to initialize B1 from A with 'l(a) = blen +
248 * 14'--after clarification, it means to use A's contents
249 * for MAC Header, EO, sec reserved and padding.
251 b1.la = cpu_to_be16(blen + 14);
252 memcpy(&b1.mac_header, a, sizeof(*a));
254 d_printf(4, NULL, "I: B0 (%zu bytes)\n", sizeof(b0));
255 d_dump(4, NULL, &b0, sizeof(b0));
256 d_printf(4, NULL, "I: B1 (%zu bytes)\n", sizeof(b1));
257 d_dump(4, NULL, &b1, sizeof(b1));
258 d_printf(4, NULL, "I: B (%zu bytes)\n", blen);
259 d_dump(4, NULL, b, blen);
260 d_printf(4, NULL, "I: B 0-padding (%zu bytes)\n", zero_padding);
261 d_printf(4, NULL, "D: IV before crypto (%zu)\n", ivsize);
262 d_dump(4, NULL, iv, ivsize);
264 sg_init_table(sg, ARRAY_SIZE(sg));
265 sg_set_buf(&sg[0], &b0, sizeof(b0));
266 sg_set_buf(&sg[1], &b1, sizeof(b1));
267 sg_set_buf(&sg[2], b, blen);
268 /* 0 if well behaved :) */
269 sg_set_buf(&sg[3], bzero, zero_padding);
270 sg_init_one(&sg_dst, dst_buf, dst_size);
274 result = crypto_blkcipher_encrypt(&desc, &sg_dst, sg, dst_size);
276 printk(KERN_ERR "E: can't compute CBC-MAC tag (MIC): %d\n",
278 goto error_cbc_crypt;
280 d_printf(4, NULL, "D: MIC tag\n");
281 d_dump(4, NULL, iv, ivsize);
283 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5]
284 * The procedure is to AES crypt the A0 block and XOR the MIC
285 * Tag agains it; we only do the first 8 bytes and place it
286 * directly in the destination buffer.
288 * POS Crypto API: size is assumed to be AES's block size.
289 * Thanks for documenting it -- tip taken from airo.c
291 ax.flags = 0x01; /* as per WUSB 1.0 spec */
294 crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax);
295 bytewise_xor(mic, &ax, iv, 8);
296 d_printf(4, NULL, "D: CTR[MIC]\n");
297 d_dump(4, NULL, &ax, 8);
298 d_printf(4, NULL, "D: CCM-MIC tag\n");
299 d_dump(4, NULL, mic, 8);
304 d_fnend(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
305 "n %p, a %p, b %p, blen %zu)\n",
306 tfm_cbc, tfm_aes, mic, n, a, b, blen);
311 * WUSB Pseudo Random Function (WUSB1.0[6.5])
313 * @b: buffer to the source data; cannot be a global or const local
314 * (will confuse the scatterlists)
316 ssize_t wusb_prf(void *out, size_t out_size,
317 const u8 key[16], const struct aes_ccm_nonce *_n,
318 const struct aes_ccm_label *a,
319 const void *b, size_t blen, size_t len)
321 ssize_t result, bytes = 0, bitr;
322 struct aes_ccm_nonce n = *_n;
323 struct crypto_blkcipher *tfm_cbc;
324 struct crypto_cipher *tfm_aes;
328 d_fnstart(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
329 "a %p, b %p, blen %zu, len %zu)\n", out, out_size,
330 key, _n, a, b, blen, len);
332 tfm_cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
333 if (IS_ERR(tfm_cbc)) {
334 result = PTR_ERR(tfm_cbc);
335 printk(KERN_ERR "E: can't load CBC(AES): %d\n", (int)result);
336 goto error_alloc_cbc;
338 result = crypto_blkcipher_setkey(tfm_cbc, key, 16);
340 printk(KERN_ERR "E: can't set CBC key: %d\n", (int)result);
341 goto error_setkey_cbc;
344 tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
345 if (IS_ERR(tfm_aes)) {
346 result = PTR_ERR(tfm_aes);
347 printk(KERN_ERR "E: can't load AES: %d\n", (int)result);
348 goto error_alloc_aes;
350 result = crypto_cipher_setkey(tfm_aes, key, 16);
352 printk(KERN_ERR "E: can't set AES key: %d\n", (int)result);
353 goto error_setkey_aes;
356 for (bitr = 0; bitr < (len + 63) / 64; bitr++) {
357 sfn_le = cpu_to_le64(sfn++);
358 memcpy(&n.sfn, &sfn_le, sizeof(n.sfn)); /* n.sfn++... */
359 result = wusb_ccm_mac(tfm_cbc, tfm_aes, out + bytes,
368 crypto_free_cipher(tfm_aes);
371 crypto_free_blkcipher(tfm_cbc);
373 d_fnend(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
374 "a %p, b %p, blen %zu, len %zu) = %d\n", out, out_size,
375 key, _n, a, b, blen, len, (int)bytes);
379 /* WUSB1.0[A.2] test vectors */
380 static const u8 stv_hsmic_key[16] = {
381 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
382 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
385 static const struct aes_ccm_nonce stv_hsmic_n = {
387 .tkid = { 0x76, 0x98, 0x01, },
388 .dest_addr = { .data = { 0xbe, 0x00 } },
389 .src_addr = { .data = { 0x76, 0x98 } },
393 * Out-of-band MIC Generation verification code
396 static int wusb_oob_mic_verify(void)
400 /* WUSB1.0[A.2] test vectors
402 * Need to keep it in the local stack as GCC 4.1.3something
403 * messes up and generates noise.
405 struct usb_handshake stv_hsmic_hs = {
408 .tTKID = { 0x76, 0x98, 0x01 },
410 .CDID = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
411 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
412 0x3c, 0x3d, 0x3e, 0x3f },
413 .nonce = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
414 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
415 0x2c, 0x2d, 0x2e, 0x2f },
416 .MIC = { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
421 result = wusb_oob_mic(mic, stv_hsmic_key, &stv_hsmic_n, &stv_hsmic_hs);
423 printk(KERN_ERR "E: WUSB OOB MIC test: failed: %d\n", result);
424 else if (memcmp(stv_hsmic_hs.MIC, mic, sizeof(mic))) {
425 printk(KERN_ERR "E: OOB MIC test: "
426 "mismatch between MIC result and WUSB1.0[A2]\n");
427 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC);
428 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size);
429 dump_bytes(NULL, &stv_hsmic_hs, hs_size);
430 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n",
431 sizeof(stv_hsmic_n));
432 dump_bytes(NULL, &stv_hsmic_n, sizeof(stv_hsmic_n));
433 printk(KERN_ERR "E: MIC out:\n");
434 dump_bytes(NULL, mic, sizeof(mic));
435 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n");
436 dump_bytes(NULL, stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC));
444 * Test vectors for Key derivation
446 * These come from WUSB1.0[6.5.1], the vectors in WUSB1.0[A.1]
447 * (errata corrected in 2005/07).
449 static const u8 stv_key_a1[16] __attribute__ ((__aligned__(4))) = {
450 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
451 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
454 static const struct aes_ccm_nonce stv_keydvt_n_a1 = {
456 .tkid = { 0x76, 0x98, 0x01, },
457 .dest_addr = { .data = { 0xbe, 0x00 } },
458 .src_addr = { .data = { 0x76, 0x98 } },
461 static const struct wusb_keydvt_out stv_keydvt_out_a1 = {
463 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
464 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
467 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06,
468 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d
473 * Performa a test to make sure we match the vectors defined in
474 * WUSB1.0[A.1](Errata2006/12)
476 static int wusb_key_derive_verify(void)
479 struct wusb_keydvt_out keydvt_out;
480 /* These come from WUSB1.0[A.1] + 2006/12 errata
481 * NOTE: can't make this const or global -- somehow it seems
482 * the scatterlists for crypto get confused and we get
483 * bad data. There is no doc on this... */
484 struct wusb_keydvt_in stv_keydvt_in_a1 = {
486 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
487 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
490 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
491 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
495 result = wusb_key_derive(&keydvt_out, stv_key_a1, &stv_keydvt_n_a1,
498 printk(KERN_ERR "E: WUSB key derivation test: "
499 "derivation failed: %d\n", result);
500 if (memcmp(&stv_keydvt_out_a1, &keydvt_out, sizeof(keydvt_out))) {
501 printk(KERN_ERR "E: WUSB key derivation test: "
502 "mismatch between key derivation result "
503 "and WUSB1.0[A1] Errata 2006/12\n");
504 printk(KERN_ERR "E: keydvt in: key (%zu bytes)\n",
506 dump_bytes(NULL, stv_key_a1, sizeof(stv_key_a1));
507 printk(KERN_ERR "E: keydvt in: nonce (%zu bytes)\n",
508 sizeof(stv_keydvt_n_a1));
509 dump_bytes(NULL, &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
510 printk(KERN_ERR "E: keydvt in: hnonce & dnonce (%zu bytes)\n",
511 sizeof(stv_keydvt_in_a1));
512 dump_bytes(NULL, &stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
513 printk(KERN_ERR "E: keydvt out: KCK\n");
514 dump_bytes(NULL, &keydvt_out.kck, sizeof(keydvt_out.kck));
515 printk(KERN_ERR "E: keydvt out: PTK\n");
516 dump_bytes(NULL, &keydvt_out.ptk, sizeof(keydvt_out.ptk));
524 * Initialize crypto system
526 * FIXME: we do nothing now, other than verifying. Later on we'll
527 * cache the encryption stuff, so that's why we have a separate init.
529 int wusb_crypto_init(void)
533 if (debug_crypto_verify) {
534 result = wusb_key_derive_verify();
537 return wusb_oob_mic_verify();
542 void wusb_crypto_exit(void)
544 /* FIXME: free cached crypto transforms */