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 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <errno.h> 30 #include <security/cryptoki.h> 31 #include <sys/crypto/ioctl.h> 32 #include "kernelGlobal.h" 33 #include "kernelObject.h" 34 #include "kernelSession.h" 35 #include "kernelEmulate.h" 36 37 CK_RV 38 C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 39 CK_OBJECT_HANDLE hKey) 40 { 41 CK_RV rv; 42 kernel_session_t *session_p; 43 kernel_object_t *key_p; 44 boolean_t ses_lock_held = B_FALSE; 45 crypto_sign_init_t sign_init; 46 crypto_mech_type_t k_mech_type; 47 int r; 48 49 if (!kernel_initialized) 50 return (CKR_CRYPTOKI_NOT_INITIALIZED); 51 52 if (pMechanism == NULL) { 53 return (CKR_ARGUMENTS_BAD); 54 } 55 56 /* Get the kernel's internal mechanism number. */ 57 rv = kernel_mech(pMechanism->mechanism, &k_mech_type); 58 if (rv != CKR_OK) { 59 return (rv); 60 } 61 62 /* Obtain the session pointer. */ 63 rv = handle2session(hSession, &session_p); 64 if (rv != CKR_OK) 65 return (rv); 66 67 /* Obtain the object pointer. */ 68 HANDLE2OBJECT(hKey, key_p, rv); 69 if (rv != CKR_OK) { 70 REFRELE(session_p, ses_lock_held); 71 return (rv); 72 } 73 74 /* Check to see if key object supports signature. */ 75 if (key_p->is_lib_obj && !(key_p->bool_attr_mask & SIGN_BOOL_ON)) { 76 rv = CKR_KEY_TYPE_INCONSISTENT; 77 goto clean_exit; 78 } 79 80 (void) pthread_mutex_lock(&session_p->session_mutex); 81 ses_lock_held = B_TRUE; 82 83 /* 84 * This active flag will remain ON until application calls either 85 * C_Sign or C_SignFinal to actually obtain the signature. 86 */ 87 session_p->sign.flags = CRYPTO_OPERATION_ACTIVE; 88 sign_init.si_session = session_p->k_session; 89 (void) pthread_mutex_unlock(&session_p->session_mutex); 90 ses_lock_held = B_FALSE; 91 92 if (!key_p->is_lib_obj) { 93 sign_init.si_key.ck_format = CRYPTO_KEY_REFERENCE; 94 sign_init.si_key.ck_obj_id = key_p->k_handle; 95 } else { 96 if (key_p->class == CKO_SECRET_KEY) { 97 sign_init.si_key.ck_format = CRYPTO_KEY_RAW; 98 sign_init.si_key.ck_data = 99 get_symmetric_key_value(key_p); 100 if (sign_init.si_key.ck_data == NULL) { 101 rv = CKR_HOST_MEMORY; 102 goto clean_exit; 103 } 104 sign_init.si_key.ck_length = 105 OBJ_SEC(key_p)->sk_value_len << 3; 106 107 } else if (key_p->key_type == CKK_RSA) { 108 rv = get_rsa_private_key(key_p, &sign_init.si_key); 109 if (rv != CKR_OK) { 110 goto clean_exit; 111 } 112 } else if (key_p->key_type == CKK_DSA) { 113 rv = get_dsa_private_key(key_p, &sign_init.si_key); 114 if (rv != CKR_OK) { 115 goto clean_exit; 116 } 117 } else if (key_p->key_type == CKK_EC) { 118 rv = get_ec_private_key(key_p, &sign_init.si_key); 119 if (rv != CKR_OK) { 120 goto clean_exit; 121 } 122 } else { 123 rv = CKR_KEY_TYPE_INCONSISTENT; 124 goto clean_exit; 125 } 126 } 127 128 sign_init.si_mech.cm_type = k_mech_type; 129 sign_init.si_mech.cm_param = pMechanism->pParameter; 130 sign_init.si_mech.cm_param_len = pMechanism->ulParameterLen; 131 132 while ((r = ioctl(kernel_fd, CRYPTO_SIGN_INIT, &sign_init)) < 0) { 133 if (errno != EINTR) 134 break; 135 } 136 if (r < 0) { 137 rv = CKR_FUNCTION_FAILED; 138 } else { 139 rv = crypto2pkcs11_error_number(sign_init.si_return_value); 140 } 141 142 if (rv == CKR_OK && SLOT_HAS_LIMITED_HASH(session_p) && 143 is_hmac(pMechanism->mechanism)) { 144 if (key_p->is_lib_obj && key_p->class == CKO_SECRET_KEY) { 145 (void) pthread_mutex_lock(&session_p->session_mutex); 146 session_p->sign.flags |= CRYPTO_EMULATE; 147 (void) pthread_mutex_unlock(&session_p->session_mutex); 148 rv = emulate_init(session_p, pMechanism, 149 &(sign_init.si_key), OP_SIGN); 150 } else { 151 rv = CKR_ARGUMENTS_BAD; 152 } 153 } 154 155 if (key_p->is_lib_obj) { 156 if (key_p->class == CKO_SECRET_KEY) { 157 free(sign_init.si_key.ck_data); 158 } else { 159 free_key_attributes(&sign_init.si_key); 160 } 161 } 162 163 if (rv != CKR_OK) { 164 (void) pthread_mutex_lock(&session_p->session_mutex); 165 session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE; 166 ses_lock_held = B_TRUE; 167 } 168 169 clean_exit: 170 OBJ_REFRELE(key_p); 171 REFRELE(session_p, ses_lock_held); 172 return (rv); 173 } 174 175 176 CK_RV 177 C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, 178 CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) 179 { 180 181 CK_RV rv; 182 kernel_session_t *session_p; 183 boolean_t ses_lock_held = B_FALSE; 184 crypto_sign_t sign; 185 int r; 186 187 if (!kernel_initialized) 188 return (CKR_CRYPTOKI_NOT_INITIALIZED); 189 190 /* Obtain the session pointer */ 191 rv = handle2session(hSession, &session_p); 192 if (rv != CKR_OK) 193 return (rv); 194 195 if (pulSignatureLen == NULL) { 196 rv = CKR_ARGUMENTS_BAD; 197 goto clean_exit; 198 } 199 200 (void) pthread_mutex_lock(&session_p->session_mutex); 201 ses_lock_held = B_TRUE; 202 203 /* Application must call C_SignInit before calling C_Sign. */ 204 if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 205 REFRELE(session_p, ses_lock_held); 206 return (CKR_OPERATION_NOT_INITIALIZED); 207 } 208 209 /* 210 * C_Sign must be called without intervening C_SignUpdate 211 * calls. 212 */ 213 if (session_p->sign.flags & CRYPTO_OPERATION_UPDATE) { 214 /* 215 * C_Sign can not be used to terminate a multi-part 216 * operation, so we'll leave the active sign operation 217 * flag on and let the application continue with the 218 * sign update operation. 219 */ 220 REFRELE(session_p, ses_lock_held); 221 return (CKR_FUNCTION_FAILED); 222 } 223 224 if (session_p->sign.flags & CRYPTO_EMULATE) { 225 if ((ulDataLen < SLOT_THRESHOLD(session_p)) || 226 (ulDataLen > SLOT_MAX_INDATA_LEN(session_p))) { 227 session_p->sign.flags |= CRYPTO_EMULATE_USING_SW; 228 (void) pthread_mutex_unlock(&session_p->session_mutex); 229 230 rv = do_soft_hmac_sign(get_spp(&session_p->sign), 231 pData, ulDataLen, 232 pSignature, pulSignatureLen, OP_SINGLE); 233 goto done; 234 } else { 235 free_soft_ctx(get_sp(&session_p->sign), OP_SIGN); 236 } 237 } 238 239 sign.cs_session = session_p->k_session; 240 (void) pthread_mutex_unlock(&session_p->session_mutex); 241 ses_lock_held = B_FALSE; 242 243 sign.cs_datalen = ulDataLen; 244 sign.cs_databuf = (char *)pData; 245 sign.cs_signlen = *pulSignatureLen; 246 sign.cs_signbuf = (char *)pSignature; 247 248 while ((r = ioctl(kernel_fd, CRYPTO_SIGN, &sign)) < 0) { 249 if (errno != EINTR) 250 break; 251 } 252 if (r < 0) { 253 rv = CKR_FUNCTION_FAILED; 254 } else { 255 rv = crypto2pkcs11_error_number(sign.cs_return_value); 256 } 257 258 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL) 259 *pulSignatureLen = sign.cs_signlen; 260 261 done: 262 if ((rv == CKR_BUFFER_TOO_SMALL) || 263 (rv == CKR_OK && pSignature == NULL)) { 264 /* 265 * We will not terminate the active sign operation flag, 266 * when the application-supplied buffer is too small, or 267 * the application asks for the length of buffer to hold 268 * the signature. 269 */ 270 REFRELE(session_p, ses_lock_held); 271 return (rv); 272 } 273 274 clean_exit: 275 /* 276 * Terminates the active sign operation. 277 * Application needs to call C_SignInit again for next 278 * sign operation. 279 */ 280 (void) pthread_mutex_lock(&session_p->session_mutex); 281 282 REINIT_OPBUF(&session_p->sign); 283 session_p->sign.flags = 0; 284 ses_lock_held = B_TRUE; 285 REFRELE(session_p, ses_lock_held); 286 287 return (rv); 288 } 289 290 291 CK_RV 292 C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 293 CK_ULONG ulPartLen) 294 { 295 296 CK_RV rv; 297 kernel_session_t *session_p; 298 boolean_t ses_lock_held = B_FALSE; 299 crypto_sign_update_t sign_update; 300 int r; 301 302 if (!kernel_initialized) 303 return (CKR_CRYPTOKI_NOT_INITIALIZED); 304 305 /* Obtain the session pointer */ 306 rv = handle2session(hSession, &session_p); 307 if (rv != CKR_OK) 308 return (rv); 309 310 if (pPart == NULL) { 311 rv = CKR_ARGUMENTS_BAD; 312 goto clean_exit; 313 } 314 315 (void) pthread_mutex_lock(&session_p->session_mutex); 316 ses_lock_held = B_TRUE; 317 318 /* 319 * Application must call C_SignInit before calling 320 * C_SignUpdate. 321 */ 322 if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 323 REFRELE(session_p, ses_lock_held); 324 return (CKR_OPERATION_NOT_INITIALIZED); 325 } 326 327 session_p->sign.flags |= CRYPTO_OPERATION_UPDATE; 328 329 if (session_p->sign.flags & CRYPTO_EMULATE) { 330 (void) pthread_mutex_unlock(&session_p->session_mutex); 331 rv = emulate_update(session_p, pPart, ulPartLen, OP_SIGN); 332 goto done; 333 } 334 335 sign_update.su_session = session_p->k_session; 336 (void) pthread_mutex_unlock(&session_p->session_mutex); 337 ses_lock_held = B_FALSE; 338 339 sign_update.su_datalen = ulPartLen; 340 sign_update.su_databuf = (char *)pPart; 341 342 while ((r = ioctl(kernel_fd, CRYPTO_SIGN_UPDATE, &sign_update)) < 0) { 343 if (errno != EINTR) 344 break; 345 } 346 if (r < 0) { 347 rv = CKR_FUNCTION_FAILED; 348 } else { 349 rv = crypto2pkcs11_error_number(sign_update.su_return_value); 350 } 351 352 done: 353 if (rv == CKR_OK) { 354 REFRELE(session_p, ses_lock_held); 355 return (rv); 356 } 357 358 clean_exit: 359 /* 360 * After an error occurred, terminate the current sign 361 * operation by resetting the active and update flags. 362 */ 363 (void) pthread_mutex_lock(&session_p->session_mutex); 364 REINIT_OPBUF(&session_p->sign); 365 session_p->sign.flags = 0; 366 ses_lock_held = B_TRUE; 367 REFRELE(session_p, ses_lock_held); 368 369 return (rv); 370 } 371 372 373 CK_RV 374 C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, 375 CK_ULONG_PTR pulSignatureLen) 376 { 377 378 CK_RV rv; 379 kernel_session_t *session_p; 380 boolean_t ses_lock_held = B_FALSE; 381 crypto_sign_final_t sign_final; 382 int r; 383 384 if (!kernel_initialized) 385 return (CKR_CRYPTOKI_NOT_INITIALIZED); 386 387 /* Obtain the session pointer */ 388 rv = handle2session(hSession, &session_p); 389 if (rv != CKR_OK) 390 return (rv); 391 392 if (pulSignatureLen == NULL) { 393 rv = CKR_ARGUMENTS_BAD; 394 goto clean_exit; 395 } 396 397 (void) pthread_mutex_lock(&session_p->session_mutex); 398 ses_lock_held = B_TRUE; 399 400 /* 401 * Application must call C_SignInit before calling 402 * C_SignFinal. 403 */ 404 if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 405 REFRELE(session_p, ses_lock_held); 406 return (CKR_OPERATION_NOT_INITIALIZED); 407 } 408 409 /* The order of checks is important here */ 410 if (session_p->sign.flags & CRYPTO_EMULATE_USING_SW) { 411 if (session_p->sign.flags & CRYPTO_EMULATE_UPDATE_DONE) { 412 (void) pthread_mutex_unlock(&session_p->session_mutex); 413 rv = do_soft_hmac_sign(get_spp(&session_p->sign), 414 NULL, 0, pSignature, pulSignatureLen, OP_FINAL); 415 } else { 416 /* 417 * We end up here if an earlier C_SignFinal() call 418 * took the C_Sign() path and it had returned 419 * CKR_BUFFER_TOO_SMALL. 420 */ 421 digest_buf_t *bufp = session_p->sign.context; 422 (void) pthread_mutex_unlock(&session_p->session_mutex); 423 if (bufp == NULL || bufp->buf == NULL) { 424 rv = CKR_ARGUMENTS_BAD; 425 goto clean_exit; 426 } 427 rv = do_soft_hmac_sign(get_spp(&session_p->sign), 428 bufp->buf, bufp->indata_len, 429 pSignature, pulSignatureLen, OP_SINGLE); 430 } 431 goto done; 432 } else if (session_p->sign.flags & CRYPTO_EMULATE) { 433 digest_buf_t *bufp = session_p->sign.context; 434 435 /* 436 * We are emulating a single-part operation now. 437 * So, clear the flag. 438 */ 439 session_p->sign.flags &= ~CRYPTO_OPERATION_UPDATE; 440 if (bufp == NULL || bufp->buf == NULL) { 441 rv = CKR_ARGUMENTS_BAD; 442 goto clean_exit; 443 } 444 REFRELE(session_p, ses_lock_held); 445 rv = C_Sign(hSession, bufp->buf, bufp->indata_len, 446 pSignature, pulSignatureLen); 447 return (rv); 448 } 449 450 sign_final.sf_session = session_p->k_session; 451 (void) pthread_mutex_unlock(&session_p->session_mutex); 452 ses_lock_held = B_FALSE; 453 454 sign_final.sf_signlen = *pulSignatureLen; 455 sign_final.sf_signbuf = (char *)pSignature; 456 457 while ((r = ioctl(kernel_fd, CRYPTO_SIGN_FINAL, &sign_final)) < 0) { 458 if (errno != EINTR) 459 break; 460 } 461 if (r < 0) { 462 rv = CKR_FUNCTION_FAILED; 463 } else { 464 rv = crypto2pkcs11_error_number(sign_final.sf_return_value); 465 } 466 467 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL) 468 *pulSignatureLen = sign_final.sf_signlen; 469 470 done: 471 if ((rv == CKR_BUFFER_TOO_SMALL) || 472 (rv == CKR_OK && pSignature == NULL)) { 473 /* 474 * We will not terminate the active sign operation flag, 475 * when the application-supplied buffer is too small, or 476 * the application asks for the length of buffer to hold 477 * the signature. 478 */ 479 REFRELE(session_p, ses_lock_held); 480 return (rv); 481 } 482 483 clean_exit: 484 /* Terminates the active sign operation */ 485 (void) pthread_mutex_lock(&session_p->session_mutex); 486 REINIT_OPBUF(&session_p->sign); 487 session_p->sign.flags = 0; 488 ses_lock_held = B_TRUE; 489 REFRELE(session_p, ses_lock_held); 490 491 return (rv); 492 } 493 494 495 CK_RV 496 C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 497 CK_OBJECT_HANDLE hKey) 498 { 499 500 CK_RV rv; 501 kernel_session_t *session_p; 502 kernel_object_t *key_p; 503 boolean_t ses_lock_held = B_FALSE; 504 crypto_sign_recover_init_t sr_init; 505 crypto_mech_type_t k_mech_type; 506 int r; 507 508 if (!kernel_initialized) 509 return (CKR_CRYPTOKI_NOT_INITIALIZED); 510 511 if (pMechanism == NULL) { 512 return (CKR_ARGUMENTS_BAD); 513 } 514 515 /* Get the kernel's internal mechanism number. */ 516 rv = kernel_mech(pMechanism->mechanism, &k_mech_type); 517 if (rv != CKR_OK) 518 return (rv); 519 520 /* Obtain the session pointer. */ 521 rv = handle2session(hSession, &session_p); 522 if (rv != CKR_OK) 523 return (rv); 524 525 /* Obtain the object pointer. */ 526 HANDLE2OBJECT(hKey, key_p, rv); 527 if (rv != CKR_OK) { 528 REFRELE(session_p, ses_lock_held); 529 return (rv); 530 } 531 532 /* 533 * Check to see if key object is a RSA key and if it supports 534 * sign_recover. 535 */ 536 if (key_p->is_lib_obj && !((key_p->key_type == CKK_RSA) && 537 (key_p->bool_attr_mask & SIGN_RECOVER_BOOL_ON))) { 538 rv = CKR_KEY_TYPE_INCONSISTENT; 539 goto clean_exit; 540 } 541 542 (void) pthread_mutex_lock(&session_p->session_mutex); 543 ses_lock_held = B_TRUE; 544 545 /* 546 * This active flag will remain ON until application calls 547 * C_SignRecover to actually obtain the signature. 548 */ 549 session_p->sign.flags = CRYPTO_OPERATION_ACTIVE; 550 551 /* Set up the key data */ 552 if (!key_p->is_lib_obj) { 553 sr_init.ri_key.ck_format = CRYPTO_KEY_REFERENCE; 554 sr_init.ri_key.ck_obj_id = key_p->k_handle; 555 } else { 556 if (key_p->key_type == CKK_RSA) { 557 if (get_rsa_private_key(key_p, &sr_init.ri_key) != 558 CKR_OK) { 559 rv = CKR_HOST_MEMORY; 560 goto clean_exit; 561 } 562 } else { 563 rv = CKR_KEY_TYPE_INCONSISTENT; 564 goto clean_exit; 565 } 566 } 567 568 sr_init.ri_session = session_p->k_session; 569 (void) pthread_mutex_unlock(&session_p->session_mutex); 570 ses_lock_held = B_FALSE; 571 sr_init.ri_mech.cm_type = k_mech_type; 572 sr_init.ri_mech.cm_param = pMechanism->pParameter; 573 sr_init.ri_mech.cm_param_len = pMechanism->ulParameterLen; 574 575 while ((r = ioctl(kernel_fd, CRYPTO_SIGN_RECOVER_INIT, &sr_init)) < 0) { 576 if (errno != EINTR) 577 break; 578 } 579 if (r < 0) { 580 rv = CKR_FUNCTION_FAILED; 581 } else { 582 rv = crypto2pkcs11_error_number(sr_init.ri_return_value); 583 } 584 585 if (key_p->is_lib_obj) { 586 free_key_attributes(&sr_init.ri_key); 587 } 588 589 if (rv != CKR_OK) { 590 (void) pthread_mutex_lock(&session_p->session_mutex); 591 session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE; 592 ses_lock_held = B_TRUE; 593 } 594 595 clean_exit: 596 OBJ_REFRELE(key_p); 597 REFRELE(session_p, ses_lock_held); 598 return (rv); 599 } 600 601 602 CK_RV 603 C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 604 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) 605 { 606 607 CK_RV rv; 608 kernel_session_t *session_p; 609 boolean_t ses_lock_held = B_FALSE; 610 crypto_sign_recover_t sign_recover; 611 int r; 612 613 if (!kernel_initialized) 614 return (CKR_CRYPTOKI_NOT_INITIALIZED); 615 616 /* Obatin the session pointer */ 617 rv = handle2session(hSession, &session_p); 618 if (rv != CKR_OK) 619 return (rv); 620 621 if (pulSignatureLen == NULL) { 622 rv = CKR_ARGUMENTS_BAD; 623 goto clean_exit; 624 } 625 626 (void) pthread_mutex_lock(&session_p->session_mutex); 627 ses_lock_held = B_TRUE; 628 629 /* Application must call C_SignInit before calling C_Sign. */ 630 if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 631 REFRELE(session_p, ses_lock_held); 632 return (CKR_OPERATION_NOT_INITIALIZED); 633 } 634 635 sign_recover.sr_session = session_p->k_session; 636 (void) pthread_mutex_unlock(&session_p->session_mutex); 637 ses_lock_held = B_FALSE; 638 639 sign_recover.sr_datalen = ulDataLen; 640 sign_recover.sr_databuf = (char *)pData; 641 sign_recover.sr_signlen = *pulSignatureLen; 642 sign_recover.sr_signbuf = (char *)pSignature; 643 644 while ((r = ioctl(kernel_fd, CRYPTO_SIGN_RECOVER, &sign_recover)) < 0) { 645 if (errno != EINTR) 646 break; 647 } 648 if (r < 0) { 649 rv = CKR_FUNCTION_FAILED; 650 } else { 651 rv = crypto2pkcs11_error_number(sign_recover.sr_return_value); 652 } 653 654 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL) 655 *pulSignatureLen = sign_recover.sr_signlen; 656 657 if ((rv == CKR_BUFFER_TOO_SMALL) || 658 (rv == CKR_OK && pSignature == NULL)) { 659 /* 660 * We will not terminate the active sign operation flag, 661 * when the application-supplied buffer is too small, or 662 * the application asks for the length of buffer to hold 663 * the signature. 664 */ 665 REFRELE(session_p, ses_lock_held); 666 return (rv); 667 } 668 669 clean_exit: 670 /* 671 * Terminates the active sign operation. 672 * Application needs to call C_SignInit again for next 673 * sign operation. 674 */ 675 (void) pthread_mutex_lock(&session_p->session_mutex); 676 session_p->sign.flags = 0; 677 ses_lock_held = B_TRUE; 678 REFRELE(session_p, ses_lock_held); 679 680 return (rv); 681 } 682