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