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 v4.16-rc7 518 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_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 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[crypto_skcipher_ivsize(tfm_cbc)]; 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 memset(iv, 0, sizeof(iv)); 228 229 /* Setup B0 */ 230 scratch->b0.flags = 0x59; /* Format B0 */ 231 scratch->b0.ccm_nonce = *n; 232 scratch->b0.lm = cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */ 233 234 /* Setup B1 235 * 236 * The WUSB spec is anything but clear! WUSB1.0[6.5] 237 * says that to initialize B1 from A with 'l(a) = blen + 238 * 14'--after clarification, it means to use A's contents 239 * for MAC Header, EO, sec reserved and padding. 240 */ 241 scratch->b1.la = cpu_to_be16(blen + 14); 242 memcpy(&scratch->b1.mac_header, a, sizeof(*a)); 243 244 sg_init_table(sg, ARRAY_SIZE(sg)); 245 sg_set_buf(&sg[0], &scratch->b0, sizeof(scratch->b0)); 246 sg_set_buf(&sg[1], &scratch->b1, sizeof(scratch->b1)); 247 sg_set_buf(&sg[2], b, blen); 248 /* 0 if well behaved :) */ 249 sg_set_page(&sg[3], ZERO_PAGE(0), zero_padding, 0); 250 sg_init_one(&sg_dst, dst_buf, dst_size); 251 252 skcipher_request_set_tfm(req, tfm_cbc); 253 skcipher_request_set_callback(req, 0, NULL, NULL); 254 skcipher_request_set_crypt(req, sg, &sg_dst, dst_size, iv); 255 result = crypto_skcipher_encrypt(req); 256 skcipher_request_zero(req); 257 if (result < 0) { 258 printk(KERN_ERR "E: can't compute CBC-MAC tag (MIC): %d\n", 259 result); 260 goto error_cbc_crypt; 261 } 262 263 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5] 264 * The procedure is to AES crypt the A0 block and XOR the MIC 265 * Tag against it; we only do the first 8 bytes and place it 266 * directly in the destination buffer. 267 * 268 * POS Crypto API: size is assumed to be AES's block size. 269 * Thanks for documenting it -- tip taken from airo.c 270 */ 271 scratch->ax.flags = 0x01; /* as per WUSB 1.0 spec */ 272 scratch->ax.ccm_nonce = *n; 273 scratch->ax.counter = 0; 274 crypto_cipher_encrypt_one(tfm_aes, (void *)&scratch->ax, 275 (void *)&scratch->ax); 276 bytewise_xor(mic, &scratch->ax, iv, 8); 277 result = 8; 278error_cbc_crypt: 279 kfree(dst_buf); 280error_dst_buf: 281 return result; 282} 283 284/* 285 * WUSB Pseudo Random Function (WUSB1.0[6.5]) 286 * 287 * @b: buffer to the source data; cannot be a global or const local 288 * (will confuse the scatterlists) 289 */ 290ssize_t wusb_prf(void *out, size_t out_size, 291 const u8 key[16], const struct aes_ccm_nonce *_n, 292 const struct aes_ccm_label *a, 293 const void *b, size_t blen, size_t len) 294{ 295 ssize_t result, bytes = 0, bitr; 296 struct aes_ccm_nonce n = *_n; 297 struct crypto_skcipher *tfm_cbc; 298 struct crypto_cipher *tfm_aes; 299 struct wusb_mac_scratch *scratch; 300 u64 sfn = 0; 301 __le64 sfn_le; 302 303 tfm_cbc = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); 304 if (IS_ERR(tfm_cbc)) { 305 result = PTR_ERR(tfm_cbc); 306 printk(KERN_ERR "E: can't load CBC(AES): %d\n", (int)result); 307 goto error_alloc_cbc; 308 } 309 result = crypto_skcipher_setkey(tfm_cbc, key, 16); 310 if (result < 0) { 311 printk(KERN_ERR "E: can't set CBC key: %d\n", (int)result); 312 goto error_setkey_cbc; 313 } 314 315 tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); 316 if (IS_ERR(tfm_aes)) { 317 result = PTR_ERR(tfm_aes); 318 printk(KERN_ERR "E: can't load AES: %d\n", (int)result); 319 goto error_alloc_aes; 320 } 321 result = crypto_cipher_setkey(tfm_aes, key, 16); 322 if (result < 0) { 323 printk(KERN_ERR "E: can't set AES key: %d\n", (int)result); 324 goto error_setkey_aes; 325 } 326 scratch = kmalloc(sizeof(*scratch), GFP_KERNEL); 327 if (!scratch) { 328 result = -ENOMEM; 329 goto error_alloc_scratch; 330 } 331 332 for (bitr = 0; bitr < (len + 63) / 64; bitr++) { 333 sfn_le = cpu_to_le64(sfn++); 334 memcpy(&n.sfn, &sfn_le, sizeof(n.sfn)); /* n.sfn++... */ 335 result = wusb_ccm_mac(tfm_cbc, tfm_aes, scratch, out + bytes, 336 &n, a, b, blen); 337 if (result < 0) 338 goto error_ccm_mac; 339 bytes += result; 340 } 341 result = bytes; 342 343 kfree(scratch); 344error_alloc_scratch: 345error_ccm_mac: 346error_setkey_aes: 347 crypto_free_cipher(tfm_aes); 348error_alloc_aes: 349error_setkey_cbc: 350 crypto_free_skcipher(tfm_cbc); 351error_alloc_cbc: 352 return result; 353} 354 355/* WUSB1.0[A.2] test vectors */ 356static const u8 stv_hsmic_key[16] = { 357 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d, 358 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f 359}; 360 361static const struct aes_ccm_nonce stv_hsmic_n = { 362 .sfn = { 0 }, 363 .tkid = { 0x76, 0x98, 0x01, }, 364 .dest_addr = { .data = { 0xbe, 0x00 } }, 365 .src_addr = { .data = { 0x76, 0x98 } }, 366}; 367 368/* 369 * Out-of-band MIC Generation verification code 370 * 371 */ 372static int wusb_oob_mic_verify(void) 373{ 374 int result; 375 u8 mic[8]; 376 /* WUSB1.0[A.2] test vectors 377 * 378 * Need to keep it in the local stack as GCC 4.1.3something 379 * messes up and generates noise. 380 */ 381 struct usb_handshake stv_hsmic_hs = { 382 .bMessageNumber = 2, 383 .bStatus = 00, 384 .tTKID = { 0x76, 0x98, 0x01 }, 385 .bReserved = 00, 386 .CDID = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 387 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 388 0x3c, 0x3d, 0x3e, 0x3f }, 389 .nonce = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 390 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 391 0x2c, 0x2d, 0x2e, 0x2f }, 392 .MIC = { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c, 393 0x14, 0x7b }, 394 }; 395 size_t hs_size; 396 397 result = wusb_oob_mic(mic, stv_hsmic_key, &stv_hsmic_n, &stv_hsmic_hs); 398 if (result < 0) 399 printk(KERN_ERR "E: WUSB OOB MIC test: failed: %d\n", result); 400 else if (memcmp(stv_hsmic_hs.MIC, mic, sizeof(mic))) { 401 printk(KERN_ERR "E: OOB MIC test: " 402 "mismatch between MIC result and WUSB1.0[A2]\n"); 403 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC); 404 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size); 405 wusb_key_dump(&stv_hsmic_hs, hs_size); 406 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n", 407 sizeof(stv_hsmic_n)); 408 wusb_key_dump(&stv_hsmic_n, sizeof(stv_hsmic_n)); 409 printk(KERN_ERR "E: MIC out:\n"); 410 wusb_key_dump(mic, sizeof(mic)); 411 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n"); 412 wusb_key_dump(stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC)); 413 result = -EINVAL; 414 } else 415 result = 0; 416 return result; 417} 418 419/* 420 * Test vectors for Key derivation 421 * 422 * These come from WUSB1.0[6.5.1], the vectors in WUSB1.0[A.1] 423 * (errata corrected in 2005/07). 424 */ 425static const u8 stv_key_a1[16] __attribute__ ((__aligned__(4))) = { 426 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 427 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f 428}; 429 430static const struct aes_ccm_nonce stv_keydvt_n_a1 = { 431 .sfn = { 0 }, 432 .tkid = { 0x76, 0x98, 0x01, }, 433 .dest_addr = { .data = { 0xbe, 0x00 } }, 434 .src_addr = { .data = { 0x76, 0x98 } }, 435}; 436 437static const struct wusb_keydvt_out stv_keydvt_out_a1 = { 438 .kck = { 439 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d, 440 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f 441 }, 442 .ptk = { 443 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06, 444 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d 445 } 446}; 447 448/* 449 * Performa a test to make sure we match the vectors defined in 450 * WUSB1.0[A.1](Errata2006/12) 451 */ 452static int wusb_key_derive_verify(void) 453{ 454 int result = 0; 455 struct wusb_keydvt_out keydvt_out; 456 /* These come from WUSB1.0[A.1] + 2006/12 errata 457 * NOTE: can't make this const or global -- somehow it seems 458 * the scatterlists for crypto get confused and we get 459 * bad data. There is no doc on this... */ 460 struct wusb_keydvt_in stv_keydvt_in_a1 = { 461 .hnonce = { 462 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 463 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 464 }, 465 .dnonce = { 466 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 467 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f 468 } 469 }; 470 471 result = wusb_key_derive(&keydvt_out, stv_key_a1, &stv_keydvt_n_a1, 472 &stv_keydvt_in_a1); 473 if (result < 0) 474 printk(KERN_ERR "E: WUSB key derivation test: " 475 "derivation failed: %d\n", result); 476 if (memcmp(&stv_keydvt_out_a1, &keydvt_out, sizeof(keydvt_out))) { 477 printk(KERN_ERR "E: WUSB key derivation test: " 478 "mismatch between key derivation result " 479 "and WUSB1.0[A1] Errata 2006/12\n"); 480 printk(KERN_ERR "E: keydvt in: key\n"); 481 wusb_key_dump(stv_key_a1, sizeof(stv_key_a1)); 482 printk(KERN_ERR "E: keydvt in: nonce\n"); 483 wusb_key_dump(&stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1)); 484 printk(KERN_ERR "E: keydvt in: hnonce & dnonce\n"); 485 wusb_key_dump(&stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1)); 486 printk(KERN_ERR "E: keydvt out: KCK\n"); 487 wusb_key_dump(&keydvt_out.kck, sizeof(keydvt_out.kck)); 488 printk(KERN_ERR "E: keydvt out: PTK\n"); 489 wusb_key_dump(&keydvt_out.ptk, sizeof(keydvt_out.ptk)); 490 result = -EINVAL; 491 } else 492 result = 0; 493 return result; 494} 495 496/* 497 * Initialize crypto system 498 * 499 * FIXME: we do nothing now, other than verifying. Later on we'll 500 * cache the encryption stuff, so that's why we have a separate init. 501 */ 502int wusb_crypto_init(void) 503{ 504 int result; 505 506 if (debug_crypto_verify) { 507 result = wusb_key_derive_verify(); 508 if (result < 0) 509 return result; 510 return wusb_oob_mic_verify(); 511 } 512 return 0; 513} 514 515void wusb_crypto_exit(void) 516{ 517 /* FIXME: free cached crypto transforms */ 518}