1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2015 by Saso Kiselkov. All rights reserved. 24 */ 25 26 #ifndef _KERNEL 27 #include <strings.h> 28 #include <limits.h> 29 #include <assert.h> 30 #include <security/cryptoki.h> 31 #endif 32 33 #include <sys/types.h> 34 #include <sys/kmem.h> 35 #define INLINE_CRYPTO_GET_PTRS 36 #include <modes/modes.h> 37 #include <sys/crypto/common.h> 38 #include <sys/crypto/impl.h> 39 #include <sys/byteorder.h> 40 41 #if defined(__i386) || defined(__amd64) 42 #define UNALIGNED_POINTERS_PERMITTED 43 #endif 44 45 /* 46 * Encrypt multiple blocks of data in CCM mode. Decrypt for CCM mode 47 * is done in another function. 48 */ 49 int 50 ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length, 51 crypto_data_t *out, size_t block_size, 52 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 53 void (*copy_block)(const uint8_t *, uint8_t *), 54 void (*xor_block)(const uint8_t *, uint8_t *)) 55 { 56 size_t remainder = length; 57 size_t need; 58 uint8_t *datap = (uint8_t *)data; 59 uint8_t *blockp; 60 uint8_t *lastp; 61 void *iov_or_mp; 62 offset_t offset; 63 uint8_t *out_data_1; 64 uint8_t *out_data_2; 65 size_t out_data_1_len; 66 uint64_t counter; 67 uint8_t *mac_buf; 68 69 if (length + ctx->ccm_remainder_len < block_size) { 70 /* accumulate bytes here and return */ 71 bcopy(datap, 72 (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len, 73 length); 74 ctx->ccm_remainder_len += length; 75 ctx->ccm_copy_to = datap; 76 return (CRYPTO_SUCCESS); 77 } 78 79 lastp = (uint8_t *)ctx->ccm_cb; 80 if (out != NULL) 81 crypto_init_ptrs(out, &iov_or_mp, &offset); 82 83 mac_buf = (uint8_t *)ctx->ccm_mac_buf; 84 85 do { 86 /* Unprocessed data from last call. */ 87 if (ctx->ccm_remainder_len > 0) { 88 need = block_size - ctx->ccm_remainder_len; 89 90 if (need > remainder) 91 return (CRYPTO_DATA_LEN_RANGE); 92 93 bcopy(datap, &((uint8_t *)ctx->ccm_remainder) 94 [ctx->ccm_remainder_len], need); 95 96 blockp = (uint8_t *)ctx->ccm_remainder; 97 } else { 98 blockp = datap; 99 } 100 101 /* 102 * do CBC MAC 103 * 104 * XOR the previous cipher block current clear block. 105 * mac_buf always contain previous cipher block. 106 */ 107 xor_block(blockp, mac_buf); 108 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 109 110 /* ccm_cb is the counter block */ 111 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, 112 (uint8_t *)ctx->ccm_tmp); 113 114 lastp = (uint8_t *)ctx->ccm_tmp; 115 116 /* 117 * Increment counter. Counter bits are confined 118 * to the bottom 64 bits of the counter block. 119 */ 120 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask); 121 counter = htonll(counter + 1); 122 counter &= ctx->ccm_counter_mask; 123 ctx->ccm_cb[1] = 124 (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter; 125 126 /* 127 * XOR encrypted counter block with the current clear block. 128 */ 129 xor_block(blockp, lastp); 130 131 ctx->ccm_processed_data_len += block_size; 132 133 if (out == NULL) { 134 if (ctx->ccm_remainder_len > 0) { 135 bcopy(blockp, ctx->ccm_copy_to, 136 ctx->ccm_remainder_len); 137 bcopy(blockp + ctx->ccm_remainder_len, datap, 138 need); 139 } 140 } else { 141 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, 142 &out_data_1_len, &out_data_2, block_size); 143 144 /* copy block to where it belongs */ 145 if (out_data_1_len == block_size) { 146 copy_block(lastp, out_data_1); 147 } else { 148 bcopy(lastp, out_data_1, out_data_1_len); 149 if (out_data_2 != NULL) { 150 bcopy(lastp + out_data_1_len, 151 out_data_2, 152 block_size - out_data_1_len); 153 } 154 } 155 /* update offset */ 156 out->cd_offset += block_size; 157 } 158 159 /* Update pointer to next block of data to be processed. */ 160 if (ctx->ccm_remainder_len != 0) { 161 datap += need; 162 ctx->ccm_remainder_len = 0; 163 } else { 164 datap += block_size; 165 } 166 167 remainder = (size_t)&data[length] - (size_t)datap; 168 169 /* Incomplete last block. */ 170 if (remainder > 0 && remainder < block_size) { 171 bcopy(datap, ctx->ccm_remainder, remainder); 172 ctx->ccm_remainder_len = remainder; 173 ctx->ccm_copy_to = datap; 174 goto out; 175 } 176 ctx->ccm_copy_to = NULL; 177 178 } while (remainder > 0); 179 180 out: 181 return (CRYPTO_SUCCESS); 182 } 183 184 void 185 calculate_ccm_mac(ccm_ctx_t *ctx, uint8_t *ccm_mac, 186 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *)) 187 { 188 uint64_t counter; 189 uint8_t *counterp, *mac_buf; 190 int i; 191 192 mac_buf = (uint8_t *)ctx->ccm_mac_buf; 193 194 /* first counter block start with index 0 */ 195 counter = 0; 196 ctx->ccm_cb[1] = (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter; 197 198 counterp = (uint8_t *)ctx->ccm_tmp; 199 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp); 200 201 /* calculate XOR of MAC with first counter block */ 202 for (i = 0; i < ctx->ccm_mac_len; i++) { 203 ccm_mac[i] = mac_buf[i] ^ counterp[i]; 204 } 205 } 206 207 /* ARGSUSED */ 208 int 209 ccm_encrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size, 210 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 211 void (*xor_block)(const uint8_t *, uint8_t *)) 212 { 213 uint8_t *lastp, *mac_buf, *ccm_mac_p, *macp; 214 void *iov_or_mp; 215 offset_t offset; 216 uint8_t *out_data_1; 217 uint8_t *out_data_2; 218 size_t out_data_1_len; 219 int i; 220 221 if (out->cd_length < (ctx->ccm_remainder_len + ctx->ccm_mac_len)) { 222 return (CRYPTO_DATA_LEN_RANGE); 223 } 224 225 /* 226 * When we get here, the number of bytes of payload processed 227 * plus whatever data remains, if any, 228 * should be the same as the number of bytes that's being 229 * passed in the argument during init time. 230 */ 231 if ((ctx->ccm_processed_data_len + ctx->ccm_remainder_len) 232 != (ctx->ccm_data_len)) { 233 return (CRYPTO_DATA_LEN_RANGE); 234 } 235 236 mac_buf = (uint8_t *)ctx->ccm_mac_buf; 237 238 if (ctx->ccm_remainder_len > 0) { 239 240 /* ccm_mac_input_buf is not used for encryption */ 241 macp = (uint8_t *)ctx->ccm_mac_input_buf; 242 bzero(macp, block_size); 243 244 /* copy remainder to temporary buffer */ 245 bcopy(ctx->ccm_remainder, macp, ctx->ccm_remainder_len); 246 247 /* calculate the CBC MAC */ 248 xor_block(macp, mac_buf); 249 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 250 251 /* calculate the counter mode */ 252 lastp = (uint8_t *)ctx->ccm_tmp; 253 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, lastp); 254 255 /* XOR with counter block */ 256 for (i = 0; i < ctx->ccm_remainder_len; i++) { 257 macp[i] ^= lastp[i]; 258 } 259 ctx->ccm_processed_data_len += ctx->ccm_remainder_len; 260 } 261 262 /* Calculate the CCM MAC */ 263 ccm_mac_p = (uint8_t *)ctx->ccm_tmp; 264 calculate_ccm_mac(ctx, ccm_mac_p, encrypt_block); 265 266 crypto_init_ptrs(out, &iov_or_mp, &offset); 267 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, 268 &out_data_1_len, &out_data_2, 269 ctx->ccm_remainder_len + ctx->ccm_mac_len); 270 271 if (ctx->ccm_remainder_len > 0) { 272 273 /* copy temporary block to where it belongs */ 274 if (out_data_2 == NULL) { 275 /* everything will fit in out_data_1 */ 276 bcopy(macp, out_data_1, ctx->ccm_remainder_len); 277 bcopy(ccm_mac_p, out_data_1 + ctx->ccm_remainder_len, 278 ctx->ccm_mac_len); 279 } else { 280 281 if (out_data_1_len < ctx->ccm_remainder_len) { 282 283 size_t data_2_len_used; 284 285 bcopy(macp, out_data_1, out_data_1_len); 286 287 data_2_len_used = ctx->ccm_remainder_len 288 - out_data_1_len; 289 290 bcopy((uint8_t *)macp + out_data_1_len, 291 out_data_2, data_2_len_used); 292 bcopy(ccm_mac_p, out_data_2 + data_2_len_used, 293 ctx->ccm_mac_len); 294 } else { 295 bcopy(macp, out_data_1, out_data_1_len); 296 if (out_data_1_len == ctx->ccm_remainder_len) { 297 /* mac will be in out_data_2 */ 298 bcopy(ccm_mac_p, out_data_2, 299 ctx->ccm_mac_len); 300 } else { 301 size_t len_not_used = out_data_1_len - 302 ctx->ccm_remainder_len; 303 /* 304 * part of mac in will be in 305 * out_data_1, part of the mac will be 306 * in out_data_2 307 */ 308 bcopy(ccm_mac_p, 309 out_data_1 + ctx->ccm_remainder_len, 310 len_not_used); 311 bcopy(ccm_mac_p + len_not_used, 312 out_data_2, 313 ctx->ccm_mac_len - len_not_used); 314 315 } 316 } 317 } 318 } else { 319 /* copy block to where it belongs */ 320 bcopy(ccm_mac_p, out_data_1, out_data_1_len); 321 if (out_data_2 != NULL) { 322 bcopy(ccm_mac_p + out_data_1_len, out_data_2, 323 block_size - out_data_1_len); 324 } 325 } 326 out->cd_offset += ctx->ccm_remainder_len + ctx->ccm_mac_len; 327 ctx->ccm_remainder_len = 0; 328 return (CRYPTO_SUCCESS); 329 } 330 331 /* 332 * This will only deal with decrypting the last block of the input that 333 * might not be a multiple of block length. 334 */ 335 void 336 ccm_decrypt_incomplete_block(ccm_ctx_t *ctx, 337 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *)) 338 { 339 uint8_t *datap, *outp, *counterp; 340 int i; 341 342 datap = (uint8_t *)ctx->ccm_remainder; 343 outp = &((ctx->ccm_pt_buf)[ctx->ccm_processed_data_len]); 344 345 counterp = (uint8_t *)ctx->ccm_tmp; 346 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp); 347 348 /* XOR with counter block */ 349 for (i = 0; i < ctx->ccm_remainder_len; i++) { 350 outp[i] = datap[i] ^ counterp[i]; 351 } 352 } 353 354 /* 355 * This will decrypt the cipher text. However, the plaintext won't be 356 * returned to the caller. It will be returned when decrypt_final() is 357 * called if the MAC matches 358 */ 359 /* ARGSUSED */ 360 int 361 ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length, 362 crypto_data_t *out, size_t block_size, 363 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 364 void (*copy_block)(const uint8_t *, uint8_t *), 365 void (*xor_block)(const uint8_t *, uint8_t *)) 366 { 367 size_t remainder = length; 368 size_t need; 369 uint8_t *datap = (uint8_t *)data; 370 uint8_t *blockp; 371 uint8_t *cbp; 372 uint64_t counter; 373 size_t pt_len, total_decrypted_len, mac_len, pm_len, pd_len; 374 uint8_t *resultp; 375 376 377 pm_len = ctx->ccm_processed_mac_len; 378 379 if (pm_len > 0) { 380 uint8_t *tmp; 381 /* 382 * all ciphertext has been processed, just waiting for 383 * part of the value of the mac 384 */ 385 if ((pm_len + length) > ctx->ccm_mac_len) { 386 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 387 } 388 tmp = (uint8_t *)ctx->ccm_mac_input_buf; 389 390 bcopy(datap, tmp + pm_len, length); 391 392 ctx->ccm_processed_mac_len += length; 393 return (CRYPTO_SUCCESS); 394 } 395 396 /* 397 * If we decrypt the given data, what total amount of data would 398 * have been decrypted? 399 */ 400 pd_len = ctx->ccm_processed_data_len; 401 total_decrypted_len = pd_len + length + ctx->ccm_remainder_len; 402 403 if (total_decrypted_len > 404 (ctx->ccm_data_len + ctx->ccm_mac_len)) { 405 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 406 } 407 408 pt_len = ctx->ccm_data_len; 409 410 if (total_decrypted_len > pt_len) { 411 /* 412 * part of the input will be the MAC, need to isolate that 413 * to be dealt with later. The left-over data in 414 * ccm_remainder_len from last time will not be part of the 415 * MAC. Otherwise, it would have already been taken out 416 * when this call is made last time. 417 */ 418 size_t pt_part = pt_len - pd_len - ctx->ccm_remainder_len; 419 420 mac_len = length - pt_part; 421 422 ctx->ccm_processed_mac_len = mac_len; 423 bcopy(data + pt_part, ctx->ccm_mac_input_buf, mac_len); 424 425 if (pt_part + ctx->ccm_remainder_len < block_size) { 426 /* 427 * since this is last of the ciphertext, will 428 * just decrypt with it here 429 */ 430 bcopy(datap, &((uint8_t *)ctx->ccm_remainder) 431 [ctx->ccm_remainder_len], pt_part); 432 ctx->ccm_remainder_len += pt_part; 433 ccm_decrypt_incomplete_block(ctx, encrypt_block); 434 ctx->ccm_processed_data_len += ctx->ccm_remainder_len; 435 ctx->ccm_remainder_len = 0; 436 return (CRYPTO_SUCCESS); 437 } else { 438 /* let rest of the code handle this */ 439 length = pt_part; 440 } 441 } else if (length + ctx->ccm_remainder_len < block_size) { 442 /* accumulate bytes here and return */ 443 bcopy(datap, 444 (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len, 445 length); 446 ctx->ccm_remainder_len += length; 447 ctx->ccm_copy_to = datap; 448 return (CRYPTO_SUCCESS); 449 } 450 451 do { 452 /* Unprocessed data from last call. */ 453 if (ctx->ccm_remainder_len > 0) { 454 need = block_size - ctx->ccm_remainder_len; 455 456 if (need > remainder) 457 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 458 459 bcopy(datap, &((uint8_t *)ctx->ccm_remainder) 460 [ctx->ccm_remainder_len], need); 461 462 blockp = (uint8_t *)ctx->ccm_remainder; 463 } else { 464 blockp = datap; 465 } 466 467 /* Calculate the counter mode, ccm_cb is the counter block */ 468 cbp = (uint8_t *)ctx->ccm_tmp; 469 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, cbp); 470 471 /* 472 * Increment counter. 473 * Counter bits are confined to the bottom 64 bits 474 */ 475 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask); 476 counter = htonll(counter + 1); 477 counter &= ctx->ccm_counter_mask; 478 ctx->ccm_cb[1] = 479 (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter; 480 481 /* XOR with the ciphertext */ 482 xor_block(blockp, cbp); 483 484 /* Copy the plaintext to the "holding buffer" */ 485 resultp = (uint8_t *)ctx->ccm_pt_buf + 486 ctx->ccm_processed_data_len; 487 copy_block(cbp, resultp); 488 489 ctx->ccm_processed_data_len += block_size; 490 491 ctx->ccm_lastp = blockp; 492 493 /* Update pointer to next block of data to be processed. */ 494 if (ctx->ccm_remainder_len != 0) { 495 datap += need; 496 ctx->ccm_remainder_len = 0; 497 } else { 498 datap += block_size; 499 } 500 501 remainder = (size_t)&data[length] - (size_t)datap; 502 503 /* Incomplete last block */ 504 if (remainder > 0 && remainder < block_size) { 505 bcopy(datap, ctx->ccm_remainder, remainder); 506 ctx->ccm_remainder_len = remainder; 507 ctx->ccm_copy_to = datap; 508 if (ctx->ccm_processed_mac_len > 0) { 509 /* 510 * not expecting anymore ciphertext, just 511 * compute plaintext for the remaining input 512 */ 513 ccm_decrypt_incomplete_block(ctx, 514 encrypt_block); 515 ctx->ccm_processed_data_len += remainder; 516 ctx->ccm_remainder_len = 0; 517 } 518 goto out; 519 } 520 ctx->ccm_copy_to = NULL; 521 522 } while (remainder > 0); 523 524 out: 525 return (CRYPTO_SUCCESS); 526 } 527 528 int 529 ccm_decrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size, 530 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 531 void (*copy_block)(const uint8_t *, uint8_t *), 532 void (*xor_block)(const uint8_t *, uint8_t *)) 533 { 534 size_t mac_remain, pt_len; 535 uint8_t *pt, *mac_buf, *macp, *ccm_mac_p; 536 int rv; 537 538 pt_len = ctx->ccm_data_len; 539 540 /* Make sure output buffer can fit all of the plaintext */ 541 if (out->cd_length < pt_len) { 542 return (CRYPTO_DATA_LEN_RANGE); 543 } 544 545 pt = ctx->ccm_pt_buf; 546 mac_remain = ctx->ccm_processed_data_len; 547 mac_buf = (uint8_t *)ctx->ccm_mac_buf; 548 549 macp = (uint8_t *)ctx->ccm_tmp; 550 551 while (mac_remain > 0) { 552 553 if (mac_remain < block_size) { 554 bzero(macp, block_size); 555 bcopy(pt, macp, mac_remain); 556 mac_remain = 0; 557 } else { 558 copy_block(pt, macp); 559 mac_remain -= block_size; 560 pt += block_size; 561 } 562 563 /* calculate the CBC MAC */ 564 xor_block(macp, mac_buf); 565 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 566 } 567 568 /* Calculate the CCM MAC */ 569 ccm_mac_p = (uint8_t *)ctx->ccm_tmp; 570 calculate_ccm_mac((ccm_ctx_t *)ctx, ccm_mac_p, encrypt_block); 571 572 /* compare the input CCM MAC value with what we calculated */ 573 if (bcmp(ctx->ccm_mac_input_buf, ccm_mac_p, ctx->ccm_mac_len)) { 574 /* They don't match */ 575 return (CRYPTO_INVALID_MAC); 576 } else { 577 rv = crypto_put_output_data(ctx->ccm_pt_buf, out, pt_len); 578 if (rv != CRYPTO_SUCCESS) 579 return (rv); 580 out->cd_offset += pt_len; 581 } 582 return (CRYPTO_SUCCESS); 583 } 584 585 int 586 ccm_validate_args(CK_AES_CCM_PARAMS *ccm_param, boolean_t is_encrypt_init) 587 { 588 size_t macSize, nonceSize; 589 uint8_t q; 590 uint64_t maxValue; 591 592 /* 593 * Check the length of the MAC. The only valid 594 * lengths for the MAC are: 4, 6, 8, 10, 12, 14, 16 595 */ 596 macSize = ccm_param->ulMACSize; 597 if ((macSize < 4) || (macSize > 16) || ((macSize % 2) != 0)) { 598 return (CRYPTO_MECHANISM_PARAM_INVALID); 599 } 600 601 /* Check the nonce length. Valid values are 7, 8, 9, 10, 11, 12, 13 */ 602 nonceSize = ccm_param->ulNonceSize; 603 if ((nonceSize < 7) || (nonceSize > 13)) { 604 return (CRYPTO_MECHANISM_PARAM_INVALID); 605 } 606 607 /* q is the length of the field storing the length, in bytes */ 608 q = (uint8_t)((15 - nonceSize) & 0xFF); 609 610 611 /* 612 * If it is decrypt, need to make sure size of ciphertext is at least 613 * bigger than MAC len 614 */ 615 if ((!is_encrypt_init) && (ccm_param->ulDataSize < macSize)) { 616 return (CRYPTO_MECHANISM_PARAM_INVALID); 617 } 618 619 /* 620 * Check to make sure the length of the payload is within the 621 * range of values allowed by q 622 */ 623 if (q < 8) { 624 maxValue = (1ULL << (q * 8)) - 1; 625 } else { 626 maxValue = ULONG_MAX; 627 } 628 629 if (ccm_param->ulDataSize > maxValue) { 630 return (CRYPTO_MECHANISM_PARAM_INVALID); 631 } 632 return (CRYPTO_SUCCESS); 633 } 634 635 /* 636 * Format the first block used in CBC-MAC (B0) and the initial counter 637 * block based on formatting functions and counter generation functions 638 * specified in RFC 3610 and NIST publication 800-38C, appendix A 639 * 640 * b0 is the first block used in CBC-MAC 641 * cb0 is the first counter block 642 * 643 * It's assumed that the arguments b0 and cb0 are preallocated AES blocks 644 * 645 */ 646 static void 647 ccm_format_initial_blocks(uchar_t *nonce, ulong_t nonceSize, 648 ulong_t authDataSize, uint8_t *b0, ccm_ctx_t *aes_ctx) 649 { 650 uint64_t payloadSize; 651 uint8_t t, q, have_adata = 0; 652 size_t limit; 653 int i, j, k; 654 uint64_t mask = 0; 655 uint8_t *cb; 656 657 q = (uint8_t)((15 - nonceSize) & 0xFF); 658 t = (uint8_t)((aes_ctx->ccm_mac_len) & 0xFF); 659 660 /* Construct the first octet of b0 */ 661 if (authDataSize > 0) { 662 have_adata = 1; 663 } 664 b0[0] = (have_adata << 6) | (((t - 2) / 2) << 3) | (q - 1); 665 666 /* copy the nonce value into b0 */ 667 bcopy(nonce, &(b0[1]), nonceSize); 668 669 /* store the length of the payload into b0 */ 670 bzero(&(b0[1+nonceSize]), q); 671 672 payloadSize = aes_ctx->ccm_data_len; 673 limit = 8 < q ? 8 : q; 674 675 for (i = 0, j = 0, k = 15; i < limit; i++, j += 8, k--) { 676 b0[k] = (uint8_t)((payloadSize >> j) & 0xFF); 677 } 678 679 /* format the counter block */ 680 681 cb = (uint8_t *)aes_ctx->ccm_cb; 682 683 cb[0] = 0x07 & (q-1); /* first byte */ 684 685 /* copy the nonce value into the counter block */ 686 bcopy(nonce, &(cb[1]), nonceSize); 687 688 bzero(&(cb[1+nonceSize]), q); 689 690 /* Create the mask for the counter field based on the size of nonce */ 691 q <<= 3; 692 while (q-- > 0) { 693 mask |= (1ULL << q); 694 } 695 696 aes_ctx->ccm_counter_mask = htonll(mask); 697 698 /* 699 * During calculation, we start using counter block 1, we will 700 * set it up right here. 701 * We can just set the last byte to have the value 1, because 702 * even with the biggest nonce of 13, the last byte of the 703 * counter block will be used for the counter value. 704 */ 705 cb[15] = 0x01; 706 } 707 708 /* 709 * Encode the length of the associated data as 710 * specified in RFC 3610 and NIST publication 800-38C, appendix A 711 */ 712 static void 713 encode_adata_len(ulong_t auth_data_len, uint8_t *encoded, size_t *encoded_len) 714 { 715 #ifdef UNALIGNED_POINTERS_PERMITTED 716 uint32_t *lencoded_ptr; 717 #ifdef _LP64 718 uint64_t *llencoded_ptr; 719 #endif 720 #endif /* UNALIGNED_POINTERS_PERMITTED */ 721 722 if (auth_data_len < ((1ULL<<16) - (1ULL<<8))) { 723 /* 0 < a < (2^16-2^8) */ 724 *encoded_len = 2; 725 encoded[0] = (auth_data_len & 0xff00) >> 8; 726 encoded[1] = auth_data_len & 0xff; 727 728 } else if ((auth_data_len >= ((1ULL<<16) - (1ULL<<8))) && 729 (auth_data_len < (1ULL << 31))) { 730 /* (2^16-2^8) <= a < 2^32 */ 731 *encoded_len = 6; 732 encoded[0] = 0xff; 733 encoded[1] = 0xfe; 734 #ifdef UNALIGNED_POINTERS_PERMITTED 735 lencoded_ptr = (uint32_t *)(void *)&encoded[2]; 736 *lencoded_ptr = htonl(auth_data_len); 737 #else 738 encoded[2] = (auth_data_len & 0xff000000) >> 24; 739 encoded[3] = (auth_data_len & 0xff0000) >> 16; 740 encoded[4] = (auth_data_len & 0xff00) >> 8; 741 encoded[5] = auth_data_len & 0xff; 742 #endif /* UNALIGNED_POINTERS_PERMITTED */ 743 744 #ifdef _LP64 745 } else { 746 /* 2^32 <= a < 2^64 */ 747 *encoded_len = 10; 748 encoded[0] = 0xff; 749 encoded[1] = 0xff; 750 #ifdef UNALIGNED_POINTERS_PERMITTED 751 llencoded_ptr = (uint64_t *)(void *)&encoded[2]; 752 *llencoded_ptr = htonl(auth_data_len); 753 #else 754 encoded[2] = (auth_data_len & 0xff00000000000000) >> 56; 755 encoded[3] = (auth_data_len & 0xff000000000000) >> 48; 756 encoded[4] = (auth_data_len & 0xff0000000000) >> 40; 757 encoded[5] = (auth_data_len & 0xff00000000) >> 32; 758 encoded[6] = (auth_data_len & 0xff000000) >> 24; 759 encoded[7] = (auth_data_len & 0xff0000) >> 16; 760 encoded[8] = (auth_data_len & 0xff00) >> 8; 761 encoded[9] = auth_data_len & 0xff; 762 #endif /* UNALIGNED_POINTERS_PERMITTED */ 763 #endif /* _LP64 */ 764 } 765 } 766 767 /* 768 * The following function should be call at encrypt or decrypt init time 769 * for AES CCM mode. 770 */ 771 int 772 ccm_init(ccm_ctx_t *ctx, unsigned char *nonce, size_t nonce_len, 773 unsigned char *auth_data, size_t auth_data_len, size_t block_size, 774 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 775 void (*xor_block)(const uint8_t *, uint8_t *)) 776 { 777 uint8_t *mac_buf, *datap, *ivp, *authp; 778 size_t remainder, processed; 779 uint8_t encoded_a[10]; /* max encoded auth data length is 10 octets */ 780 size_t encoded_a_len = 0; 781 782 mac_buf = (uint8_t *)&(ctx->ccm_mac_buf); 783 784 /* 785 * Format the 1st block for CBC-MAC and construct the 786 * 1st counter block. 787 * 788 * aes_ctx->ccm_iv is used for storing the counter block 789 * mac_buf will store b0 at this time. 790 */ 791 ccm_format_initial_blocks(nonce, nonce_len, 792 auth_data_len, mac_buf, ctx); 793 794 /* The IV for CBC MAC for AES CCM mode is always zero */ 795 ivp = (uint8_t *)ctx->ccm_tmp; 796 bzero(ivp, block_size); 797 798 xor_block(ivp, mac_buf); 799 800 /* encrypt the nonce */ 801 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 802 803 /* take care of the associated data, if any */ 804 if (auth_data_len == 0) { 805 return (CRYPTO_SUCCESS); 806 } 807 808 encode_adata_len(auth_data_len, encoded_a, &encoded_a_len); 809 810 remainder = auth_data_len; 811 812 /* 1st block: it contains encoded associated data, and some data */ 813 authp = (uint8_t *)ctx->ccm_tmp; 814 bzero(authp, block_size); 815 bcopy(encoded_a, authp, encoded_a_len); 816 processed = block_size - encoded_a_len; 817 if (processed > auth_data_len) { 818 /* in case auth_data is very small */ 819 processed = auth_data_len; 820 } 821 bcopy(auth_data, authp+encoded_a_len, processed); 822 /* xor with previous buffer */ 823 xor_block(authp, mac_buf); 824 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 825 remainder -= processed; 826 if (remainder == 0) { 827 /* a small amount of associated data, it's all done now */ 828 return (CRYPTO_SUCCESS); 829 } 830 831 do { 832 if (remainder < block_size) { 833 /* 834 * There's not a block full of data, pad rest of 835 * buffer with zero 836 */ 837 bzero(authp, block_size); 838 bcopy(&(auth_data[processed]), authp, remainder); 839 datap = (uint8_t *)authp; 840 remainder = 0; 841 } else { 842 datap = (uint8_t *)(&(auth_data[processed])); 843 processed += block_size; 844 remainder -= block_size; 845 } 846 847 xor_block(datap, mac_buf); 848 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 849 850 } while (remainder > 0); 851 852 return (CRYPTO_SUCCESS); 853 } 854 855 int 856 ccm_init_ctx(ccm_ctx_t *ccm_ctx, char *param, int kmflag, 857 boolean_t is_encrypt_init, size_t block_size, 858 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 859 void (*xor_block)(const uint8_t *, uint8_t *)) 860 { 861 int rv; 862 CK_AES_CCM_PARAMS *ccm_param; 863 864 if (param != NULL) { 865 ccm_param = (CK_AES_CCM_PARAMS *)(void *)param; 866 867 if ((rv = ccm_validate_args(ccm_param, 868 is_encrypt_init)) != 0) { 869 return (rv); 870 } 871 872 ccm_ctx->ccm_mac_len = ccm_param->ulMACSize; 873 if (is_encrypt_init) { 874 ccm_ctx->ccm_data_len = ccm_param->ulDataSize; 875 } else { 876 ccm_ctx->ccm_data_len = 877 ccm_param->ulDataSize - ccm_ctx->ccm_mac_len; 878 ccm_ctx->ccm_processed_mac_len = 0; 879 } 880 ccm_ctx->ccm_processed_data_len = 0; 881 882 ccm_ctx->ccm_flags |= CCM_MODE; 883 } else { 884 rv = CRYPTO_MECHANISM_PARAM_INVALID; 885 goto out; 886 } 887 888 if (ccm_init(ccm_ctx, ccm_param->nonce, ccm_param->ulNonceSize, 889 ccm_param->authData, ccm_param->ulAuthDataSize, block_size, 890 encrypt_block, xor_block) != 0) { 891 rv = CRYPTO_MECHANISM_PARAM_INVALID; 892 goto out; 893 } 894 if (!is_encrypt_init) { 895 /* allocate buffer for storing decrypted plaintext */ 896 #ifdef _KERNEL 897 ccm_ctx->ccm_pt_buf = kmem_alloc(ccm_ctx->ccm_data_len, 898 kmflag); 899 #else 900 ccm_ctx->ccm_pt_buf = malloc(ccm_ctx->ccm_data_len); 901 #endif 902 if (ccm_ctx->ccm_pt_buf == NULL) { 903 rv = CRYPTO_HOST_MEMORY; 904 } 905 } 906 out: 907 return (rv); 908 } 909 910 void * 911 ccm_alloc_ctx(int kmflag) 912 { 913 ccm_ctx_t *ccm_ctx; 914 915 #ifdef _KERNEL 916 if ((ccm_ctx = kmem_zalloc(sizeof (ccm_ctx_t), kmflag)) == NULL) 917 #else 918 if ((ccm_ctx = calloc(1, sizeof (ccm_ctx_t))) == NULL) 919 #endif 920 return (NULL); 921 922 ccm_ctx->ccm_flags = CCM_MODE; 923 return (ccm_ctx); 924 }