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