Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.0-rc5 522 lines 16 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Ultra Wide Band 4 * AES-128 CCM Encryption 5 * 6 * Copyright (C) 2007 Intel Corporation 7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 8 * 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 12 * there. 13 * 14 * Thanks a zillion to John Keys for his help and clarifications over 15 * the designed-by-a-committee text. 16 * 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 22 * Linux Crypto API. 23 * 24 * We leave a crypto test module so we can verify that vectors match, 25 * every now and then. 26 * 27 * Block size: 16 bytes -- AES seems to do things in 'block sizes'. I 28 * am learning a lot... 29 * 30 * Conveniently, some data structures that need to be 31 * funneled through AES are...16 bytes in size! 32 */ 33 34#include <crypto/skcipher.h> 35#include <linux/crypto.h> 36#include <linux/module.h> 37#include <linux/err.h> 38#include <linux/uwb.h> 39#include <linux/slab.h> 40#include <linux/usb/wusb.h> 41#include <linux/scatterlist.h> 42 43static int debug_crypto_verify; 44 45module_param(debug_crypto_verify, int, 0); 46MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms"); 47 48static void wusb_key_dump(const void *buf, size_t len) 49{ 50 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_OFFSET, 16, 1, 51 buf, len, 0); 52} 53 54/* 55 * Block of data, as understood by AES-CCM 56 * 57 * The code assumes this structure is nothing but a 16 byte array 58 * (packed in a struct to avoid common mess ups that I usually do with 59 * arrays and enforcing type checking). 60 */ 61struct aes_ccm_block { 62 u8 data[16]; 63} __attribute__((packed)); 64 65/* 66 * Counter-mode Blocks (WUSB1.0[6.4]) 67 * 68 * According to CCM (or so it seems), for the purpose of calculating 69 * the MIC, the message is broken in N counter-mode blocks, B0, B1, 70 * ... BN. 71 * 72 * B0 contains flags, the CCM nonce and l(m). 73 * 74 * B1 contains l(a), the MAC header, the encryption offset and padding. 75 * 76 * If EO is nonzero, additional blocks are built from payload bytes 77 * until EO is exhausted (FIXME: padding to 16 bytes, I guess). The 78 * padding is not xmitted. 79 */ 80 81/* WUSB1.0[T6.4] */ 82struct aes_ccm_b0 { 83 u8 flags; /* 0x59, per CCM spec */ 84 struct aes_ccm_nonce ccm_nonce; 85 __be16 lm; 86} __attribute__((packed)); 87 88/* WUSB1.0[T6.5] */ 89struct aes_ccm_b1 { 90 __be16 la; 91 u8 mac_header[10]; 92 __le16 eo; 93 u8 security_reserved; /* This is always zero */ 94 u8 padding; /* 0 */ 95} __attribute__((packed)); 96 97/* 98 * Encryption Blocks (WUSB1.0[6.4.4]) 99 * 100 * CCM uses Ax blocks to generate a keystream with which the MIC and 101 * the message's payload are encoded. A0 always encrypts/decrypts the 102 * MIC. Ax (x>0) are used for the successive payload blocks. 103 * 104 * The x is the counter, and is increased for each block. 105 */ 106struct aes_ccm_a { 107 u8 flags; /* 0x01, per CCM spec */ 108 struct aes_ccm_nonce ccm_nonce; 109 __be16 counter; /* Value of x */ 110} __attribute__((packed)); 111 112static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2, 113 size_t size) 114{ 115 u8 *bo = _bo; 116 const u8 *bi1 = _bi1, *bi2 = _bi2; 117 size_t itr; 118 for (itr = 0; itr < size; itr++) 119 bo[itr] = bi1[itr] ^ bi2[itr]; 120} 121 122/* Scratch space for MAC calculations. */ 123struct wusb_mac_scratch { 124 struct aes_ccm_b0 b0; 125 struct aes_ccm_b1 b1; 126 struct aes_ccm_a ax; 127}; 128 129/* 130 * CC-MAC function WUSB1.0[6.5] 131 * 132 * Take a data string and produce the encrypted CBC Counter-mode MIC 133 * 134 * Note the names for most function arguments are made to (more or 135 * less) match those used in the pseudo-function definition given in 136 * WUSB1.0[6.5]. 137 * 138 * @tfm_cbc: CBC(AES) blkcipher handle (initialized) 139 * 140 * @tfm_aes: AES cipher handle (initialized) 141 * 142 * @mic: buffer for placing the computed MIC (Message Integrity 143 * Code). This is exactly 8 bytes, and we expect the buffer to 144 * be at least eight bytes in length. 145 * 146 * @key: 128 bit symmetric key 147 * 148 * @n: CCM nonce 149 * 150 * @a: ASCII string, 14 bytes long (I guess zero padded if needed; 151 * we use exactly 14 bytes). 152 * 153 * @b: data stream to be processed; cannot be a global or const local 154 * (will confuse the scatterlists) 155 * 156 * @blen: size of b... 157 * 158 * Still not very clear how this is done, but looks like this: we 159 * create block B0 (as WUSB1.0[6.5] says), then we AES-crypt it with 160 * @key. We bytewise xor B0 with B1 (1) and AES-crypt that. Then we 161 * take the payload and divide it in blocks (16 bytes), xor them with 162 * the previous crypto result (16 bytes) and crypt it, repeat the next 163 * block with the output of the previous one, rinse wash (I guess this 164 * is what AES CBC mode means...but I truly have no idea). So we use 165 * the CBC(AES) blkcipher, that does precisely that. The IV (Initial 166 * Vector) is 16 bytes and is set to zero, so 167 * 168 * See rfc3610. Linux crypto has a CBC implementation, but the 169 * documentation is scarce, to say the least, and the example code is 170 * so intricated that is difficult to understand how things work. Most 171 * of this is guess work -- bite me. 172 * 173 * (1) Created as 6.5 says, again, using as l(a) 'Blen + 14', and 174 * using the 14 bytes of @a to fill up 175 * b1.{mac_header,e0,security_reserved,padding}. 176 * 177 * NOTE: The definition of l(a) in WUSB1.0[6.5] vs the definition of 178 * l(m) is orthogonal, they bear no relationship, so it is not 179 * in conflict with the parameter's relation that 180 * WUSB1.0[6.4.2]) defines. 181 * 182 * NOTE: WUSB1.0[A.1]: Host Nonce is missing a nibble? (1e); fixed in 183 * first errata released on 2005/07. 184 * 185 * NOTE: we need to clean IV to zero at each invocation to make sure 186 * we start with a fresh empty Initial Vector, so that the CBC 187 * works ok. 188 * 189 * NOTE: blen is not aligned to a block size, we'll pad zeros, that's 190 * what sg[4] is for. Maybe there is a smarter way to do this. 191 */ 192static int wusb_ccm_mac(struct crypto_sync_skcipher *tfm_cbc, 193 struct crypto_cipher *tfm_aes, 194 struct wusb_mac_scratch *scratch, 195 void *mic, 196 const struct aes_ccm_nonce *n, 197 const struct aes_ccm_label *a, const void *b, 198 size_t blen) 199{ 200 int result = 0; 201 SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm_cbc); 202 struct scatterlist sg[4], sg_dst; 203 void *dst_buf; 204 size_t dst_size; 205 u8 *iv; 206 size_t zero_padding; 207 208 /* 209 * These checks should be compile time optimized out 210 * ensure @a fills b1's mac_header and following fields 211 */ 212 WARN_ON(sizeof(*a) != sizeof(scratch->b1) - sizeof(scratch->b1.la)); 213 WARN_ON(sizeof(scratch->b0) != sizeof(struct aes_ccm_block)); 214 WARN_ON(sizeof(scratch->b1) != sizeof(struct aes_ccm_block)); 215 WARN_ON(sizeof(scratch->ax) != sizeof(struct aes_ccm_block)); 216 217 result = -ENOMEM; 218 zero_padding = blen % sizeof(struct aes_ccm_block); 219 if (zero_padding) 220 zero_padding = sizeof(struct aes_ccm_block) - zero_padding; 221 dst_size = blen + sizeof(scratch->b0) + sizeof(scratch->b1) + 222 zero_padding; 223 dst_buf = kzalloc(dst_size, GFP_KERNEL); 224 if (!dst_buf) 225 goto error_dst_buf; 226 227 iv = kzalloc(crypto_sync_skcipher_ivsize(tfm_cbc), GFP_KERNEL); 228 if (!iv) 229 goto error_iv; 230 231 /* Setup B0 */ 232 scratch->b0.flags = 0x59; /* Format B0 */ 233 scratch->b0.ccm_nonce = *n; 234 scratch->b0.lm = cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */ 235 236 /* Setup B1 237 * 238 * The WUSB spec is anything but clear! WUSB1.0[6.5] 239 * says that to initialize B1 from A with 'l(a) = blen + 240 * 14'--after clarification, it means to use A's contents 241 * for MAC Header, EO, sec reserved and padding. 242 */ 243 scratch->b1.la = cpu_to_be16(blen + 14); 244 memcpy(&scratch->b1.mac_header, a, sizeof(*a)); 245 246 sg_init_table(sg, ARRAY_SIZE(sg)); 247 sg_set_buf(&sg[0], &scratch->b0, sizeof(scratch->b0)); 248 sg_set_buf(&sg[1], &scratch->b1, sizeof(scratch->b1)); 249 sg_set_buf(&sg[2], b, blen); 250 /* 0 if well behaved :) */ 251 sg_set_page(&sg[3], ZERO_PAGE(0), zero_padding, 0); 252 sg_init_one(&sg_dst, dst_buf, dst_size); 253 254 skcipher_request_set_sync_tfm(req, tfm_cbc); 255 skcipher_request_set_callback(req, 0, NULL, NULL); 256 skcipher_request_set_crypt(req, sg, &sg_dst, dst_size, iv); 257 result = crypto_skcipher_encrypt(req); 258 skcipher_request_zero(req); 259 if (result < 0) { 260 printk(KERN_ERR "E: can't compute CBC-MAC tag (MIC): %d\n", 261 result); 262 goto error_cbc_crypt; 263 } 264 265 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5] 266 * The procedure is to AES crypt the A0 block and XOR the MIC 267 * Tag against it; we only do the first 8 bytes and place it 268 * directly in the destination buffer. 269 * 270 * POS Crypto API: size is assumed to be AES's block size. 271 * Thanks for documenting it -- tip taken from airo.c 272 */ 273 scratch->ax.flags = 0x01; /* as per WUSB 1.0 spec */ 274 scratch->ax.ccm_nonce = *n; 275 scratch->ax.counter = 0; 276 crypto_cipher_encrypt_one(tfm_aes, (void *)&scratch->ax, 277 (void *)&scratch->ax); 278 bytewise_xor(mic, &scratch->ax, iv, 8); 279 result = 8; 280error_cbc_crypt: 281 kfree(iv); 282error_iv: 283 kfree(dst_buf); 284error_dst_buf: 285 return result; 286} 287 288/* 289 * WUSB Pseudo Random Function (WUSB1.0[6.5]) 290 * 291 * @b: buffer to the source data; cannot be a global or const local 292 * (will confuse the scatterlists) 293 */ 294ssize_t wusb_prf(void *out, size_t out_size, 295 const u8 key[16], const struct aes_ccm_nonce *_n, 296 const struct aes_ccm_label *a, 297 const void *b, size_t blen, size_t len) 298{ 299 ssize_t result, bytes = 0, bitr; 300 struct aes_ccm_nonce n = *_n; 301 struct crypto_sync_skcipher *tfm_cbc; 302 struct crypto_cipher *tfm_aes; 303 struct wusb_mac_scratch *scratch; 304 u64 sfn = 0; 305 __le64 sfn_le; 306 307 tfm_cbc = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0); 308 if (IS_ERR(tfm_cbc)) { 309 result = PTR_ERR(tfm_cbc); 310 printk(KERN_ERR "E: can't load CBC(AES): %d\n", (int)result); 311 goto error_alloc_cbc; 312 } 313 result = crypto_sync_skcipher_setkey(tfm_cbc, key, 16); 314 if (result < 0) { 315 printk(KERN_ERR "E: can't set CBC key: %d\n", (int)result); 316 goto error_setkey_cbc; 317 } 318 319 tfm_aes = crypto_alloc_cipher("aes", 0, 0); 320 if (IS_ERR(tfm_aes)) { 321 result = PTR_ERR(tfm_aes); 322 printk(KERN_ERR "E: can't load AES: %d\n", (int)result); 323 goto error_alloc_aes; 324 } 325 result = crypto_cipher_setkey(tfm_aes, key, 16); 326 if (result < 0) { 327 printk(KERN_ERR "E: can't set AES key: %d\n", (int)result); 328 goto error_setkey_aes; 329 } 330 scratch = kmalloc(sizeof(*scratch), GFP_KERNEL); 331 if (!scratch) { 332 result = -ENOMEM; 333 goto error_alloc_scratch; 334 } 335 336 for (bitr = 0; bitr < (len + 63) / 64; bitr++) { 337 sfn_le = cpu_to_le64(sfn++); 338 memcpy(&n.sfn, &sfn_le, sizeof(n.sfn)); /* n.sfn++... */ 339 result = wusb_ccm_mac(tfm_cbc, tfm_aes, scratch, out + bytes, 340 &n, a, b, blen); 341 if (result < 0) 342 goto error_ccm_mac; 343 bytes += result; 344 } 345 result = bytes; 346 347 kfree(scratch); 348error_alloc_scratch: 349error_ccm_mac: 350error_setkey_aes: 351 crypto_free_cipher(tfm_aes); 352error_alloc_aes: 353error_setkey_cbc: 354 crypto_free_sync_skcipher(tfm_cbc); 355error_alloc_cbc: 356 return result; 357} 358 359/* WUSB1.0[A.2] test vectors */ 360static const u8 stv_hsmic_key[16] = { 361 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d, 362 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f 363}; 364 365static const struct aes_ccm_nonce stv_hsmic_n = { 366 .sfn = { 0 }, 367 .tkid = { 0x76, 0x98, 0x01, }, 368 .dest_addr = { .data = { 0xbe, 0x00 } }, 369 .src_addr = { .data = { 0x76, 0x98 } }, 370}; 371 372/* 373 * Out-of-band MIC Generation verification code 374 * 375 */ 376static int wusb_oob_mic_verify(void) 377{ 378 int result; 379 u8 mic[8]; 380 /* WUSB1.0[A.2] test vectors 381 * 382 * Need to keep it in the local stack as GCC 4.1.3something 383 * messes up and generates noise. 384 */ 385 struct usb_handshake stv_hsmic_hs = { 386 .bMessageNumber = 2, 387 .bStatus = 00, 388 .tTKID = { 0x76, 0x98, 0x01 }, 389 .bReserved = 00, 390 .CDID = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 391 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 392 0x3c, 0x3d, 0x3e, 0x3f }, 393 .nonce = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 394 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 395 0x2c, 0x2d, 0x2e, 0x2f }, 396 .MIC = { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c, 397 0x14, 0x7b }, 398 }; 399 size_t hs_size; 400 401 result = wusb_oob_mic(mic, stv_hsmic_key, &stv_hsmic_n, &stv_hsmic_hs); 402 if (result < 0) 403 printk(KERN_ERR "E: WUSB OOB MIC test: failed: %d\n", result); 404 else if (memcmp(stv_hsmic_hs.MIC, mic, sizeof(mic))) { 405 printk(KERN_ERR "E: OOB MIC test: " 406 "mismatch between MIC result and WUSB1.0[A2]\n"); 407 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC); 408 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size); 409 wusb_key_dump(&stv_hsmic_hs, hs_size); 410 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n", 411 sizeof(stv_hsmic_n)); 412 wusb_key_dump(&stv_hsmic_n, sizeof(stv_hsmic_n)); 413 printk(KERN_ERR "E: MIC out:\n"); 414 wusb_key_dump(mic, sizeof(mic)); 415 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n"); 416 wusb_key_dump(stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC)); 417 result = -EINVAL; 418 } else 419 result = 0; 420 return result; 421} 422 423/* 424 * Test vectors for Key derivation 425 * 426 * These come from WUSB1.0[6.5.1], the vectors in WUSB1.0[A.1] 427 * (errata corrected in 2005/07). 428 */ 429static const u8 stv_key_a1[16] __attribute__ ((__aligned__(4))) = { 430 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 431 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f 432}; 433 434static const struct aes_ccm_nonce stv_keydvt_n_a1 = { 435 .sfn = { 0 }, 436 .tkid = { 0x76, 0x98, 0x01, }, 437 .dest_addr = { .data = { 0xbe, 0x00 } }, 438 .src_addr = { .data = { 0x76, 0x98 } }, 439}; 440 441static const struct wusb_keydvt_out stv_keydvt_out_a1 = { 442 .kck = { 443 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d, 444 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f 445 }, 446 .ptk = { 447 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06, 448 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d 449 } 450}; 451 452/* 453 * Performa a test to make sure we match the vectors defined in 454 * WUSB1.0[A.1](Errata2006/12) 455 */ 456static int wusb_key_derive_verify(void) 457{ 458 int result = 0; 459 struct wusb_keydvt_out keydvt_out; 460 /* These come from WUSB1.0[A.1] + 2006/12 errata 461 * NOTE: can't make this const or global -- somehow it seems 462 * the scatterlists for crypto get confused and we get 463 * bad data. There is no doc on this... */ 464 struct wusb_keydvt_in stv_keydvt_in_a1 = { 465 .hnonce = { 466 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 467 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 468 }, 469 .dnonce = { 470 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 471 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f 472 } 473 }; 474 475 result = wusb_key_derive(&keydvt_out, stv_key_a1, &stv_keydvt_n_a1, 476 &stv_keydvt_in_a1); 477 if (result < 0) 478 printk(KERN_ERR "E: WUSB key derivation test: " 479 "derivation failed: %d\n", result); 480 if (memcmp(&stv_keydvt_out_a1, &keydvt_out, sizeof(keydvt_out))) { 481 printk(KERN_ERR "E: WUSB key derivation test: " 482 "mismatch between key derivation result " 483 "and WUSB1.0[A1] Errata 2006/12\n"); 484 printk(KERN_ERR "E: keydvt in: key\n"); 485 wusb_key_dump(stv_key_a1, sizeof(stv_key_a1)); 486 printk(KERN_ERR "E: keydvt in: nonce\n"); 487 wusb_key_dump(&stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1)); 488 printk(KERN_ERR "E: keydvt in: hnonce & dnonce\n"); 489 wusb_key_dump(&stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1)); 490 printk(KERN_ERR "E: keydvt out: KCK\n"); 491 wusb_key_dump(&keydvt_out.kck, sizeof(keydvt_out.kck)); 492 printk(KERN_ERR "E: keydvt out: PTK\n"); 493 wusb_key_dump(&keydvt_out.ptk, sizeof(keydvt_out.ptk)); 494 result = -EINVAL; 495 } else 496 result = 0; 497 return result; 498} 499 500/* 501 * Initialize crypto system 502 * 503 * FIXME: we do nothing now, other than verifying. Later on we'll 504 * cache the encryption stuff, so that's why we have a separate init. 505 */ 506int wusb_crypto_init(void) 507{ 508 int result; 509 510 if (debug_crypto_verify) { 511 result = wusb_key_derive_verify(); 512 if (result < 0) 513 return result; 514 return wusb_oob_mic_verify(); 515 } 516 return 0; 517} 518 519void wusb_crypto_exit(void) 520{ 521 /* FIXME: free cached crypto transforms */ 522}