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