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