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 static int debug_crypto_verify
= 0;
57 module_param(debug_crypto_verify
, int, 0);
58 MODULE_PARM_DESC(debug_crypto_verify
, "verify the key generation algorithms");
60 static void wusb_key_dump(const void *buf
, size_t len
)
62 print_hex_dump(KERN_ERR
, " ", DUMP_PREFIX_OFFSET
, 16, 1,
67 * Block of data, as understood by AES-CCM
69 * The code assumes this structure is nothing but a 16 byte array
70 * (packed in a struct to avoid common mess ups that I usually do with
71 * arrays and enforcing type checking).
73 struct aes_ccm_block
{
75 } __attribute__((packed
));
78 * Counter-mode Blocks (WUSB1.0[6.4])
80 * According to CCM (or so it seems), for the purpose of calculating
81 * the MIC, the message is broken in N counter-mode blocks, B0, B1,
84 * B0 contains flags, the CCM nonce and l(m).
86 * B1 contains l(a), the MAC header, the encryption offset and padding.
88 * If EO is nonzero, additional blocks are built from payload bytes
89 * until EO is exahusted (FIXME: padding to 16 bytes, I guess). The
90 * padding is not xmitted.
95 u8 flags
; /* 0x59, per CCM spec */
96 struct aes_ccm_nonce ccm_nonce
;
98 } __attribute__((packed
));
105 u8 security_reserved
; /* This is always zero */
107 } __attribute__((packed
));
110 * Encryption Blocks (WUSB1.0[6.4.4])
112 * CCM uses Ax blocks to generate a keystream with which the MIC and
113 * the message's payload are encoded. A0 always encrypts/decrypts the
114 * MIC. Ax (x>0) are used for the sucesive payload blocks.
116 * The x is the counter, and is increased for each block.
119 u8 flags
; /* 0x01, per CCM spec */
120 struct aes_ccm_nonce ccm_nonce
;
121 __be16 counter
; /* Value of x */
122 } __attribute__((packed
));
124 static void bytewise_xor(void *_bo
, const void *_bi1
, const void *_bi2
,
128 const u8
*bi1
= _bi1
, *bi2
= _bi2
;
130 for (itr
= 0; itr
< size
; itr
++)
131 bo
[itr
] = bi1
[itr
] ^ bi2
[itr
];
135 * CC-MAC function WUSB1.0[6.5]
137 * Take a data string and produce the encrypted CBC Counter-mode MIC
139 * Note the names for most function arguments are made to (more or
140 * less) match those used in the pseudo-function definition given in
143 * @tfm_cbc: CBC(AES) blkcipher handle (initialized)
145 * @tfm_aes: AES cipher handle (initialized)
147 * @mic: buffer for placing the computed MIC (Message Integrity
148 * Code). This is exactly 8 bytes, and we expect the buffer to
149 * be at least eight bytes in length.
151 * @key: 128 bit symmetric key
155 * @a: ASCII string, 14 bytes long (I guess zero padded if needed;
156 * we use exactly 14 bytes).
158 * @b: data stream to be processed; cannot be a global or const local
159 * (will confuse the scatterlists)
161 * @blen: size of b...
163 * Still not very clear how this is done, but looks like this: we
164 * create block B0 (as WUSB1.0[6.5] says), then we AES-crypt it with
165 * @key. We bytewise xor B0 with B1 (1) and AES-crypt that. Then we
166 * take the payload and divide it in blocks (16 bytes), xor them with
167 * the previous crypto result (16 bytes) and crypt it, repeat the next
168 * block with the output of the previous one, rinse wash (I guess this
169 * is what AES CBC mode means...but I truly have no idea). So we use
170 * the CBC(AES) blkcipher, that does precisely that. The IV (Initial
171 * Vector) is 16 bytes and is set to zero, so
173 * See rfc3610. Linux crypto has a CBC implementation, but the
174 * documentation is scarce, to say the least, and the example code is
175 * so intricated that is difficult to understand how things work. Most
176 * of this is guess work -- bite me.
178 * (1) Created as 6.5 says, again, using as l(a) 'Blen + 14', and
179 * using the 14 bytes of @a to fill up
180 * b1.{mac_header,e0,security_reserved,padding}.
182 * NOTE: The definiton of l(a) in WUSB1.0[6.5] vs the definition of
183 * l(m) is orthogonal, they bear no relationship, so it is not
184 * in conflict with the parameter's relation that
185 * WUSB1.0[6.4.2]) defines.
187 * NOTE: WUSB1.0[A.1]: Host Nonce is missing a nibble? (1e); fixed in
188 * first errata released on 2005/07.
190 * NOTE: we need to clean IV to zero at each invocation to make sure
191 * we start with a fresh empty Initial Vector, so that the CBC
194 * NOTE: blen is not aligned to a block size, we'll pad zeros, that's
195 * what sg[4] is for. Maybe there is a smarter way to do this.
197 static int wusb_ccm_mac(struct crypto_blkcipher
*tfm_cbc
,
198 struct crypto_cipher
*tfm_aes
, void *mic
,
199 const struct aes_ccm_nonce
*n
,
200 const struct aes_ccm_label
*a
, const void *b
,
204 struct blkcipher_desc desc
;
205 struct aes_ccm_b0 b0
;
206 struct aes_ccm_b1 b1
;
208 struct scatterlist sg
[4], sg_dst
;
210 size_t ivsize
, dst_size
;
211 const u8 bzero
[16] = { 0 };
215 * These checks should be compile time optimized out
216 * ensure @a fills b1's mac_header and following fields
218 WARN_ON(sizeof(*a
) != sizeof(b1
) - sizeof(b1
.la
));
219 WARN_ON(sizeof(b0
) != sizeof(struct aes_ccm_block
));
220 WARN_ON(sizeof(b1
) != sizeof(struct aes_ccm_block
));
221 WARN_ON(sizeof(ax
) != sizeof(struct aes_ccm_block
));
224 zero_padding
= sizeof(struct aes_ccm_block
)
225 - blen
% sizeof(struct aes_ccm_block
);
226 zero_padding
= blen
% sizeof(struct aes_ccm_block
);
228 zero_padding
= sizeof(struct aes_ccm_block
) - zero_padding
;
229 dst_size
= blen
+ sizeof(b0
) + sizeof(b1
) + zero_padding
;
230 dst_buf
= kzalloc(dst_size
, GFP_KERNEL
);
231 if (dst_buf
== NULL
) {
232 printk(KERN_ERR
"E: can't alloc destination buffer\n");
236 iv
= crypto_blkcipher_crt(tfm_cbc
)->iv
;
237 ivsize
= crypto_blkcipher_ivsize(tfm_cbc
);
238 memset(iv
, 0, ivsize
);
241 b0
.flags
= 0x59; /* Format B0 */
243 b0
.lm
= cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */
247 * The WUSB spec is anything but clear! WUSB1.0[6.5]
248 * says that to initialize B1 from A with 'l(a) = blen +
249 * 14'--after clarification, it means to use A's contents
250 * for MAC Header, EO, sec reserved and padding.
252 b1
.la
= cpu_to_be16(blen
+ 14);
253 memcpy(&b1
.mac_header
, a
, sizeof(*a
));
255 sg_init_table(sg
, ARRAY_SIZE(sg
));
256 sg_set_buf(&sg
[0], &b0
, sizeof(b0
));
257 sg_set_buf(&sg
[1], &b1
, sizeof(b1
));
258 sg_set_buf(&sg
[2], b
, blen
);
259 /* 0 if well behaved :) */
260 sg_set_buf(&sg
[3], bzero
, zero_padding
);
261 sg_init_one(&sg_dst
, dst_buf
, dst_size
);
265 result
= crypto_blkcipher_encrypt(&desc
, &sg_dst
, sg
, dst_size
);
267 printk(KERN_ERR
"E: can't compute CBC-MAC tag (MIC): %d\n",
269 goto error_cbc_crypt
;
272 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5]
273 * The procedure is to AES crypt the A0 block and XOR the MIC
274 * Tag agains it; we only do the first 8 bytes and place it
275 * directly in the destination buffer.
277 * POS Crypto API: size is assumed to be AES's block size.
278 * Thanks for documenting it -- tip taken from airo.c
280 ax
.flags
= 0x01; /* as per WUSB 1.0 spec */
283 crypto_cipher_encrypt_one(tfm_aes
, (void *)&ax
, (void *)&ax
);
284 bytewise_xor(mic
, &ax
, iv
, 8);
293 * WUSB Pseudo Random Function (WUSB1.0[6.5])
295 * @b: buffer to the source data; cannot be a global or const local
296 * (will confuse the scatterlists)
298 ssize_t
wusb_prf(void *out
, size_t out_size
,
299 const u8 key
[16], const struct aes_ccm_nonce
*_n
,
300 const struct aes_ccm_label
*a
,
301 const void *b
, size_t blen
, size_t len
)
303 ssize_t result
, bytes
= 0, bitr
;
304 struct aes_ccm_nonce n
= *_n
;
305 struct crypto_blkcipher
*tfm_cbc
;
306 struct crypto_cipher
*tfm_aes
;
310 tfm_cbc
= crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC
);
311 if (IS_ERR(tfm_cbc
)) {
312 result
= PTR_ERR(tfm_cbc
);
313 printk(KERN_ERR
"E: can't load CBC(AES): %d\n", (int)result
);
314 goto error_alloc_cbc
;
316 result
= crypto_blkcipher_setkey(tfm_cbc
, key
, 16);
318 printk(KERN_ERR
"E: can't set CBC key: %d\n", (int)result
);
319 goto error_setkey_cbc
;
322 tfm_aes
= crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC
);
323 if (IS_ERR(tfm_aes
)) {
324 result
= PTR_ERR(tfm_aes
);
325 printk(KERN_ERR
"E: can't load AES: %d\n", (int)result
);
326 goto error_alloc_aes
;
328 result
= crypto_cipher_setkey(tfm_aes
, key
, 16);
330 printk(KERN_ERR
"E: can't set AES key: %d\n", (int)result
);
331 goto error_setkey_aes
;
334 for (bitr
= 0; bitr
< (len
+ 63) / 64; bitr
++) {
335 sfn_le
= cpu_to_le64(sfn
++);
336 memcpy(&n
.sfn
, &sfn_le
, sizeof(n
.sfn
)); /* n.sfn++... */
337 result
= wusb_ccm_mac(tfm_cbc
, tfm_aes
, out
+ bytes
,
346 crypto_free_cipher(tfm_aes
);
349 crypto_free_blkcipher(tfm_cbc
);
354 /* WUSB1.0[A.2] test vectors */
355 static const u8 stv_hsmic_key
[16] = {
356 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
357 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
360 static const struct aes_ccm_nonce stv_hsmic_n
= {
362 .tkid
= { 0x76, 0x98, 0x01, },
363 .dest_addr
= { .data
= { 0xbe, 0x00 } },
364 .src_addr
= { .data
= { 0x76, 0x98 } },
368 * Out-of-band MIC Generation verification code
371 static int wusb_oob_mic_verify(void)
375 /* WUSB1.0[A.2] test vectors
377 * Need to keep it in the local stack as GCC 4.1.3something
378 * messes up and generates noise.
380 struct usb_handshake stv_hsmic_hs
= {
383 .tTKID
= { 0x76, 0x98, 0x01 },
385 .CDID
= { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
386 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
387 0x3c, 0x3d, 0x3e, 0x3f },
388 .nonce
= { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
389 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
390 0x2c, 0x2d, 0x2e, 0x2f },
391 .MIC
= { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
396 result
= wusb_oob_mic(mic
, stv_hsmic_key
, &stv_hsmic_n
, &stv_hsmic_hs
);
398 printk(KERN_ERR
"E: WUSB OOB MIC test: failed: %d\n", result
);
399 else if (memcmp(stv_hsmic_hs
.MIC
, mic
, sizeof(mic
))) {
400 printk(KERN_ERR
"E: OOB MIC test: "
401 "mismatch between MIC result and WUSB1.0[A2]\n");
402 hs_size
= sizeof(stv_hsmic_hs
) - sizeof(stv_hsmic_hs
.MIC
);
403 printk(KERN_ERR
"E: Handshake2 in: (%zu bytes)\n", hs_size
);
404 wusb_key_dump(&stv_hsmic_hs
, hs_size
);
405 printk(KERN_ERR
"E: CCM Nonce in: (%zu bytes)\n",
406 sizeof(stv_hsmic_n
));
407 wusb_key_dump(&stv_hsmic_n
, sizeof(stv_hsmic_n
));
408 printk(KERN_ERR
"E: MIC out:\n");
409 wusb_key_dump(mic
, sizeof(mic
));
410 printk(KERN_ERR
"E: MIC out (from WUSB1.0[A.2]):\n");
411 wusb_key_dump(stv_hsmic_hs
.MIC
, sizeof(stv_hsmic_hs
.MIC
));
419 * Test vectors for Key derivation
421 * These come from WUSB1.0[6.5.1], the vectors in WUSB1.0[A.1]
422 * (errata corrected in 2005/07).
424 static const u8 stv_key_a1
[16] __attribute__ ((__aligned__(4))) = {
425 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
426 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
429 static const struct aes_ccm_nonce stv_keydvt_n_a1
= {
431 .tkid
= { 0x76, 0x98, 0x01, },
432 .dest_addr
= { .data
= { 0xbe, 0x00 } },
433 .src_addr
= { .data
= { 0x76, 0x98 } },
436 static const struct wusb_keydvt_out stv_keydvt_out_a1
= {
438 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
439 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
442 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06,
443 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d
448 * Performa a test to make sure we match the vectors defined in
449 * WUSB1.0[A.1](Errata2006/12)
451 static int wusb_key_derive_verify(void)
454 struct wusb_keydvt_out keydvt_out
;
455 /* These come from WUSB1.0[A.1] + 2006/12 errata
456 * NOTE: can't make this const or global -- somehow it seems
457 * the scatterlists for crypto get confused and we get
458 * bad data. There is no doc on this... */
459 struct wusb_keydvt_in stv_keydvt_in_a1
= {
461 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
462 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
465 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
466 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
470 result
= wusb_key_derive(&keydvt_out
, stv_key_a1
, &stv_keydvt_n_a1
,
473 printk(KERN_ERR
"E: WUSB key derivation test: "
474 "derivation failed: %d\n", result
);
475 if (memcmp(&stv_keydvt_out_a1
, &keydvt_out
, sizeof(keydvt_out
))) {
476 printk(KERN_ERR
"E: WUSB key derivation test: "
477 "mismatch between key derivation result "
478 "and WUSB1.0[A1] Errata 2006/12\n");
479 printk(KERN_ERR
"E: keydvt in: key\n");
480 wusb_key_dump(stv_key_a1
, sizeof(stv_key_a1
));
481 printk(KERN_ERR
"E: keydvt in: nonce\n");
482 wusb_key_dump( &stv_keydvt_n_a1
, sizeof(stv_keydvt_n_a1
));
483 printk(KERN_ERR
"E: keydvt in: hnonce & dnonce\n");
484 wusb_key_dump(&stv_keydvt_in_a1
, sizeof(stv_keydvt_in_a1
));
485 printk(KERN_ERR
"E: keydvt out: KCK\n");
486 wusb_key_dump(&keydvt_out
.kck
, sizeof(keydvt_out
.kck
));
487 printk(KERN_ERR
"E: keydvt out: PTK\n");
488 wusb_key_dump(&keydvt_out
.ptk
, sizeof(keydvt_out
.ptk
));
496 * Initialize crypto system
498 * FIXME: we do nothing now, other than verifying. Later on we'll
499 * cache the encryption stuff, so that's why we have a separate init.
501 int wusb_crypto_init(void)
505 if (debug_crypto_verify
) {
506 result
= wusb_key_derive_verify();
509 return wusb_oob_mic_verify();
514 void wusb_crypto_exit(void)
516 /* FIXME: free cached crypto transforms */