1 // SPDX-License-Identifier: GPL-2.0
4 * AES-128 CCM Encryption
6 * Copyright (C) 2007 Intel Corporation
7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
9 * We don't do any encryption here; we use the Linux Kernel's AES-128
10 * crypto modules to construct keys and payload blocks in a way
11 * defined by WUSB1.0[6]. Check the erratas, as typos are are patched
14 * Thanks a zillion to John Keys for his help and clarifications over
15 * the designed-by-a-committee text.
17 * So the idea is that there is this basic Pseudo-Random-Function
18 * defined in WUSB1.0[6.5] which is the core of everything. It works
19 * by tweaking some blocks, AES crypting them and then xoring
20 * something else with them (this seems to be called CBC(AES) -- can
21 * you tell I know jack about crypto?). So we just funnel it into the
24 * We leave a crypto test module so we can verify that vectors match,
27 * Block size: 16 bytes -- AES seems to do things in 'block sizes'. I
28 * am learning a lot...
30 * Conveniently, some data structures that need to be
31 * funneled through AES are...16 bytes in size!
34 #include <crypto/aes.h>
35 #include <crypto/algapi.h>
36 #include <crypto/hash.h>
37 #include <crypto/skcipher.h>
38 #include <linux/crypto.h>
39 #include <linux/module.h>
40 #include <linux/err.h>
41 #include <linux/uwb.h>
42 #include <linux/slab.h>
43 #include <linux/usb/wusb.h>
44 #include <linux/scatterlist.h>
46 static int debug_crypto_verify
;
48 module_param(debug_crypto_verify
, int, 0);
49 MODULE_PARM_DESC(debug_crypto_verify
, "verify the key generation algorithms");
51 static void wusb_key_dump(const void *buf
, size_t len
)
53 print_hex_dump(KERN_ERR
, " ", DUMP_PREFIX_OFFSET
, 16, 1,
58 * Block of data, as understood by AES-CCM
60 * The code assumes this structure is nothing but a 16 byte array
61 * (packed in a struct to avoid common mess ups that I usually do with
62 * arrays and enforcing type checking).
64 struct aes_ccm_block
{
66 } __attribute__((packed
));
69 * Counter-mode Blocks (WUSB1.0[6.4])
71 * According to CCM (or so it seems), for the purpose of calculating
72 * the MIC, the message is broken in N counter-mode blocks, B0, B1,
75 * B0 contains flags, the CCM nonce and l(m).
77 * B1 contains l(a), the MAC header, the encryption offset and padding.
79 * If EO is nonzero, additional blocks are built from payload bytes
80 * until EO is exhausted (FIXME: padding to 16 bytes, I guess). The
81 * padding is not xmitted.
86 u8 flags
; /* 0x59, per CCM spec */
87 struct aes_ccm_nonce ccm_nonce
;
89 } __attribute__((packed
));
96 u8 security_reserved
; /* This is always zero */
98 } __attribute__((packed
));
101 * Encryption Blocks (WUSB1.0[6.4.4])
103 * CCM uses Ax blocks to generate a keystream with which the MIC and
104 * the message's payload are encoded. A0 always encrypts/decrypts the
105 * MIC. Ax (x>0) are used for the successive payload blocks.
107 * The x is the counter, and is increased for each block.
110 u8 flags
; /* 0x01, per CCM spec */
111 struct aes_ccm_nonce ccm_nonce
;
112 __be16 counter
; /* Value of x */
113 } __attribute__((packed
));
115 /* Scratch space for MAC calculations. */
116 struct wusb_mac_scratch
{
117 struct aes_ccm_b0 b0
;
118 struct aes_ccm_b1 b1
;
123 * CC-MAC function WUSB1.0[6.5]
125 * Take a data string and produce the encrypted CBC Counter-mode MIC
127 * Note the names for most function arguments are made to (more or
128 * less) match those used in the pseudo-function definition given in
131 * @tfm_cbc: CBC(AES) blkcipher handle (initialized)
133 * @tfm_aes: AES cipher handle (initialized)
135 * @mic: buffer for placing the computed MIC (Message Integrity
136 * Code). This is exactly 8 bytes, and we expect the buffer to
137 * be at least eight bytes in length.
139 * @key: 128 bit symmetric key
143 * @a: ASCII string, 14 bytes long (I guess zero padded if needed;
144 * we use exactly 14 bytes).
146 * @b: data stream to be processed
148 * @blen: size of b...
150 * Still not very clear how this is done, but looks like this: we
151 * create block B0 (as WUSB1.0[6.5] says), then we AES-crypt it with
152 * @key. We bytewise xor B0 with B1 (1) and AES-crypt that. Then we
153 * take the payload and divide it in blocks (16 bytes), xor them with
154 * the previous crypto result (16 bytes) and crypt it, repeat the next
155 * block with the output of the previous one, rinse wash. So we use
156 * the CBC-MAC(AES) shash, that does precisely that. The IV (Initial
157 * Vector) is 16 bytes and is set to zero, so
159 * (1) Created as 6.5 says, again, using as l(a) 'Blen + 14', and
160 * using the 14 bytes of @a to fill up
161 * b1.{mac_header,e0,security_reserved,padding}.
163 * NOTE: The definition of l(a) in WUSB1.0[6.5] vs the definition of
164 * l(m) is orthogonal, they bear no relationship, so it is not
165 * in conflict with the parameter's relation that
166 * WUSB1.0[6.4.2]) defines.
168 * NOTE: WUSB1.0[A.1]: Host Nonce is missing a nibble? (1e); fixed in
169 * first errata released on 2005/07.
171 * NOTE: we need to clean IV to zero at each invocation to make sure
172 * we start with a fresh empty Initial Vector, so that the CBC
175 * NOTE: blen is not aligned to a block size, we'll pad zeros, that's
176 * what sg[4] is for. Maybe there is a smarter way to do this.
178 static int wusb_ccm_mac(struct crypto_shash
*tfm_cbcmac
,
179 struct wusb_mac_scratch
*scratch
,
181 const struct aes_ccm_nonce
*n
,
182 const struct aes_ccm_label
*a
, const void *b
,
185 SHASH_DESC_ON_STACK(desc
, tfm_cbcmac
);
186 u8 iv
[AES_BLOCK_SIZE
];
189 * These checks should be compile time optimized out
190 * ensure @a fills b1's mac_header and following fields
192 BUILD_BUG_ON(sizeof(*a
) != sizeof(scratch
->b1
) - sizeof(scratch
->b1
.la
));
193 BUILD_BUG_ON(sizeof(scratch
->b0
) != sizeof(struct aes_ccm_block
));
194 BUILD_BUG_ON(sizeof(scratch
->b1
) != sizeof(struct aes_ccm_block
));
195 BUILD_BUG_ON(sizeof(scratch
->ax
) != sizeof(struct aes_ccm_block
));
198 scratch
->b0
.flags
= 0x59; /* Format B0 */
199 scratch
->b0
.ccm_nonce
= *n
;
200 scratch
->b0
.lm
= cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */
204 * The WUSB spec is anything but clear! WUSB1.0[6.5]
205 * says that to initialize B1 from A with 'l(a) = blen +
206 * 14'--after clarification, it means to use A's contents
207 * for MAC Header, EO, sec reserved and padding.
209 scratch
->b1
.la
= cpu_to_be16(blen
+ 14);
210 memcpy(&scratch
->b1
.mac_header
, a
, sizeof(*a
));
212 desc
->tfm
= tfm_cbcmac
;
213 crypto_shash_init(desc
);
214 crypto_shash_update(desc
, (u8
*)&scratch
->b0
, sizeof(scratch
->b0
) +
215 sizeof(scratch
->b1
));
216 crypto_shash_finup(desc
, b
, blen
, iv
);
218 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5]
219 * The procedure is to AES crypt the A0 block and XOR the MIC
220 * Tag against it; we only do the first 8 bytes and place it
221 * directly in the destination buffer.
223 scratch
->ax
.flags
= 0x01; /* as per WUSB 1.0 spec */
224 scratch
->ax
.ccm_nonce
= *n
;
225 scratch
->ax
.counter
= 0;
227 /* reuse the CBC-MAC transform to perform the single block encryption */
228 crypto_shash_digest(desc
, (u8
*)&scratch
->ax
, sizeof(scratch
->ax
),
231 crypto_xor_cpy(mic
, (u8
*)&scratch
->ax
, iv
, 8);
237 * WUSB Pseudo Random Function (WUSB1.0[6.5])
239 * @b: buffer to the source data; cannot be a global or const local
240 * (will confuse the scatterlists)
242 ssize_t
wusb_prf(void *out
, size_t out_size
,
243 const u8 key
[16], const struct aes_ccm_nonce
*_n
,
244 const struct aes_ccm_label
*a
,
245 const void *b
, size_t blen
, size_t len
)
247 ssize_t result
, bytes
= 0, bitr
;
248 struct aes_ccm_nonce n
= *_n
;
249 struct crypto_shash
*tfm_cbcmac
;
250 struct wusb_mac_scratch scratch
;
254 tfm_cbcmac
= crypto_alloc_shash("cbcmac(aes)", 0, 0);
255 if (IS_ERR(tfm_cbcmac
)) {
256 result
= PTR_ERR(tfm_cbcmac
);
257 printk(KERN_ERR
"E: can't load CBCMAC-AES: %d\n", (int)result
);
258 goto error_alloc_cbcmac
;
261 result
= crypto_shash_setkey(tfm_cbcmac
, key
, AES_BLOCK_SIZE
);
263 printk(KERN_ERR
"E: can't set CBCMAC-AES key: %d\n", (int)result
);
264 goto error_setkey_cbcmac
;
267 for (bitr
= 0; bitr
< (len
+ 63) / 64; bitr
++) {
268 sfn_le
= cpu_to_le64(sfn
++);
269 memcpy(&n
.sfn
, &sfn_le
, sizeof(n
.sfn
)); /* n.sfn++... */
270 result
= wusb_ccm_mac(tfm_cbcmac
, &scratch
, out
+ bytes
,
280 crypto_free_shash(tfm_cbcmac
);
285 /* WUSB1.0[A.2] test vectors */
286 static const u8 stv_hsmic_key
[16] = {
287 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
288 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
291 static const struct aes_ccm_nonce stv_hsmic_n
= {
293 .tkid
= { 0x76, 0x98, 0x01, },
294 .dest_addr
= { .data
= { 0xbe, 0x00 } },
295 .src_addr
= { .data
= { 0x76, 0x98 } },
299 * Out-of-band MIC Generation verification code
302 static int wusb_oob_mic_verify(void)
306 /* WUSB1.0[A.2] test vectors */
307 static const struct usb_handshake stv_hsmic_hs
= {
310 .tTKID
= { 0x76, 0x98, 0x01 },
312 .CDID
= { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
313 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
314 0x3c, 0x3d, 0x3e, 0x3f },
315 .nonce
= { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
316 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
317 0x2c, 0x2d, 0x2e, 0x2f },
318 .MIC
= { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
323 result
= wusb_oob_mic(mic
, stv_hsmic_key
, &stv_hsmic_n
, &stv_hsmic_hs
);
325 printk(KERN_ERR
"E: WUSB OOB MIC test: failed: %d\n", result
);
326 else if (memcmp(stv_hsmic_hs
.MIC
, mic
, sizeof(mic
))) {
327 printk(KERN_ERR
"E: OOB MIC test: "
328 "mismatch between MIC result and WUSB1.0[A2]\n");
329 hs_size
= sizeof(stv_hsmic_hs
) - sizeof(stv_hsmic_hs
.MIC
);
330 printk(KERN_ERR
"E: Handshake2 in: (%zu bytes)\n", hs_size
);
331 wusb_key_dump(&stv_hsmic_hs
, hs_size
);
332 printk(KERN_ERR
"E: CCM Nonce in: (%zu bytes)\n",
333 sizeof(stv_hsmic_n
));
334 wusb_key_dump(&stv_hsmic_n
, sizeof(stv_hsmic_n
));
335 printk(KERN_ERR
"E: MIC out:\n");
336 wusb_key_dump(mic
, sizeof(mic
));
337 printk(KERN_ERR
"E: MIC out (from WUSB1.0[A.2]):\n");
338 wusb_key_dump(stv_hsmic_hs
.MIC
, sizeof(stv_hsmic_hs
.MIC
));
346 * Test vectors for Key derivation
348 * These come from WUSB1.0[6.5.1], the vectors in WUSB1.0[A.1]
349 * (errata corrected in 2005/07).
351 static const u8 stv_key_a1
[16] __attribute__ ((__aligned__(4))) = {
352 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
353 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
356 static const struct aes_ccm_nonce stv_keydvt_n_a1
= {
358 .tkid
= { 0x76, 0x98, 0x01, },
359 .dest_addr
= { .data
= { 0xbe, 0x00 } },
360 .src_addr
= { .data
= { 0x76, 0x98 } },
363 static const struct wusb_keydvt_out stv_keydvt_out_a1
= {
365 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
366 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
369 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06,
370 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d
375 * Performa a test to make sure we match the vectors defined in
376 * WUSB1.0[A.1](Errata2006/12)
378 static int wusb_key_derive_verify(void)
381 struct wusb_keydvt_out keydvt_out
;
382 /* These come from WUSB1.0[A.1] + 2006/12 errata */
383 static const struct wusb_keydvt_in stv_keydvt_in_a1
= {
385 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
386 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
389 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
390 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
394 result
= wusb_key_derive(&keydvt_out
, stv_key_a1
, &stv_keydvt_n_a1
,
397 printk(KERN_ERR
"E: WUSB key derivation test: "
398 "derivation failed: %d\n", result
);
399 if (memcmp(&stv_keydvt_out_a1
, &keydvt_out
, sizeof(keydvt_out
))) {
400 printk(KERN_ERR
"E: WUSB key derivation test: "
401 "mismatch between key derivation result "
402 "and WUSB1.0[A1] Errata 2006/12\n");
403 printk(KERN_ERR
"E: keydvt in: key\n");
404 wusb_key_dump(stv_key_a1
, sizeof(stv_key_a1
));
405 printk(KERN_ERR
"E: keydvt in: nonce\n");
406 wusb_key_dump(&stv_keydvt_n_a1
, sizeof(stv_keydvt_n_a1
));
407 printk(KERN_ERR
"E: keydvt in: hnonce & dnonce\n");
408 wusb_key_dump(&stv_keydvt_in_a1
, sizeof(stv_keydvt_in_a1
));
409 printk(KERN_ERR
"E: keydvt out: KCK\n");
410 wusb_key_dump(&keydvt_out
.kck
, sizeof(keydvt_out
.kck
));
411 printk(KERN_ERR
"E: keydvt out: PTK\n");
412 wusb_key_dump(&keydvt_out
.ptk
, sizeof(keydvt_out
.ptk
));
420 * Initialize crypto system
422 * FIXME: we do nothing now, other than verifying. Later on we'll
423 * cache the encryption stuff, so that's why we have a separate init.
425 int wusb_crypto_init(void)
429 if (debug_crypto_verify
) {
430 result
= wusb_key_derive_verify();
433 return wusb_oob_mic_verify();
438 void wusb_crypto_exit(void)
440 /* FIXME: free cached crypto transforms */