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 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/modctl.h> 28 #include <sys/cmn_err.h> 29 #include <sys/note.h> 30 #include <sys/crypto/common.h> 31 #include <sys/crypto/spi.h> 32 #include <sys/strsun.h> 33 #include <sys/systm.h> 34 #include <sys/sysmacros.h> 35 36 #include <sys/sha1.h> 37 #include <sha1/sha1_impl.h> 38 39 /* 40 * The sha1 module is created with two modlinkages: 41 * - a modlmisc that allows consumers to directly call the entry points 42 * SHA1Init, SHA1Update, and SHA1Final. 43 * - a modlcrypto that allows the module to register with the Kernel 44 * Cryptographic Framework (KCF) as a software provider for the SHA1 45 * mechanisms. 46 */ 47 48 static struct modlmisc modlmisc = { 49 &mod_miscops, 50 "SHA1 Message-Digest Algorithm" 51 }; 52 53 static struct modlcrypto modlcrypto = { 54 &mod_cryptoops, 55 "SHA1 Kernel SW Provider 1.1" 56 }; 57 58 static struct modlinkage modlinkage = { 59 MODREV_1, &modlmisc, &modlcrypto, NULL 60 }; 61 62 63 /* 64 * Macros to access the SHA1 or SHA1-HMAC contexts from a context passed 65 * by KCF to one of the entry points. 66 */ 67 68 #define PROV_SHA1_CTX(ctx) ((sha1_ctx_t *)(ctx)->cc_provider_private) 69 #define PROV_SHA1_HMAC_CTX(ctx) ((sha1_hmac_ctx_t *)(ctx)->cc_provider_private) 70 71 /* to extract the digest length passed as mechanism parameter */ 72 #define PROV_SHA1_GET_DIGEST_LEN(m, len) { \ 73 if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \ 74 (len) = (uint32_t)*((ulong_t *)(void *)mechanism->cm_param); \ 75 else { \ 76 ulong_t tmp_ulong; \ 77 bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \ 78 (len) = (uint32_t)tmp_ulong; \ 79 } \ 80 } 81 82 #define PROV_SHA1_DIGEST_KEY(ctx, key, len, digest) { \ 83 SHA1Init(ctx); \ 84 SHA1Update(ctx, key, len); \ 85 SHA1Final(digest, ctx); \ 86 } 87 88 /* 89 * Mechanism info structure passed to KCF during registration. 90 */ 91 static crypto_mech_info_t sha1_mech_info_tab[] = { 92 /* SHA1 */ 93 {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE, 94 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 95 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 96 /* SHA1-HMAC */ 97 {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE, 98 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 99 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN, 100 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 101 /* SHA1-HMAC GENERAL */ 102 {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE, 103 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 104 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN, 105 CRYPTO_KEYSIZE_UNIT_IN_BYTES} 106 }; 107 108 static void sha1_provider_status(crypto_provider_handle_t, uint_t *); 109 110 static crypto_control_ops_t sha1_control_ops = { 111 sha1_provider_status 112 }; 113 114 static int sha1_digest_init(crypto_ctx_t *, crypto_mechanism_t *, 115 crypto_req_handle_t); 116 static int sha1_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 117 crypto_req_handle_t); 118 static int sha1_digest_update(crypto_ctx_t *, crypto_data_t *, 119 crypto_req_handle_t); 120 static int sha1_digest_final(crypto_ctx_t *, crypto_data_t *, 121 crypto_req_handle_t); 122 static int sha1_digest_atomic(crypto_provider_handle_t, crypto_session_id_t, 123 crypto_mechanism_t *, crypto_data_t *, crypto_data_t *, 124 crypto_req_handle_t); 125 126 static crypto_digest_ops_t sha1_digest_ops = { 127 sha1_digest_init, 128 sha1_digest, 129 sha1_digest_update, 130 NULL, 131 sha1_digest_final, 132 sha1_digest_atomic 133 }; 134 135 static int sha1_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, 136 crypto_spi_ctx_template_t, crypto_req_handle_t); 137 static int sha1_mac_update(crypto_ctx_t *, crypto_data_t *, 138 crypto_req_handle_t); 139 static int sha1_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t); 140 static int sha1_mac_atomic(crypto_provider_handle_t, crypto_session_id_t, 141 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 142 crypto_spi_ctx_template_t, crypto_req_handle_t); 143 static int sha1_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 144 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 145 crypto_spi_ctx_template_t, crypto_req_handle_t); 146 147 static crypto_mac_ops_t sha1_mac_ops = { 148 sha1_mac_init, 149 NULL, 150 sha1_mac_update, 151 sha1_mac_final, 152 sha1_mac_atomic, 153 sha1_mac_verify_atomic 154 }; 155 156 static int sha1_create_ctx_template(crypto_provider_handle_t, 157 crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *, 158 size_t *, crypto_req_handle_t); 159 static int sha1_free_context(crypto_ctx_t *); 160 161 static crypto_ctx_ops_t sha1_ctx_ops = { 162 sha1_create_ctx_template, 163 sha1_free_context 164 }; 165 166 static crypto_ops_t sha1_crypto_ops = { 167 &sha1_control_ops, 168 &sha1_digest_ops, 169 NULL, 170 &sha1_mac_ops, 171 NULL, 172 NULL, 173 NULL, 174 NULL, 175 NULL, 176 NULL, 177 NULL, 178 NULL, 179 NULL, 180 &sha1_ctx_ops, 181 NULL, 182 NULL, 183 NULL, 184 }; 185 186 static crypto_provider_info_t sha1_prov_info = { 187 CRYPTO_SPI_VERSION_4, 188 "SHA1 Software Provider", 189 CRYPTO_SW_PROVIDER, 190 {&modlinkage}, 191 NULL, 192 &sha1_crypto_ops, 193 sizeof (sha1_mech_info_tab)/sizeof (crypto_mech_info_t), 194 sha1_mech_info_tab 195 }; 196 197 static crypto_kcf_provider_handle_t sha1_prov_handle = 0; 198 199 int 200 _init() 201 { 202 int ret; 203 204 if ((ret = mod_install(&modlinkage)) != 0) 205 return (ret); 206 207 /* 208 * Register with KCF. If the registration fails, log do not uninstall 209 * the module, since the functionality provided by misc/sha1 should 210 * still be available. 211 */ 212 (void) crypto_register_provider(&sha1_prov_info, &sha1_prov_handle); 213 214 return (0); 215 } 216 217 int 218 _info(struct modinfo *modinfop) 219 { 220 return (mod_info(&modlinkage, modinfop)); 221 } 222 223 /* 224 * KCF software provider control entry points. 225 */ 226 /* ARGSUSED */ 227 static void 228 sha1_provider_status(crypto_provider_handle_t provider, uint_t *status) 229 { 230 *status = CRYPTO_PROVIDER_READY; 231 } 232 233 /* 234 * KCF software provider digest entry points. 235 */ 236 237 static int 238 sha1_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 239 crypto_req_handle_t req) 240 { 241 if (mechanism->cm_type != SHA1_MECH_INFO_TYPE) 242 return (CRYPTO_MECHANISM_INVALID); 243 244 /* 245 * Allocate and initialize SHA1 context. 246 */ 247 ctx->cc_provider_private = kmem_alloc(sizeof (sha1_ctx_t), 248 crypto_kmflag(req)); 249 if (ctx->cc_provider_private == NULL) 250 return (CRYPTO_HOST_MEMORY); 251 252 PROV_SHA1_CTX(ctx)->sc_mech_type = SHA1_MECH_INFO_TYPE; 253 SHA1Init(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx); 254 255 return (CRYPTO_SUCCESS); 256 } 257 258 /* 259 * Helper SHA1 digest update function for uio data. 260 */ 261 static int 262 sha1_digest_update_uio(SHA1_CTX *sha1_ctx, crypto_data_t *data) 263 { 264 off_t offset = data->cd_offset; 265 size_t length = data->cd_length; 266 uint_t vec_idx; 267 size_t cur_len; 268 269 /* we support only kernel buffer */ 270 if (data->cd_uio->uio_segflg != UIO_SYSSPACE) 271 return (CRYPTO_ARGUMENTS_BAD); 272 273 /* 274 * Jump to the first iovec containing data to be 275 * digested. 276 */ 277 for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt && 278 offset >= data->cd_uio->uio_iov[vec_idx].iov_len; 279 offset -= data->cd_uio->uio_iov[vec_idx++].iov_len) 280 ; 281 if (vec_idx == data->cd_uio->uio_iovcnt) { 282 /* 283 * The caller specified an offset that is larger than the 284 * total size of the buffers it provided. 285 */ 286 return (CRYPTO_DATA_LEN_RANGE); 287 } 288 289 /* 290 * Now do the digesting on the iovecs. 291 */ 292 while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) { 293 cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len - 294 offset, length); 295 296 SHA1Update(sha1_ctx, 297 (uint8_t *)data->cd_uio->uio_iov[vec_idx].iov_base + offset, 298 cur_len); 299 300 length -= cur_len; 301 vec_idx++; 302 offset = 0; 303 } 304 305 if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) { 306 /* 307 * The end of the specified iovec's was reached but 308 * the length requested could not be processed, i.e. 309 * The caller requested to digest more data than it provided. 310 */ 311 return (CRYPTO_DATA_LEN_RANGE); 312 } 313 314 return (CRYPTO_SUCCESS); 315 } 316 317 /* 318 * Helper SHA1 digest final function for uio data. 319 * digest_len is the length of the desired digest. If digest_len 320 * is smaller than the default SHA1 digest length, the caller 321 * must pass a scratch buffer, digest_scratch, which must 322 * be at least SHA1_DIGEST_LENGTH bytes. 323 */ 324 static int 325 sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest, 326 ulong_t digest_len, uchar_t *digest_scratch) 327 { 328 off_t offset = digest->cd_offset; 329 uint_t vec_idx; 330 331 /* we support only kernel buffer */ 332 if (digest->cd_uio->uio_segflg != UIO_SYSSPACE) 333 return (CRYPTO_ARGUMENTS_BAD); 334 335 /* 336 * Jump to the first iovec containing ptr to the digest to 337 * be returned. 338 */ 339 for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len && 340 vec_idx < digest->cd_uio->uio_iovcnt; 341 offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len) 342 ; 343 if (vec_idx == digest->cd_uio->uio_iovcnt) { 344 /* 345 * The caller specified an offset that is 346 * larger than the total size of the buffers 347 * it provided. 348 */ 349 return (CRYPTO_DATA_LEN_RANGE); 350 } 351 352 if (offset + digest_len <= 353 digest->cd_uio->uio_iov[vec_idx].iov_len) { 354 /* 355 * The computed SHA1 digest will fit in the current 356 * iovec. 357 */ 358 if (digest_len != SHA1_DIGEST_LENGTH) { 359 /* 360 * The caller requested a short digest. Digest 361 * into a scratch buffer and return to 362 * the user only what was requested. 363 */ 364 SHA1Final(digest_scratch, sha1_ctx); 365 bcopy(digest_scratch, (uchar_t *)digest-> 366 cd_uio->uio_iov[vec_idx].iov_base + offset, 367 digest_len); 368 } else { 369 SHA1Final((uchar_t *)digest-> 370 cd_uio->uio_iov[vec_idx].iov_base + offset, 371 sha1_ctx); 372 } 373 } else { 374 /* 375 * The computed digest will be crossing one or more iovec's. 376 * This is bad performance-wise but we need to support it. 377 * Allocate a small scratch buffer on the stack and 378 * copy it piece meal to the specified digest iovec's. 379 */ 380 uchar_t digest_tmp[SHA1_DIGEST_LENGTH]; 381 off_t scratch_offset = 0; 382 size_t length = digest_len; 383 size_t cur_len; 384 385 SHA1Final(digest_tmp, sha1_ctx); 386 387 while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) { 388 cur_len = MIN(digest->cd_uio->uio_iov[vec_idx].iov_len - 389 offset, length); 390 bcopy(digest_tmp + scratch_offset, 391 digest->cd_uio->uio_iov[vec_idx].iov_base + offset, 392 cur_len); 393 394 length -= cur_len; 395 vec_idx++; 396 scratch_offset += cur_len; 397 offset = 0; 398 } 399 400 if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) { 401 /* 402 * The end of the specified iovec's was reached but 403 * the length requested could not be processed, i.e. 404 * The caller requested to digest more data than it 405 * provided. 406 */ 407 return (CRYPTO_DATA_LEN_RANGE); 408 } 409 } 410 411 return (CRYPTO_SUCCESS); 412 } 413 414 /* 415 * Helper SHA1 digest update for mblk's. 416 */ 417 static int 418 sha1_digest_update_mblk(SHA1_CTX *sha1_ctx, crypto_data_t *data) 419 { 420 off_t offset = data->cd_offset; 421 size_t length = data->cd_length; 422 mblk_t *mp; 423 size_t cur_len; 424 425 /* 426 * Jump to the first mblk_t containing data to be digested. 427 */ 428 for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp); 429 offset -= MBLKL(mp), mp = mp->b_cont) 430 ; 431 if (mp == NULL) { 432 /* 433 * The caller specified an offset that is larger than the 434 * total size of the buffers it provided. 435 */ 436 return (CRYPTO_DATA_LEN_RANGE); 437 } 438 439 /* 440 * Now do the digesting on the mblk chain. 441 */ 442 while (mp != NULL && length > 0) { 443 cur_len = MIN(MBLKL(mp) - offset, length); 444 SHA1Update(sha1_ctx, mp->b_rptr + offset, cur_len); 445 length -= cur_len; 446 offset = 0; 447 mp = mp->b_cont; 448 } 449 450 if (mp == NULL && length > 0) { 451 /* 452 * The end of the mblk was reached but the length requested 453 * could not be processed, i.e. The caller requested 454 * to digest more data than it provided. 455 */ 456 return (CRYPTO_DATA_LEN_RANGE); 457 } 458 459 return (CRYPTO_SUCCESS); 460 } 461 462 /* 463 * Helper SHA1 digest final for mblk's. 464 * digest_len is the length of the desired digest. If digest_len 465 * is smaller than the default SHA1 digest length, the caller 466 * must pass a scratch buffer, digest_scratch, which must 467 * be at least SHA1_DIGEST_LENGTH bytes. 468 */ 469 static int 470 sha1_digest_final_mblk(SHA1_CTX *sha1_ctx, crypto_data_t *digest, 471 ulong_t digest_len, uchar_t *digest_scratch) 472 { 473 off_t offset = digest->cd_offset; 474 mblk_t *mp; 475 476 /* 477 * Jump to the first mblk_t that will be used to store the digest. 478 */ 479 for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp); 480 offset -= MBLKL(mp), mp = mp->b_cont) 481 ; 482 if (mp == NULL) { 483 /* 484 * The caller specified an offset that is larger than the 485 * total size of the buffers it provided. 486 */ 487 return (CRYPTO_DATA_LEN_RANGE); 488 } 489 490 if (offset + digest_len <= MBLKL(mp)) { 491 /* 492 * The computed SHA1 digest will fit in the current mblk. 493 * Do the SHA1Final() in-place. 494 */ 495 if (digest_len != SHA1_DIGEST_LENGTH) { 496 /* 497 * The caller requested a short digest. Digest 498 * into a scratch buffer and return to 499 * the user only what was requested. 500 */ 501 SHA1Final(digest_scratch, sha1_ctx); 502 bcopy(digest_scratch, mp->b_rptr + offset, digest_len); 503 } else { 504 SHA1Final(mp->b_rptr + offset, sha1_ctx); 505 } 506 } else { 507 /* 508 * The computed digest will be crossing one or more mblk's. 509 * This is bad performance-wise but we need to support it. 510 * Allocate a small scratch buffer on the stack and 511 * copy it piece meal to the specified digest iovec's. 512 */ 513 uchar_t digest_tmp[SHA1_DIGEST_LENGTH]; 514 off_t scratch_offset = 0; 515 size_t length = digest_len; 516 size_t cur_len; 517 518 SHA1Final(digest_tmp, sha1_ctx); 519 520 while (mp != NULL && length > 0) { 521 cur_len = MIN(MBLKL(mp) - offset, length); 522 bcopy(digest_tmp + scratch_offset, 523 mp->b_rptr + offset, cur_len); 524 525 length -= cur_len; 526 mp = mp->b_cont; 527 scratch_offset += cur_len; 528 offset = 0; 529 } 530 531 if (mp == NULL && length > 0) { 532 /* 533 * The end of the specified mblk was reached but 534 * the length requested could not be processed, i.e. 535 * The caller requested to digest more data than it 536 * provided. 537 */ 538 return (CRYPTO_DATA_LEN_RANGE); 539 } 540 } 541 542 return (CRYPTO_SUCCESS); 543 } 544 545 /* ARGSUSED */ 546 static int 547 sha1_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest, 548 crypto_req_handle_t req) 549 { 550 int ret = CRYPTO_SUCCESS; 551 552 ASSERT(ctx->cc_provider_private != NULL); 553 554 /* 555 * We need to just return the length needed to store the output. 556 * We should not destroy the context for the following cases. 557 */ 558 if ((digest->cd_length == 0) || 559 (digest->cd_length < SHA1_DIGEST_LENGTH)) { 560 digest->cd_length = SHA1_DIGEST_LENGTH; 561 return (CRYPTO_BUFFER_TOO_SMALL); 562 } 563 564 /* 565 * Do the SHA1 update on the specified input data. 566 */ 567 switch (data->cd_format) { 568 case CRYPTO_DATA_RAW: 569 SHA1Update(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 570 (uint8_t *)data->cd_raw.iov_base + data->cd_offset, 571 data->cd_length); 572 break; 573 case CRYPTO_DATA_UIO: 574 ret = sha1_digest_update_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 575 data); 576 break; 577 case CRYPTO_DATA_MBLK: 578 ret = sha1_digest_update_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 579 data); 580 break; 581 default: 582 ret = CRYPTO_ARGUMENTS_BAD; 583 } 584 585 if (ret != CRYPTO_SUCCESS) { 586 /* the update failed, free context and bail */ 587 kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t)); 588 ctx->cc_provider_private = NULL; 589 digest->cd_length = 0; 590 return (ret); 591 } 592 593 /* 594 * Do a SHA1 final, must be done separately since the digest 595 * type can be different than the input data type. 596 */ 597 switch (digest->cd_format) { 598 case CRYPTO_DATA_RAW: 599 SHA1Final((unsigned char *)digest->cd_raw.iov_base + 600 digest->cd_offset, &PROV_SHA1_CTX(ctx)->sc_sha1_ctx); 601 break; 602 case CRYPTO_DATA_UIO: 603 ret = sha1_digest_final_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 604 digest, SHA1_DIGEST_LENGTH, NULL); 605 break; 606 case CRYPTO_DATA_MBLK: 607 ret = sha1_digest_final_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 608 digest, SHA1_DIGEST_LENGTH, NULL); 609 break; 610 default: 611 ret = CRYPTO_ARGUMENTS_BAD; 612 } 613 614 /* all done, free context and return */ 615 616 if (ret == CRYPTO_SUCCESS) { 617 digest->cd_length = SHA1_DIGEST_LENGTH; 618 } else { 619 digest->cd_length = 0; 620 } 621 622 kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t)); 623 ctx->cc_provider_private = NULL; 624 return (ret); 625 } 626 627 /* ARGSUSED */ 628 static int 629 sha1_digest_update(crypto_ctx_t *ctx, crypto_data_t *data, 630 crypto_req_handle_t req) 631 { 632 int ret = CRYPTO_SUCCESS; 633 634 ASSERT(ctx->cc_provider_private != NULL); 635 636 /* 637 * Do the SHA1 update on the specified input data. 638 */ 639 switch (data->cd_format) { 640 case CRYPTO_DATA_RAW: 641 SHA1Update(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 642 (uint8_t *)data->cd_raw.iov_base + data->cd_offset, 643 data->cd_length); 644 break; 645 case CRYPTO_DATA_UIO: 646 ret = sha1_digest_update_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 647 data); 648 break; 649 case CRYPTO_DATA_MBLK: 650 ret = sha1_digest_update_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 651 data); 652 break; 653 default: 654 ret = CRYPTO_ARGUMENTS_BAD; 655 } 656 657 return (ret); 658 } 659 660 /* ARGSUSED */ 661 static int 662 sha1_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest, 663 crypto_req_handle_t req) 664 { 665 int ret = CRYPTO_SUCCESS; 666 667 ASSERT(ctx->cc_provider_private != NULL); 668 669 /* 670 * We need to just return the length needed to store the output. 671 * We should not destroy the context for the following cases. 672 */ 673 if ((digest->cd_length == 0) || 674 (digest->cd_length < SHA1_DIGEST_LENGTH)) { 675 digest->cd_length = SHA1_DIGEST_LENGTH; 676 return (CRYPTO_BUFFER_TOO_SMALL); 677 } 678 679 /* 680 * Do a SHA1 final. 681 */ 682 switch (digest->cd_format) { 683 case CRYPTO_DATA_RAW: 684 SHA1Final((unsigned char *)digest->cd_raw.iov_base + 685 digest->cd_offset, &PROV_SHA1_CTX(ctx)->sc_sha1_ctx); 686 break; 687 case CRYPTO_DATA_UIO: 688 ret = sha1_digest_final_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 689 digest, SHA1_DIGEST_LENGTH, NULL); 690 break; 691 case CRYPTO_DATA_MBLK: 692 ret = sha1_digest_final_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx, 693 digest, SHA1_DIGEST_LENGTH, NULL); 694 break; 695 default: 696 ret = CRYPTO_ARGUMENTS_BAD; 697 } 698 699 /* all done, free context and return */ 700 701 if (ret == CRYPTO_SUCCESS) { 702 digest->cd_length = SHA1_DIGEST_LENGTH; 703 } else { 704 digest->cd_length = 0; 705 } 706 707 kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t)); 708 ctx->cc_provider_private = NULL; 709 710 return (ret); 711 } 712 713 /* ARGSUSED */ 714 static int 715 sha1_digest_atomic(crypto_provider_handle_t provider, 716 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 717 crypto_data_t *data, crypto_data_t *digest, 718 crypto_req_handle_t req) 719 { 720 int ret = CRYPTO_SUCCESS; 721 SHA1_CTX sha1_ctx; 722 723 if (mechanism->cm_type != SHA1_MECH_INFO_TYPE) 724 return (CRYPTO_MECHANISM_INVALID); 725 726 /* 727 * Do the SHA1 init. 728 */ 729 SHA1Init(&sha1_ctx); 730 731 /* 732 * Do the SHA1 update on the specified input data. 733 */ 734 switch (data->cd_format) { 735 case CRYPTO_DATA_RAW: 736 SHA1Update(&sha1_ctx, 737 (uint8_t *)data->cd_raw.iov_base + data->cd_offset, 738 data->cd_length); 739 break; 740 case CRYPTO_DATA_UIO: 741 ret = sha1_digest_update_uio(&sha1_ctx, data); 742 break; 743 case CRYPTO_DATA_MBLK: 744 ret = sha1_digest_update_mblk(&sha1_ctx, data); 745 break; 746 default: 747 ret = CRYPTO_ARGUMENTS_BAD; 748 } 749 750 if (ret != CRYPTO_SUCCESS) { 751 /* the update failed, bail */ 752 digest->cd_length = 0; 753 return (ret); 754 } 755 756 /* 757 * Do a SHA1 final, must be done separately since the digest 758 * type can be different than the input data type. 759 */ 760 switch (digest->cd_format) { 761 case CRYPTO_DATA_RAW: 762 SHA1Final((unsigned char *)digest->cd_raw.iov_base + 763 digest->cd_offset, &sha1_ctx); 764 break; 765 case CRYPTO_DATA_UIO: 766 ret = sha1_digest_final_uio(&sha1_ctx, digest, 767 SHA1_DIGEST_LENGTH, NULL); 768 break; 769 case CRYPTO_DATA_MBLK: 770 ret = sha1_digest_final_mblk(&sha1_ctx, digest, 771 SHA1_DIGEST_LENGTH, NULL); 772 break; 773 default: 774 ret = CRYPTO_ARGUMENTS_BAD; 775 } 776 777 if (ret == CRYPTO_SUCCESS) { 778 digest->cd_length = SHA1_DIGEST_LENGTH; 779 } else { 780 digest->cd_length = 0; 781 } 782 783 return (ret); 784 } 785 786 /* 787 * KCF software provider mac entry points. 788 * 789 * SHA1 HMAC is: SHA1(key XOR opad, SHA1(key XOR ipad, text)) 790 * 791 * Init: 792 * The initialization routine initializes what we denote 793 * as the inner and outer contexts by doing 794 * - for inner context: SHA1(key XOR ipad) 795 * - for outer context: SHA1(key XOR opad) 796 * 797 * Update: 798 * Each subsequent SHA1 HMAC update will result in an 799 * update of the inner context with the specified data. 800 * 801 * Final: 802 * The SHA1 HMAC final will do a SHA1 final operation on the 803 * inner context, and the resulting digest will be used 804 * as the data for an update on the outer context. Last 805 * but not least, a SHA1 final on the outer context will 806 * be performed to obtain the SHA1 HMAC digest to return 807 * to the user. 808 */ 809 810 /* 811 * Initialize a SHA1-HMAC context. 812 */ 813 static void 814 sha1_mac_init_ctx(sha1_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes) 815 { 816 uint32_t ipad[SHA1_HMAC_INTS_PER_BLOCK]; 817 uint32_t opad[SHA1_HMAC_INTS_PER_BLOCK]; 818 uint_t i; 819 820 bzero(ipad, SHA1_HMAC_BLOCK_SIZE); 821 bzero(opad, SHA1_HMAC_BLOCK_SIZE); 822 823 bcopy(keyval, ipad, length_in_bytes); 824 bcopy(keyval, opad, length_in_bytes); 825 826 /* XOR key with ipad (0x36) and opad (0x5c) */ 827 for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) { 828 ipad[i] ^= 0x36363636; 829 opad[i] ^= 0x5c5c5c5c; 830 } 831 832 /* perform SHA1 on ipad */ 833 SHA1Init(&ctx->hc_icontext); 834 SHA1Update(&ctx->hc_icontext, (uint8_t *)ipad, SHA1_HMAC_BLOCK_SIZE); 835 836 /* perform SHA1 on opad */ 837 SHA1Init(&ctx->hc_ocontext); 838 SHA1Update(&ctx->hc_ocontext, (uint8_t *)opad, SHA1_HMAC_BLOCK_SIZE); 839 } 840 841 /* 842 */ 843 static int 844 sha1_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 845 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 846 crypto_req_handle_t req) 847 { 848 int ret = CRYPTO_SUCCESS; 849 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 850 851 if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE && 852 mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE) 853 return (CRYPTO_MECHANISM_INVALID); 854 855 /* Add support for key by attributes (RFE 4706552) */ 856 if (key->ck_format != CRYPTO_KEY_RAW) 857 return (CRYPTO_ARGUMENTS_BAD); 858 859 ctx->cc_provider_private = kmem_alloc(sizeof (sha1_hmac_ctx_t), 860 crypto_kmflag(req)); 861 if (ctx->cc_provider_private == NULL) 862 return (CRYPTO_HOST_MEMORY); 863 864 if (ctx_template != NULL) { 865 /* reuse context template */ 866 bcopy(ctx_template, PROV_SHA1_HMAC_CTX(ctx), 867 sizeof (sha1_hmac_ctx_t)); 868 } else { 869 /* no context template, compute context */ 870 if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) { 871 uchar_t digested_key[SHA1_DIGEST_LENGTH]; 872 sha1_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private; 873 874 /* 875 * Hash the passed-in key to get a smaller key. 876 * The inner context is used since it hasn't been 877 * initialized yet. 878 */ 879 PROV_SHA1_DIGEST_KEY(&hmac_ctx->hc_icontext, 880 key->ck_data, keylen_in_bytes, digested_key); 881 sha1_mac_init_ctx(PROV_SHA1_HMAC_CTX(ctx), 882 digested_key, SHA1_DIGEST_LENGTH); 883 } else { 884 sha1_mac_init_ctx(PROV_SHA1_HMAC_CTX(ctx), 885 key->ck_data, keylen_in_bytes); 886 } 887 } 888 889 /* 890 * Get the mechanism parameters, if applicable. 891 */ 892 PROV_SHA1_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type; 893 if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) { 894 if (mechanism->cm_param == NULL || 895 mechanism->cm_param_len != sizeof (ulong_t)) 896 ret = CRYPTO_MECHANISM_PARAM_INVALID; 897 PROV_SHA1_GET_DIGEST_LEN(mechanism, 898 PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len); 899 if (PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len > 900 SHA1_DIGEST_LENGTH) 901 ret = CRYPTO_MECHANISM_PARAM_INVALID; 902 } 903 904 if (ret != CRYPTO_SUCCESS) { 905 bzero(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t)); 906 kmem_free(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t)); 907 ctx->cc_provider_private = NULL; 908 } 909 910 return (ret); 911 } 912 913 /* ARGSUSED */ 914 static int 915 sha1_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 916 { 917 int ret = CRYPTO_SUCCESS; 918 919 ASSERT(ctx->cc_provider_private != NULL); 920 921 /* 922 * Do a SHA1 update of the inner context using the specified 923 * data. 924 */ 925 switch (data->cd_format) { 926 case CRYPTO_DATA_RAW: 927 SHA1Update(&PROV_SHA1_HMAC_CTX(ctx)->hc_icontext, 928 (uint8_t *)data->cd_raw.iov_base + data->cd_offset, 929 data->cd_length); 930 break; 931 case CRYPTO_DATA_UIO: 932 ret = sha1_digest_update_uio( 933 &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext, data); 934 break; 935 case CRYPTO_DATA_MBLK: 936 ret = sha1_digest_update_mblk( 937 &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext, data); 938 break; 939 default: 940 ret = CRYPTO_ARGUMENTS_BAD; 941 } 942 943 return (ret); 944 } 945 946 /* ARGSUSED */ 947 static int 948 sha1_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req) 949 { 950 int ret = CRYPTO_SUCCESS; 951 uchar_t digest[SHA1_DIGEST_LENGTH]; 952 uint32_t digest_len = SHA1_DIGEST_LENGTH; 953 954 ASSERT(ctx->cc_provider_private != NULL); 955 956 if (PROV_SHA1_HMAC_CTX(ctx)->hc_mech_type == 957 SHA1_HMAC_GEN_MECH_INFO_TYPE) 958 digest_len = PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len; 959 960 /* 961 * We need to just return the length needed to store the output. 962 * We should not destroy the context for the following cases. 963 */ 964 if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) { 965 mac->cd_length = digest_len; 966 return (CRYPTO_BUFFER_TOO_SMALL); 967 } 968 969 /* 970 * Do a SHA1 final on the inner context. 971 */ 972 SHA1Final(digest, &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext); 973 974 /* 975 * Do a SHA1 update on the outer context, feeding the inner 976 * digest as data. 977 */ 978 SHA1Update(&PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, digest, 979 SHA1_DIGEST_LENGTH); 980 981 /* 982 * Do a SHA1 final on the outer context, storing the computing 983 * digest in the users buffer. 984 */ 985 switch (mac->cd_format) { 986 case CRYPTO_DATA_RAW: 987 if (digest_len != SHA1_DIGEST_LENGTH) { 988 /* 989 * The caller requested a short digest. Digest 990 * into a scratch buffer and return to 991 * the user only what was requested. 992 */ 993 SHA1Final(digest, 994 &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext); 995 bcopy(digest, (unsigned char *)mac->cd_raw.iov_base + 996 mac->cd_offset, digest_len); 997 } else { 998 SHA1Final((unsigned char *)mac->cd_raw.iov_base + 999 mac->cd_offset, 1000 &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext); 1001 } 1002 break; 1003 case CRYPTO_DATA_UIO: 1004 ret = sha1_digest_final_uio( 1005 &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, mac, 1006 digest_len, digest); 1007 break; 1008 case CRYPTO_DATA_MBLK: 1009 ret = sha1_digest_final_mblk( 1010 &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, mac, 1011 digest_len, digest); 1012 break; 1013 default: 1014 ret = CRYPTO_ARGUMENTS_BAD; 1015 } 1016 1017 if (ret == CRYPTO_SUCCESS) { 1018 mac->cd_length = digest_len; 1019 } else { 1020 mac->cd_length = 0; 1021 } 1022 1023 bzero(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t)); 1024 kmem_free(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t)); 1025 ctx->cc_provider_private = NULL; 1026 1027 return (ret); 1028 } 1029 1030 #define SHA1_MAC_UPDATE(data, ctx, ret) { \ 1031 switch (data->cd_format) { \ 1032 case CRYPTO_DATA_RAW: \ 1033 SHA1Update(&(ctx).hc_icontext, \ 1034 (uint8_t *)data->cd_raw.iov_base + \ 1035 data->cd_offset, data->cd_length); \ 1036 break; \ 1037 case CRYPTO_DATA_UIO: \ 1038 ret = sha1_digest_update_uio(&(ctx).hc_icontext, data); \ 1039 break; \ 1040 case CRYPTO_DATA_MBLK: \ 1041 ret = sha1_digest_update_mblk(&(ctx).hc_icontext, \ 1042 data); \ 1043 break; \ 1044 default: \ 1045 ret = CRYPTO_ARGUMENTS_BAD; \ 1046 } \ 1047 } 1048 1049 /* ARGSUSED */ 1050 static int 1051 sha1_mac_atomic(crypto_provider_handle_t provider, 1052 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1053 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 1054 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 1055 { 1056 int ret = CRYPTO_SUCCESS; 1057 uchar_t digest[SHA1_DIGEST_LENGTH]; 1058 sha1_hmac_ctx_t sha1_hmac_ctx; 1059 uint32_t digest_len = SHA1_DIGEST_LENGTH; 1060 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 1061 1062 if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE && 1063 mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE) 1064 return (CRYPTO_MECHANISM_INVALID); 1065 1066 /* Add support for key by attributes (RFE 4706552) */ 1067 if (key->ck_format != CRYPTO_KEY_RAW) 1068 return (CRYPTO_ARGUMENTS_BAD); 1069 1070 if (ctx_template != NULL) { 1071 /* reuse context template */ 1072 bcopy(ctx_template, &sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t)); 1073 } else { 1074 /* no context template, initialize context */ 1075 if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) { 1076 /* 1077 * Hash the passed-in key to get a smaller key. 1078 * The inner context is used since it hasn't been 1079 * initialized yet. 1080 */ 1081 PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx.hc_icontext, 1082 key->ck_data, keylen_in_bytes, digest); 1083 sha1_mac_init_ctx(&sha1_hmac_ctx, digest, 1084 SHA1_DIGEST_LENGTH); 1085 } else { 1086 sha1_mac_init_ctx(&sha1_hmac_ctx, key->ck_data, 1087 keylen_in_bytes); 1088 } 1089 } 1090 1091 /* get the mechanism parameters, if applicable */ 1092 if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) { 1093 if (mechanism->cm_param == NULL || 1094 mechanism->cm_param_len != sizeof (ulong_t)) { 1095 ret = CRYPTO_MECHANISM_PARAM_INVALID; 1096 goto bail; 1097 } 1098 PROV_SHA1_GET_DIGEST_LEN(mechanism, digest_len); 1099 if (digest_len > SHA1_DIGEST_LENGTH) { 1100 ret = CRYPTO_MECHANISM_PARAM_INVALID; 1101 goto bail; 1102 } 1103 } 1104 1105 /* do a SHA1 update of the inner context using the specified data */ 1106 SHA1_MAC_UPDATE(data, sha1_hmac_ctx, ret); 1107 if (ret != CRYPTO_SUCCESS) 1108 /* the update failed, free context and bail */ 1109 goto bail; 1110 1111 /* 1112 * Do a SHA1 final on the inner context. 1113 */ 1114 SHA1Final(digest, &sha1_hmac_ctx.hc_icontext); 1115 1116 /* 1117 * Do an SHA1 update on the outer context, feeding the inner 1118 * digest as data. 1119 */ 1120 SHA1Update(&sha1_hmac_ctx.hc_ocontext, digest, SHA1_DIGEST_LENGTH); 1121 1122 /* 1123 * Do a SHA1 final on the outer context, storing the computed 1124 * digest in the users buffer. 1125 */ 1126 switch (mac->cd_format) { 1127 case CRYPTO_DATA_RAW: 1128 if (digest_len != SHA1_DIGEST_LENGTH) { 1129 /* 1130 * The caller requested a short digest. Digest 1131 * into a scratch buffer and return to 1132 * the user only what was requested. 1133 */ 1134 SHA1Final(digest, &sha1_hmac_ctx.hc_ocontext); 1135 bcopy(digest, (unsigned char *)mac->cd_raw.iov_base + 1136 mac->cd_offset, digest_len); 1137 } else { 1138 SHA1Final((unsigned char *)mac->cd_raw.iov_base + 1139 mac->cd_offset, &sha1_hmac_ctx.hc_ocontext); 1140 } 1141 break; 1142 case CRYPTO_DATA_UIO: 1143 ret = sha1_digest_final_uio(&sha1_hmac_ctx.hc_ocontext, mac, 1144 digest_len, digest); 1145 break; 1146 case CRYPTO_DATA_MBLK: 1147 ret = sha1_digest_final_mblk(&sha1_hmac_ctx.hc_ocontext, mac, 1148 digest_len, digest); 1149 break; 1150 default: 1151 ret = CRYPTO_ARGUMENTS_BAD; 1152 } 1153 1154 if (ret == CRYPTO_SUCCESS) { 1155 mac->cd_length = digest_len; 1156 } else { 1157 mac->cd_length = 0; 1158 } 1159 /* Extra paranoia: zeroize the context on the stack */ 1160 bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t)); 1161 1162 return (ret); 1163 bail: 1164 bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t)); 1165 mac->cd_length = 0; 1166 return (ret); 1167 } 1168 1169 /* ARGSUSED */ 1170 static int 1171 sha1_mac_verify_atomic(crypto_provider_handle_t provider, 1172 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1173 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 1174 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 1175 { 1176 int ret = CRYPTO_SUCCESS; 1177 uchar_t digest[SHA1_DIGEST_LENGTH]; 1178 sha1_hmac_ctx_t sha1_hmac_ctx; 1179 uint32_t digest_len = SHA1_DIGEST_LENGTH; 1180 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 1181 1182 if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE && 1183 mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE) 1184 return (CRYPTO_MECHANISM_INVALID); 1185 1186 /* Add support for key by attributes (RFE 4706552) */ 1187 if (key->ck_format != CRYPTO_KEY_RAW) 1188 return (CRYPTO_ARGUMENTS_BAD); 1189 1190 if (ctx_template != NULL) { 1191 /* reuse context template */ 1192 bcopy(ctx_template, &sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t)); 1193 } else { 1194 /* no context template, initialize context */ 1195 if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) { 1196 /* 1197 * Hash the passed-in key to get a smaller key. 1198 * The inner context is used since it hasn't been 1199 * initialized yet. 1200 */ 1201 PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx.hc_icontext, 1202 key->ck_data, keylen_in_bytes, digest); 1203 sha1_mac_init_ctx(&sha1_hmac_ctx, digest, 1204 SHA1_DIGEST_LENGTH); 1205 } else { 1206 sha1_mac_init_ctx(&sha1_hmac_ctx, key->ck_data, 1207 keylen_in_bytes); 1208 } 1209 } 1210 1211 /* get the mechanism parameters, if applicable */ 1212 if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) { 1213 if (mechanism->cm_param == NULL || 1214 mechanism->cm_param_len != sizeof (ulong_t)) { 1215 ret = CRYPTO_MECHANISM_PARAM_INVALID; 1216 goto bail; 1217 } 1218 PROV_SHA1_GET_DIGEST_LEN(mechanism, digest_len); 1219 if (digest_len > SHA1_DIGEST_LENGTH) { 1220 ret = CRYPTO_MECHANISM_PARAM_INVALID; 1221 goto bail; 1222 } 1223 } 1224 1225 if (mac->cd_length != digest_len) { 1226 ret = CRYPTO_INVALID_MAC; 1227 goto bail; 1228 } 1229 1230 /* do a SHA1 update of the inner context using the specified data */ 1231 SHA1_MAC_UPDATE(data, sha1_hmac_ctx, ret); 1232 if (ret != CRYPTO_SUCCESS) 1233 /* the update failed, free context and bail */ 1234 goto bail; 1235 1236 /* do a SHA1 final on the inner context */ 1237 SHA1Final(digest, &sha1_hmac_ctx.hc_icontext); 1238 1239 /* 1240 * Do an SHA1 update on the outer context, feeding the inner 1241 * digest as data. 1242 */ 1243 SHA1Update(&sha1_hmac_ctx.hc_ocontext, digest, SHA1_DIGEST_LENGTH); 1244 1245 /* 1246 * Do a SHA1 final on the outer context, storing the computed 1247 * digest in the users buffer. 1248 */ 1249 SHA1Final(digest, &sha1_hmac_ctx.hc_ocontext); 1250 1251 /* 1252 * Compare the computed digest against the expected digest passed 1253 * as argument. 1254 */ 1255 1256 switch (mac->cd_format) { 1257 1258 case CRYPTO_DATA_RAW: 1259 if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base + 1260 mac->cd_offset, digest_len) != 0) 1261 ret = CRYPTO_INVALID_MAC; 1262 break; 1263 1264 case CRYPTO_DATA_UIO: { 1265 off_t offset = mac->cd_offset; 1266 uint_t vec_idx; 1267 off_t scratch_offset = 0; 1268 size_t length = digest_len; 1269 size_t cur_len; 1270 1271 /* we support only kernel buffer */ 1272 if (mac->cd_uio->uio_segflg != UIO_SYSSPACE) 1273 return (CRYPTO_ARGUMENTS_BAD); 1274 1275 /* jump to the first iovec containing the expected digest */ 1276 for (vec_idx = 0; 1277 offset >= mac->cd_uio->uio_iov[vec_idx].iov_len && 1278 vec_idx < mac->cd_uio->uio_iovcnt; 1279 offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len) 1280 ; 1281 if (vec_idx == mac->cd_uio->uio_iovcnt) { 1282 /* 1283 * The caller specified an offset that is 1284 * larger than the total size of the buffers 1285 * it provided. 1286 */ 1287 ret = CRYPTO_DATA_LEN_RANGE; 1288 break; 1289 } 1290 1291 /* do the comparison of computed digest vs specified one */ 1292 while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) { 1293 cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len - 1294 offset, length); 1295 1296 if (bcmp(digest + scratch_offset, 1297 mac->cd_uio->uio_iov[vec_idx].iov_base + offset, 1298 cur_len) != 0) { 1299 ret = CRYPTO_INVALID_MAC; 1300 break; 1301 } 1302 1303 length -= cur_len; 1304 vec_idx++; 1305 scratch_offset += cur_len; 1306 offset = 0; 1307 } 1308 break; 1309 } 1310 1311 case CRYPTO_DATA_MBLK: { 1312 off_t offset = mac->cd_offset; 1313 mblk_t *mp; 1314 off_t scratch_offset = 0; 1315 size_t length = digest_len; 1316 size_t cur_len; 1317 1318 /* jump to the first mblk_t containing the expected digest */ 1319 for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp); 1320 offset -= MBLKL(mp), mp = mp->b_cont) 1321 ; 1322 if (mp == NULL) { 1323 /* 1324 * The caller specified an offset that is larger than 1325 * the total size of the buffers it provided. 1326 */ 1327 ret = CRYPTO_DATA_LEN_RANGE; 1328 break; 1329 } 1330 1331 while (mp != NULL && length > 0) { 1332 cur_len = MIN(MBLKL(mp) - offset, length); 1333 if (bcmp(digest + scratch_offset, 1334 mp->b_rptr + offset, cur_len) != 0) { 1335 ret = CRYPTO_INVALID_MAC; 1336 break; 1337 } 1338 1339 length -= cur_len; 1340 mp = mp->b_cont; 1341 scratch_offset += cur_len; 1342 offset = 0; 1343 } 1344 break; 1345 } 1346 1347 default: 1348 ret = CRYPTO_ARGUMENTS_BAD; 1349 } 1350 1351 bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t)); 1352 return (ret); 1353 bail: 1354 bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t)); 1355 mac->cd_length = 0; 1356 return (ret); 1357 } 1358 1359 /* 1360 * KCF software provider context management entry points. 1361 */ 1362 1363 /* ARGSUSED */ 1364 static int 1365 sha1_create_ctx_template(crypto_provider_handle_t provider, 1366 crypto_mechanism_t *mechanism, crypto_key_t *key, 1367 crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size, 1368 crypto_req_handle_t req) 1369 { 1370 sha1_hmac_ctx_t *sha1_hmac_ctx_tmpl; 1371 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 1372 1373 if ((mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE) && 1374 (mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)) { 1375 return (CRYPTO_MECHANISM_INVALID); 1376 } 1377 1378 /* Add support for key by attributes (RFE 4706552) */ 1379 if (key->ck_format != CRYPTO_KEY_RAW) 1380 return (CRYPTO_ARGUMENTS_BAD); 1381 1382 /* 1383 * Allocate and initialize SHA1 context. 1384 */ 1385 sha1_hmac_ctx_tmpl = kmem_alloc(sizeof (sha1_hmac_ctx_t), 1386 crypto_kmflag(req)); 1387 if (sha1_hmac_ctx_tmpl == NULL) 1388 return (CRYPTO_HOST_MEMORY); 1389 1390 if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) { 1391 uchar_t digested_key[SHA1_DIGEST_LENGTH]; 1392 1393 /* 1394 * Hash the passed-in key to get a smaller key. 1395 * The inner context is used since it hasn't been 1396 * initialized yet. 1397 */ 1398 PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx_tmpl->hc_icontext, 1399 key->ck_data, keylen_in_bytes, digested_key); 1400 sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, digested_key, 1401 SHA1_DIGEST_LENGTH); 1402 } else { 1403 sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, key->ck_data, 1404 keylen_in_bytes); 1405 } 1406 1407 sha1_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type; 1408 *ctx_template = (crypto_spi_ctx_template_t)sha1_hmac_ctx_tmpl; 1409 *ctx_template_size = sizeof (sha1_hmac_ctx_t); 1410 1411 1412 return (CRYPTO_SUCCESS); 1413 } 1414 1415 static int 1416 sha1_free_context(crypto_ctx_t *ctx) 1417 { 1418 uint_t ctx_len; 1419 sha1_mech_type_t mech_type; 1420 1421 if (ctx->cc_provider_private == NULL) 1422 return (CRYPTO_SUCCESS); 1423 1424 /* 1425 * We have to free either SHA1 or SHA1-HMAC contexts, which 1426 * have different lengths. 1427 */ 1428 1429 mech_type = PROV_SHA1_CTX(ctx)->sc_mech_type; 1430 if (mech_type == SHA1_MECH_INFO_TYPE) 1431 ctx_len = sizeof (sha1_ctx_t); 1432 else { 1433 ASSERT(mech_type == SHA1_HMAC_MECH_INFO_TYPE || 1434 mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE); 1435 ctx_len = sizeof (sha1_hmac_ctx_t); 1436 } 1437 1438 bzero(ctx->cc_provider_private, ctx_len); 1439 kmem_free(ctx->cc_provider_private, ctx_len); 1440 ctx->cc_provider_private = NULL; 1441 1442 return (CRYPTO_SUCCESS); 1443 } 1444