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