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