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