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 380 381 pm_len = ctx->ccm_processed_mac_len; 382 383 if (pm_len > 0) { 384 uint8_t *tmp; 385 /* 386 * all ciphertext has been processed, just waiting for 387 * part of the value of the mac 388 */ 389 if ((pm_len + length) > ctx->ccm_mac_len) { 390 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 391 } 392 tmp = (uint8_t *)ctx->ccm_mac_input_buf; 393 394 bcopy(datap, tmp + pm_len, length); 395 396 ctx->ccm_processed_mac_len += length; 397 return (CRYPTO_SUCCESS); 398 } 399 400 /* 401 * If we decrypt the given data, what total amount of data would 402 * have been decrypted? 403 */ 404 pd_len = ctx->ccm_processed_data_len; 405 total_decrypted_len = pd_len + length + ctx->ccm_remainder_len; 406 407 if (total_decrypted_len > 408 (ctx->ccm_data_len + ctx->ccm_mac_len)) { 409 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 410 } 411 412 pt_len = ctx->ccm_data_len; 413 414 if (total_decrypted_len > pt_len) { 415 /* 416 * part of the input will be the MAC, need to isolate that 417 * to be dealt with later. The left-over data in 418 * ccm_remainder_len from last time will not be part of the 419 * MAC. Otherwise, it would have already been taken out 420 * when this call is made last time. 421 */ 422 size_t pt_part = pt_len - pd_len - ctx->ccm_remainder_len; 423 424 mac_len = length - pt_part; 425 426 ctx->ccm_processed_mac_len = mac_len; 427 bcopy(data + pt_part, ctx->ccm_mac_input_buf, mac_len); 428 429 if (pt_part + ctx->ccm_remainder_len < block_size) { 430 /* 431 * since this is last of the ciphertext, will 432 * just decrypt with it here 433 */ 434 bcopy(datap, &((uint8_t *)ctx->ccm_remainder) 435 [ctx->ccm_remainder_len], pt_part); 436 ctx->ccm_remainder_len += pt_part; 437 ccm_decrypt_incomplete_block(ctx, encrypt_block); 438 ctx->ccm_remainder_len = 0; 439 ctx->ccm_processed_data_len += pt_part; 440 return (CRYPTO_SUCCESS); 441 } else { 442 /* let rest of the code handle this */ 443 length = pt_part; 444 } 445 } else if (length + ctx->ccm_remainder_len < block_size) { 446 /* accumulate bytes here and return */ 447 bcopy(datap, 448 (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len, 449 length); 450 ctx->ccm_remainder_len += length; 451 ctx->ccm_copy_to = datap; 452 return (CRYPTO_SUCCESS); 453 } 454 455 do { 456 /* Unprocessed data from last call. */ 457 if (ctx->ccm_remainder_len > 0) { 458 need = block_size - ctx->ccm_remainder_len; 459 460 if (need > remainder) 461 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 462 463 bcopy(datap, &((uint8_t *)ctx->ccm_remainder) 464 [ctx->ccm_remainder_len], need); 465 466 blockp = (uint8_t *)ctx->ccm_remainder; 467 } else { 468 blockp = datap; 469 } 470 471 /* Calculate the counter mode, ccm_cb is the counter block */ 472 cbp = (uint8_t *)ctx->ccm_tmp; 473 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, cbp); 474 475 /* 476 * Increment counter. 477 * Counter bits are confined to the bottom 64 bits 478 */ 479 #ifdef _LITTLE_ENDIAN 480 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask); 481 counter = htonll(counter + 1); 482 #else 483 counter = ctx->ccm_cb[1] & ctx->ccm_counter_mask; 484 counter++; 485 #endif /* _LITTLE_ENDIAN */ 486 counter &= ctx->ccm_counter_mask; 487 ctx->ccm_cb[1] = 488 (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter; 489 490 /* XOR with the ciphertext */ 491 xor_block(blockp, cbp); 492 493 /* Copy the plaintext to the "holding buffer" */ 494 resultp = (uint8_t *)ctx->ccm_pt_buf + 495 ctx->ccm_processed_data_len; 496 copy_block(cbp, resultp); 497 498 ctx->ccm_processed_data_len += block_size; 499 500 ctx->ccm_lastp = blockp; 501 502 /* Update pointer to next block of data to be processed. */ 503 if (ctx->ccm_remainder_len != 0) { 504 datap += need; 505 ctx->ccm_remainder_len = 0; 506 } else { 507 datap += block_size; 508 } 509 510 remainder = (size_t)&data[length] - (size_t)datap; 511 512 /* Incomplete last block */ 513 if (remainder > 0 && remainder < block_size) { 514 bcopy(datap, ctx->ccm_remainder, remainder); 515 ctx->ccm_remainder_len = remainder; 516 ctx->ccm_copy_to = datap; 517 if (ctx->ccm_processed_mac_len > 0) { 518 /* 519 * not expecting anymore ciphertext, just 520 * compute plaintext for the remaining input 521 */ 522 ccm_decrypt_incomplete_block(ctx, 523 encrypt_block); 524 ctx->ccm_processed_data_len += remainder; 525 ctx->ccm_remainder_len = 0; 526 } 527 goto out; 528 } 529 ctx->ccm_copy_to = NULL; 530 531 } while (remainder > 0); 532 533 out: 534 return (CRYPTO_SUCCESS); 535 } 536 537 int 538 ccm_decrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size, 539 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 540 void (*copy_block)(uint8_t *, uint8_t *), 541 void (*xor_block)(uint8_t *, uint8_t *)) 542 { 543 size_t mac_remain, pt_len; 544 uint8_t *pt, *mac_buf, *macp, *ccm_mac_p; 545 void *iov_or_mp; 546 offset_t offset; 547 uint8_t *out_data_1, *out_data_2; 548 size_t out_data_1_len; 549 550 pt_len = ctx->ccm_data_len; 551 552 /* Make sure output buffer can fit all of the plaintext */ 553 if (out->cd_length < pt_len) { 554 return (CRYPTO_DATA_LEN_RANGE); 555 } 556 557 pt = ctx->ccm_pt_buf; 558 mac_remain = ctx->ccm_processed_data_len; 559 mac_buf = (uint8_t *)ctx->ccm_mac_buf; 560 561 macp = (uint8_t *)ctx->ccm_tmp; 562 563 while (mac_remain > 0) { 564 565 if (mac_remain < block_size) { 566 bzero(macp, block_size); 567 bcopy(pt, macp, mac_remain); 568 mac_remain = 0; 569 } else { 570 copy_block(pt, macp); 571 mac_remain -= block_size; 572 pt += block_size; 573 } 574 575 /* calculate the CBC MAC */ 576 xor_block(macp, mac_buf); 577 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 578 } 579 580 /* Calculate the CCM MAC */ 581 ccm_mac_p = (uint8_t *)ctx->ccm_tmp; 582 calculate_ccm_mac((ccm_ctx_t *)ctx, ccm_mac_p, encrypt_block); 583 584 /* compare the input CCM MAC value with what we calculated */ 585 if (bcmp(ctx->ccm_mac_input_buf, ccm_mac_p, ctx->ccm_mac_len)) { 586 /* They don't match */ 587 return (CRYPTO_INVALID_MAC); 588 } else { 589 crypto_init_ptrs(out, &iov_or_mp, &offset); 590 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, 591 &out_data_1_len, &out_data_2, pt_len); 592 bcopy(ctx->ccm_pt_buf, out_data_1, out_data_1_len); 593 if (out_data_2 != NULL) { 594 bcopy((ctx->ccm_pt_buf) + out_data_1_len, 595 out_data_2, pt_len - out_data_1_len); 596 } 597 out->cd_offset += pt_len; 598 } 599 return (CRYPTO_SUCCESS); 600 } 601 602 int 603 ccm_validate_args(CK_AES_CCM_PARAMS *ccm_param, boolean_t is_encrypt_init) 604 { 605 size_t macSize, nonceSize; 606 uint8_t q; 607 uint64_t maxValue; 608 609 /* 610 * Check the length of the MAC. The only valid 611 * lengths for the MAC are: 4, 6, 8, 10, 12, 14, 16 612 */ 613 macSize = ccm_param->ulMACSize; 614 if ((macSize < 4) || (macSize > 16) || ((macSize % 2) != 0)) { 615 return (CRYPTO_MECHANISM_PARAM_INVALID); 616 } 617 618 /* Check the nonce length. Valid values are 7, 8, 9, 10, 11, 12, 13 */ 619 nonceSize = ccm_param->ulNonceSize; 620 if ((nonceSize < 7) || (nonceSize > 13)) { 621 return (CRYPTO_MECHANISM_PARAM_INVALID); 622 } 623 624 /* q is the length of the field storing the length, in bytes */ 625 q = (uint8_t)((15 - nonceSize) & 0xFF); 626 627 628 /* 629 * If it is decrypt, need to make sure size of ciphertext is at least 630 * bigger than MAC len 631 */ 632 if ((!is_encrypt_init) && (ccm_param->ulDataSize < macSize)) { 633 return (CRYPTO_MECHANISM_PARAM_INVALID); 634 } 635 636 /* 637 * Check to make sure the length of the payload is within the 638 * range of values allowed by q 639 */ 640 if (q < 8) { 641 maxValue = (1ULL << (q * 8)) - 1; 642 } else { 643 maxValue = ULONG_MAX; 644 } 645 646 if (ccm_param->ulDataSize > maxValue) { 647 return (CRYPTO_MECHANISM_PARAM_INVALID); 648 } 649 return (CRYPTO_SUCCESS); 650 } 651 652 /* 653 * Format the first block used in CBC-MAC (B0) and the initial counter 654 * block based on formatting functions and counter generation functions 655 * specified in RFC 3610 and NIST publication 800-38C, appendix A 656 * 657 * b0 is the first block used in CBC-MAC 658 * cb0 is the first counter block 659 * 660 * It's assumed that the arguments b0 and cb0 are preallocated AES blocks 661 * 662 */ 663 static void 664 ccm_format_initial_blocks(uchar_t *nonce, ulong_t nonceSize, 665 ulong_t authDataSize, uint8_t *b0, ccm_ctx_t *aes_ctx) 666 { 667 uint64_t payloadSize; 668 uint8_t t, q, have_adata = 0; 669 size_t limit; 670 int i, j, k; 671 uint64_t mask = 0; 672 uint8_t *cb; 673 674 q = (uint8_t)((15 - nonceSize) & 0xFF); 675 t = (uint8_t)((aes_ctx->ccm_mac_len) & 0xFF); 676 677 /* Construct the first octet of b0 */ 678 if (authDataSize > 0) { 679 have_adata = 1; 680 } 681 b0[0] = (have_adata << 6) | (((t - 2) / 2) << 3) | (q - 1); 682 683 /* copy the nonce value into b0 */ 684 bcopy(nonce, &(b0[1]), nonceSize); 685 686 /* store the length of the payload into b0 */ 687 bzero(&(b0[1+nonceSize]), q); 688 689 payloadSize = aes_ctx->ccm_data_len; 690 limit = 8 < q ? 8 : q; 691 692 for (i = 0, j = 0, k = 15; i < limit; i++, j += 8, k--) { 693 b0[k] = (uint8_t)((payloadSize >> j) & 0xFF); 694 } 695 696 /* format the counter block */ 697 698 cb = (uint8_t *)aes_ctx->ccm_cb; 699 700 cb[0] = 0x07 & (q-1); /* first byte */ 701 702 /* copy the nonce value into the counter block */ 703 bcopy(nonce, &(cb[1]), nonceSize); 704 705 bzero(&(cb[1+nonceSize]), q); 706 707 /* Create the mask for the counter field based on the size of nonce */ 708 q <<= 3; 709 while (q-- > 0) { 710 mask |= (1ULL << q); 711 } 712 713 #ifdef _LITTLE_ENDIAN 714 mask = htonll(mask); 715 #endif 716 aes_ctx->ccm_counter_mask = mask; 717 718 /* 719 * During calculation, we start using counter block 1, we will 720 * set it up right here. 721 * We can just set the last byte to have the value 1, because 722 * even with the biggest nonce of 13, the last byte of the 723 * counter block will be used for the counter value. 724 */ 725 cb[15] = 0x01; 726 } 727 728 /* 729 * Encode the length of the associated data as 730 * specified in RFC 3610 and NIST publication 800-38C, appendix A 731 */ 732 static void 733 encode_adata_len(ulong_t auth_data_len, uint8_t *encoded, size_t *encoded_len) 734 { 735 #ifdef UNALIGNED_POINTERS_PERMITTED 736 uint32_t *lencoded_ptr; 737 #ifdef _LP64 738 uint64_t *llencoded_ptr; 739 #endif 740 #endif /* UNALIGNED_POINTERS_PERMITTED */ 741 742 if (auth_data_len < ((1ULL<<16) - (1ULL<<8))) { 743 /* 0 < a < (2^16-2^8) */ 744 *encoded_len = 2; 745 encoded[0] = (auth_data_len & 0xff00) >> 8; 746 encoded[1] = auth_data_len & 0xff; 747 748 } else if ((auth_data_len >= ((1ULL<<16) - (1ULL<<8))) && 749 (auth_data_len < (1ULL << 31))) { 750 /* (2^16-2^8) <= a < 2^32 */ 751 *encoded_len = 6; 752 encoded[0] = 0xff; 753 encoded[1] = 0xfe; 754 #ifdef UNALIGNED_POINTERS_PERMITTED 755 lencoded_ptr = (uint32_t *)&encoded[2]; 756 *lencoded_ptr = htonl(auth_data_len); 757 #else 758 encoded[2] = (auth_data_len & 0xff000000) >> 24; 759 encoded[3] = (auth_data_len & 0xff0000) >> 16; 760 encoded[4] = (auth_data_len & 0xff00) >> 8; 761 encoded[5] = auth_data_len & 0xff; 762 #endif /* UNALIGNED_POINTERS_PERMITTED */ 763 764 #ifdef _LP64 765 } else { 766 /* 2^32 <= a < 2^64 */ 767 *encoded_len = 10; 768 encoded[0] = 0xff; 769 encoded[1] = 0xff; 770 #ifdef UNALIGNED_POINTERS_PERMITTED 771 llencoded_ptr = (uint64_t *)&encoded[2]; 772 *llencoded_ptr = htonl(auth_data_len); 773 #else 774 encoded[2] = (auth_data_len & 0xff00000000000000) >> 56; 775 encoded[3] = (auth_data_len & 0xff000000000000) >> 48; 776 encoded[4] = (auth_data_len & 0xff0000000000) >> 40; 777 encoded[5] = (auth_data_len & 0xff00000000) >> 32; 778 encoded[6] = (auth_data_len & 0xff000000) >> 24; 779 encoded[7] = (auth_data_len & 0xff0000) >> 16; 780 encoded[8] = (auth_data_len & 0xff00) >> 8; 781 encoded[9] = auth_data_len & 0xff; 782 #endif /* UNALIGNED_POINTERS_PERMITTED */ 783 #endif /* _LP64 */ 784 } 785 } 786 787 /* 788 * The following function should be call at encrypt or decrypt init time 789 * for AES CCM mode. 790 */ 791 int 792 ccm_init(ccm_ctx_t *ctx, unsigned char *nonce, size_t nonce_len, 793 unsigned char *auth_data, size_t auth_data_len, size_t block_size, 794 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 795 void (*xor_block)(uint8_t *, uint8_t *)) 796 { 797 uint8_t *mac_buf, *datap, *ivp, *authp; 798 size_t remainder, processed; 799 uint8_t encoded_a[10]; /* max encoded auth data length is 10 octets */ 800 size_t encoded_a_len = 0; 801 802 mac_buf = (uint8_t *)&(ctx->ccm_mac_buf); 803 804 /* 805 * Format the 1st block for CBC-MAC and construct the 806 * 1st counter block. 807 * 808 * aes_ctx->ccm_iv is used for storing the counter block 809 * mac_buf will store b0 at this time. 810 */ 811 ccm_format_initial_blocks(nonce, nonce_len, 812 auth_data_len, mac_buf, ctx); 813 814 /* The IV for CBC MAC for AES CCM mode is always zero */ 815 ivp = (uint8_t *)ctx->ccm_tmp; 816 bzero(ivp, block_size); 817 818 xor_block(ivp, mac_buf); 819 820 /* encrypt the nonce */ 821 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 822 823 /* take care of the associated data, if any */ 824 if (auth_data_len == 0) { 825 return (CRYPTO_SUCCESS); 826 } 827 828 encode_adata_len(auth_data_len, encoded_a, &encoded_a_len); 829 830 remainder = auth_data_len; 831 832 /* 1st block: it contains encoded associated data, and some data */ 833 authp = (uint8_t *)ctx->ccm_tmp; 834 bzero(authp, block_size); 835 bcopy(encoded_a, authp, encoded_a_len); 836 processed = block_size - encoded_a_len; 837 if (processed > auth_data_len) { 838 /* in case auth_data is very small */ 839 processed = auth_data_len; 840 } 841 bcopy(auth_data, authp+encoded_a_len, processed); 842 /* xor with previous buffer */ 843 xor_block(authp, mac_buf); 844 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 845 remainder -= processed; 846 if (remainder == 0) { 847 /* a small amount of associated data, it's all done now */ 848 return (CRYPTO_SUCCESS); 849 } 850 851 do { 852 if (remainder < block_size) { 853 /* 854 * There's not a block full of data, pad rest of 855 * buffer with zero 856 */ 857 bzero(authp, block_size); 858 bcopy(&(auth_data[processed]), authp, remainder); 859 datap = (uint8_t *)authp; 860 remainder = 0; 861 } else { 862 datap = (uint8_t *)(&(auth_data[processed])); 863 processed += block_size; 864 remainder -= block_size; 865 } 866 867 xor_block(datap, mac_buf); 868 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf); 869 870 } while (remainder > 0); 871 872 return (CRYPTO_SUCCESS); 873 } 874 875 int 876 ccm_init_ctx(ccm_ctx_t *ccm_ctx, char *param, int kmflag, 877 boolean_t is_encrypt_init, size_t block_size, 878 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 879 void (*xor_block)(uint8_t *, uint8_t *)) 880 { 881 int rv; 882 CK_AES_CCM_PARAMS *ccm_param; 883 884 if (param != NULL) { 885 ccm_param = (CK_AES_CCM_PARAMS *)param; 886 887 if ((rv = ccm_validate_args(ccm_param, 888 is_encrypt_init)) != 0) { 889 return (rv); 890 } 891 892 ccm_ctx->ccm_mac_len = ccm_param->ulMACSize; 893 if (is_encrypt_init) { 894 ccm_ctx->ccm_data_len = ccm_param->ulDataSize; 895 } else { 896 ccm_ctx->ccm_data_len = 897 ccm_param->ulDataSize - ccm_ctx->ccm_mac_len; 898 ccm_ctx->ccm_processed_mac_len = 0; 899 } 900 ccm_ctx->ccm_processed_data_len = 0; 901 902 ccm_ctx->ccm_flags |= CCM_MODE; 903 } else { 904 rv = CRYPTO_MECHANISM_PARAM_INVALID; 905 goto out; 906 } 907 908 if (ccm_init(ccm_ctx, ccm_param->nonce, ccm_param->ulNonceSize, 909 ccm_param->authData, ccm_param->ulAuthDataSize, block_size, 910 encrypt_block, xor_block) != 0) { 911 rv = CRYPTO_MECHANISM_PARAM_INVALID; 912 goto out; 913 } 914 if (!is_encrypt_init) { 915 /* allocate buffer for storing decrypted plaintext */ 916 #ifdef _KERNEL 917 ccm_ctx->ccm_pt_buf = kmem_alloc(ccm_ctx->ccm_data_len, 918 kmflag); 919 #else 920 ccm_ctx->ccm_pt_buf = malloc(ccm_ctx->ccm_data_len); 921 #endif 922 if (ccm_ctx->ccm_pt_buf == NULL) { 923 rv = CRYPTO_HOST_MEMORY; 924 } 925 } 926 out: 927 return (rv); 928 } 929 930 void * 931 ccm_alloc_ctx(int kmflag) 932 { 933 ccm_ctx_t *ccm_ctx; 934 935 #ifdef _KERNEL 936 if ((ccm_ctx = kmem_zalloc(sizeof (ccm_ctx_t), kmflag)) == NULL) 937 #else 938 if ((ccm_ctx = calloc(1, sizeof (ccm_ctx_t))) == NULL) 939 #endif 940 return (NULL); 941 942 ccm_ctx->ccm_flags = CCM_MODE; 943 return (ccm_ctx); 944 } 945