17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5ba5f469cSkrishna * Common Development and Distribution License (the "License"). 6ba5f469cSkrishna * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21ba5f469cSkrishna 227c478bd9Sstevel@tonic-gate /* 23b232b5fcSZdenek Kotala * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <pthread.h> 287c478bd9Sstevel@tonic-gate #include <errno.h> 297c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctl.h> 307c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 317c478bd9Sstevel@tonic-gate #include "kernelGlobal.h" 327c478bd9Sstevel@tonic-gate #include "kernelSession.h" 33ba5f469cSkrishna #include "kernelEmulate.h" 347c478bd9Sstevel@tonic-gate 35b2a96221Skrishna static CK_RV 36b2a96221Skrishna common_digest_init(CK_SESSION_HANDLE hSession, 37b2a96221Skrishna CK_MECHANISM_PTR pMechanism, boolean_t is_external_caller) 387c478bd9Sstevel@tonic-gate { 397c478bd9Sstevel@tonic-gate CK_RV rv; 407c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 41b232b5fcSZdenek Kotala boolean_t ses_lock_held = B_FALSE; 427c478bd9Sstevel@tonic-gate crypto_digest_init_t digest_init; 437c478bd9Sstevel@tonic-gate crypto_mech_type_t k_mech_type; 447c478bd9Sstevel@tonic-gate int r; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate if (!kernel_initialized) 477c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate if (pMechanism == NULL) 507c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* 537c478bd9Sstevel@tonic-gate * Get the kernel's internal mechanism number. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate rv = kernel_mech(pMechanism->mechanism, &k_mech_type); 567c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 577c478bd9Sstevel@tonic-gate return (rv); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate /* 607c478bd9Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session 617c478bd9Sstevel@tonic-gate * reference count. 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 647c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 657c478bd9Sstevel@tonic-gate return (rv); 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* Acquire the session lock */ 687c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 69b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate /* 727c478bd9Sstevel@tonic-gate * This active flag will remain ON until application calls either 737c478bd9Sstevel@tonic-gate * C_Digest or C_DigestFinal to actually obtain the value of 747c478bd9Sstevel@tonic-gate * the message digest. 757c478bd9Sstevel@tonic-gate */ 76b2a96221Skrishna session_p->digest.flags |= CRYPTO_OPERATION_ACTIVE; 77b2a96221Skrishna 78b2a96221Skrishna if (SLOT_HAS_LIMITED_HASH(session_p) && is_external_caller) { 79b2a96221Skrishna session_p->digest.mech.mechanism = pMechanism->mechanism; 80b2a96221Skrishna session_p->digest.mech.pParameter = NULL; 81b2a96221Skrishna session_p->digest.mech.ulParameterLen = 0; 82b2a96221Skrishna session_p->digest.flags |= CRYPTO_EMULATE; 83b2a96221Skrishna rv = emulate_buf_init(session_p, EDIGEST_LENGTH, OP_DIGEST); 84b2a96221Skrishna REFRELE(session_p, ses_lock_held); 85b2a96221Skrishna return (rv); 86b2a96221Skrishna } 87b2a96221Skrishna 887c478bd9Sstevel@tonic-gate digest_init.di_session = session_p->k_session; 897c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 90b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 917c478bd9Sstevel@tonic-gate digest_init.di_mech.cm_type = k_mech_type; 927c478bd9Sstevel@tonic-gate digest_init.di_mech.cm_param = pMechanism->pParameter; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate * If pParameter is NULL, set cm_param_len to be 0, so that ioctl call 967c478bd9Sstevel@tonic-gate * will have a clean input data. 977c478bd9Sstevel@tonic-gate */ 987c478bd9Sstevel@tonic-gate if (pMechanism->pParameter != NULL) 997c478bd9Sstevel@tonic-gate digest_init.di_mech.cm_param_len = pMechanism->ulParameterLen; 1007c478bd9Sstevel@tonic-gate else 1017c478bd9Sstevel@tonic-gate digest_init.di_mech.cm_param_len = 0; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_DIGEST_INIT, &digest_init)) < 0) { 1047c478bd9Sstevel@tonic-gate if (errno != EINTR) 1057c478bd9Sstevel@tonic-gate break; 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate if (r < 0) { 1087c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 1097c478bd9Sstevel@tonic-gate } else { 1107c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(digest_init.di_return_value); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1147c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 115b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 1167c478bd9Sstevel@tonic-gate session_p->digest.flags &= ~CRYPTO_OPERATION_ACTIVE; 1177c478bd9Sstevel@tonic-gate /* 1187c478bd9Sstevel@tonic-gate * Decrement the session reference count. 1197c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 1207c478bd9Sstevel@tonic-gate * will release the session lock for us. 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 1237c478bd9Sstevel@tonic-gate return (rv); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate /* 1277c478bd9Sstevel@tonic-gate * Decrement the session reference count. 1287c478bd9Sstevel@tonic-gate * We do not hold the session lock. 1297c478bd9Sstevel@tonic-gate */ 1307c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 1317c478bd9Sstevel@tonic-gate return (rv); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate CK_RV 135b2a96221Skrishna C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) 136b2a96221Skrishna { 137b2a96221Skrishna return (common_digest_init(hSession, pMechanism, B_TRUE)); 138b2a96221Skrishna } 139b2a96221Skrishna 140b2a96221Skrishna CK_RV 1417c478bd9Sstevel@tonic-gate C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, 1427c478bd9Sstevel@tonic-gate CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate CK_RV rv; 1457c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 146b232b5fcSZdenek Kotala boolean_t ses_lock_held = B_FALSE; 1477c478bd9Sstevel@tonic-gate crypto_digest_t digest; 1487c478bd9Sstevel@tonic-gate int r; 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate if (!kernel_initialized) 1517c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate /* 1547c478bd9Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session 1557c478bd9Sstevel@tonic-gate * reference count. 1567c478bd9Sstevel@tonic-gate */ 1577c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 1587c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1597c478bd9Sstevel@tonic-gate return (rv); 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate if (pData == NULL || pulDigestLen == NULL) { 1627c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 1637c478bd9Sstevel@tonic-gate goto clean_exit; 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* Acquire the session lock */ 1677c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 168b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* Application must call C_DigestInit before calling C_Digest */ 1717c478bd9Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) { 1727c478bd9Sstevel@tonic-gate /* 1737c478bd9Sstevel@tonic-gate * Decrement the session reference count. 1747c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 1757c478bd9Sstevel@tonic-gate * will release the session lock for us. 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 1787c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* 1827c478bd9Sstevel@tonic-gate * C_Digest must be called without intervening C_DigestUpdate 1837c478bd9Sstevel@tonic-gate * calls. 1847c478bd9Sstevel@tonic-gate */ 1857c478bd9Sstevel@tonic-gate if (session_p->digest.flags & CRYPTO_OPERATION_UPDATE) { 1867c478bd9Sstevel@tonic-gate /* 1877c478bd9Sstevel@tonic-gate * C_Digest can not be used to terminate a multi-part 1887c478bd9Sstevel@tonic-gate * operation, so we'll leave the active digest operation 1897c478bd9Sstevel@tonic-gate * flag on and let the application continue with the 1907c478bd9Sstevel@tonic-gate * digest update operation. 1917c478bd9Sstevel@tonic-gate * 1927c478bd9Sstevel@tonic-gate * Decrement the session reference count. 1937c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 1947c478bd9Sstevel@tonic-gate * will release the session lock for us. 1957c478bd9Sstevel@tonic-gate */ 1967c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 1977c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 200ba5f469cSkrishna if (session_p->digest.flags & CRYPTO_EMULATE) { 201b2a96221Skrishna crypto_active_op_t *opp; 202b2a96221Skrishna CK_MECHANISM_PTR pMechanism; 203b2a96221Skrishna 204b2a96221Skrishna opp = &(session_p->digest); 205b232b5fcSZdenek Kotala if (opp->context == NULL) { 206b232b5fcSZdenek Kotala REFRELE(session_p, ses_lock_held); 207b2a96221Skrishna return (CKR_ARGUMENTS_BAD); 208b232b5fcSZdenek Kotala } 209b2a96221Skrishna pMechanism = &(opp->mech); 210b2a96221Skrishna 211ba5f469cSkrishna if ((ulDataLen < SLOT_THRESHOLD(session_p)) || 212*4df55fdeSJanie Lu (ulDataLen > SLOT_HASH_MAX_INDATA_LEN(session_p))) { 213ba5f469cSkrishna session_p->digest.flags |= CRYPTO_EMULATE_USING_SW; 214ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 215b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 216ba5f469cSkrishna 217b2a96221Skrishna rv = do_soft_digest(get_spp(opp), pMechanism, 218b2a96221Skrishna pData, ulDataLen, pDigest, pulDigestLen, 219b2a96221Skrishna OP_INIT | OP_SINGLE); 220ba5f469cSkrishna goto done; 221b2a96221Skrishna } else if (!(session_p->digest.flags & 222b2a96221Skrishna CRYPTO_EMULATE_INIT_DONE)) { 223b2a96221Skrishna session_p->digest.flags |= CRYPTO_EMULATE_INIT_DONE; 224b2a96221Skrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 225b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 226b232b5fcSZdenek Kotala 227b2a96221Skrishna rv = common_digest_init(hSession, pMechanism, B_FALSE); 228b2a96221Skrishna if (rv != CKR_OK) 229b2a96221Skrishna goto clean_exit; 230b2a96221Skrishna (void) pthread_mutex_lock(&session_p->session_mutex); 231b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 232ba5f469cSkrishna } 233ba5f469cSkrishna } 234ba5f469cSkrishna 2357c478bd9Sstevel@tonic-gate digest.cd_session = session_p->k_session; 2367c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 237b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 2387c478bd9Sstevel@tonic-gate digest.cd_datalen = ulDataLen; 2397c478bd9Sstevel@tonic-gate digest.cd_databuf = (char *)pData; 2407c478bd9Sstevel@tonic-gate digest.cd_digestbuf = (char *)pDigest; 2417c478bd9Sstevel@tonic-gate digest.cd_digestlen = *pulDigestLen; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_DIGEST, &digest)) < 0) { 2447c478bd9Sstevel@tonic-gate if (errno != EINTR) 2457c478bd9Sstevel@tonic-gate break; 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate if (r < 0) { 2487c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 2497c478bd9Sstevel@tonic-gate } else { 2507c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(digest.cd_return_value); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate if ((rv == CKR_OK) || (rv == CKR_BUFFER_TOO_SMALL)) 2547c478bd9Sstevel@tonic-gate *pulDigestLen = digest.cd_digestlen; 2557c478bd9Sstevel@tonic-gate 256ba5f469cSkrishna done: 2577c478bd9Sstevel@tonic-gate if ((rv == CKR_BUFFER_TOO_SMALL) || 2587c478bd9Sstevel@tonic-gate (rv == CKR_OK && pDigest == NULL)) { 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * We will not terminate the active digest operation flag, 2617c478bd9Sstevel@tonic-gate * when the application-supplied buffer is too small, or 2627c478bd9Sstevel@tonic-gate * the application asks for the length of buffer to hold 2637c478bd9Sstevel@tonic-gate * the message digest. 2647c478bd9Sstevel@tonic-gate * 2657c478bd9Sstevel@tonic-gate * Decrement the session reference count. 2667c478bd9Sstevel@tonic-gate * We do not hold the session lock. 2677c478bd9Sstevel@tonic-gate */ 2687c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 2697c478bd9Sstevel@tonic-gate return (rv); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate clean_exit: 2737c478bd9Sstevel@tonic-gate /* 2747c478bd9Sstevel@tonic-gate * Terminates the active digest operation. 2757c478bd9Sstevel@tonic-gate * Application needs to call C_DigestInit again for next 2767c478bd9Sstevel@tonic-gate * digest operation. 2777c478bd9Sstevel@tonic-gate */ 2787c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 279b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 280ba5f469cSkrishna 281ba5f469cSkrishna REINIT_OPBUF(&session_p->digest); 2827c478bd9Sstevel@tonic-gate session_p->digest.flags = 0; 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate /* 2857c478bd9Sstevel@tonic-gate * Decrement the session reference count. 2867c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 2877c478bd9Sstevel@tonic-gate * will release the session lock for us. 2887c478bd9Sstevel@tonic-gate */ 2897c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate return (rv); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate CK_RV 2957c478bd9Sstevel@tonic-gate C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 2967c478bd9Sstevel@tonic-gate CK_ULONG ulPartLen) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate CK_RV rv; 3007c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 301b232b5fcSZdenek Kotala boolean_t ses_lock_held = B_FALSE; 3027c478bd9Sstevel@tonic-gate crypto_digest_update_t digest_update; 3037c478bd9Sstevel@tonic-gate int r; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate if (!kernel_initialized) 3067c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* 3097c478bd9Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session 3107c478bd9Sstevel@tonic-gate * reference count. 3117c478bd9Sstevel@tonic-gate */ 3127c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 3137c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 3147c478bd9Sstevel@tonic-gate return (rv); 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate if (pPart == NULL) { 3177c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 3187c478bd9Sstevel@tonic-gate goto clean_exit; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate /* Acquire the session lock */ 3227c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 323b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* 3267c478bd9Sstevel@tonic-gate * Application must call C_DigestInit before calling 3277c478bd9Sstevel@tonic-gate * C_DigestUpdate. 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) { 3307c478bd9Sstevel@tonic-gate /* 3317c478bd9Sstevel@tonic-gate * Decrement the session reference count. 3327c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 3337c478bd9Sstevel@tonic-gate * will release the session lock for us. 3347c478bd9Sstevel@tonic-gate */ 3357c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 3367c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate /* Set update flag to protect C_Digest */ 3407c478bd9Sstevel@tonic-gate session_p->digest.flags |= CRYPTO_OPERATION_UPDATE; 3417c478bd9Sstevel@tonic-gate 342ba5f469cSkrishna if (session_p->digest.flags & CRYPTO_EMULATE) { 343ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 344b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 345ba5f469cSkrishna rv = emulate_update(session_p, pPart, ulPartLen, OP_DIGEST); 346ba5f469cSkrishna goto done; 347ba5f469cSkrishna } 348ba5f469cSkrishna 3497c478bd9Sstevel@tonic-gate digest_update.du_session = session_p->k_session; 3507c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 351b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 3527c478bd9Sstevel@tonic-gate digest_update.du_datalen = ulPartLen; 3537c478bd9Sstevel@tonic-gate digest_update.du_databuf = (char *)pPart; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_DIGEST_UPDATE, 3567c478bd9Sstevel@tonic-gate &digest_update)) < 0) { 3577c478bd9Sstevel@tonic-gate if (errno != EINTR) 3587c478bd9Sstevel@tonic-gate break; 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate if (r < 0) { 3617c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 3627c478bd9Sstevel@tonic-gate } else { 3637c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(digest_update.du_return_value); 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate 366ba5f469cSkrishna done: 3677c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 3687c478bd9Sstevel@tonic-gate /* 3697c478bd9Sstevel@tonic-gate * Decrement the session reference count. 3707c478bd9Sstevel@tonic-gate * We do not hold the session lock. 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 3737c478bd9Sstevel@tonic-gate return (CKR_OK); 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate clean_exit: 3777c478bd9Sstevel@tonic-gate /* 3787c478bd9Sstevel@tonic-gate * After an error occurred, terminate the current digest 3797c478bd9Sstevel@tonic-gate * operation by resetting the active and update flags. 3807c478bd9Sstevel@tonic-gate */ 3817c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 382b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 383ba5f469cSkrishna REINIT_OPBUF(&session_p->digest); 3847c478bd9Sstevel@tonic-gate session_p->digest.flags = 0; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate /* 3877c478bd9Sstevel@tonic-gate * Decrement the session reference count. 3887c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 3897c478bd9Sstevel@tonic-gate * will release the session lock for us. 3907c478bd9Sstevel@tonic-gate */ 3917c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate return (rv); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate CK_RV 3987c478bd9Sstevel@tonic-gate C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) 3997c478bd9Sstevel@tonic-gate { 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate CK_RV rv; 4027c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 4037c478bd9Sstevel@tonic-gate kernel_object_t *key_p; 404b232b5fcSZdenek Kotala boolean_t ses_lock_held = B_FALSE; 4057c478bd9Sstevel@tonic-gate CK_BYTE_PTR pPart; 4067c478bd9Sstevel@tonic-gate CK_ULONG ulPartLen; 4077c478bd9Sstevel@tonic-gate crypto_digest_key_t digest_key; 4087c478bd9Sstevel@tonic-gate crypto_digest_update_t digest_update; 4097c478bd9Sstevel@tonic-gate int r; 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate if (!kernel_initialized) 4127c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate /* 4157c478bd9Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session 4167c478bd9Sstevel@tonic-gate * reference count. 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 4197c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 4207c478bd9Sstevel@tonic-gate return (rv); 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate /* Obtain the object pointer. */ 4237c478bd9Sstevel@tonic-gate HANDLE2OBJECT(hKey, key_p, rv); 42401223cbaSmcpowers if (rv != CKR_OK) { 42501223cbaSmcpowers (void) pthread_mutex_lock(&session_p->session_mutex); 426b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 427ba5f469cSkrishna REINIT_OPBUF(&session_p->digest); 42801223cbaSmcpowers session_p->digest.flags = 0; 42901223cbaSmcpowers REFRELE(session_p, ses_lock_held); 43001223cbaSmcpowers return (rv); 43101223cbaSmcpowers } 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate /* Check the key type */ 4347c478bd9Sstevel@tonic-gate if (key_p->is_lib_obj && (key_p->class != CKO_SECRET_KEY)) { 4357c478bd9Sstevel@tonic-gate rv = CKR_KEY_INDIGESTIBLE; 4367c478bd9Sstevel@tonic-gate goto clean_exit; 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate /* 4407c478bd9Sstevel@tonic-gate * Application must call C_DigestInit before calling 4417c478bd9Sstevel@tonic-gate * C_DigestKey. 4427c478bd9Sstevel@tonic-gate */ 4437c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 444b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 445b232b5fcSZdenek Kotala 4467c478bd9Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) { 4477c478bd9Sstevel@tonic-gate /* 4487c478bd9Sstevel@tonic-gate * Decrement the session reference count. 4497c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 4507c478bd9Sstevel@tonic-gate * will release the session lock for us. 4517c478bd9Sstevel@tonic-gate */ 45201223cbaSmcpowers OBJ_REFRELE(key_p); 4537c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 4547c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate session_p->digest.flags |= CRYPTO_OPERATION_UPDATE; 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate /* 4597c478bd9Sstevel@tonic-gate * If the key object is from the HW provider, call CRYPTO_DIGEST_KEY 4607c478bd9Sstevel@tonic-gate * ioctl. Otherwise, call CRYPTO_DIGEST_UPDATE ioctl and pass the key 4617c478bd9Sstevel@tonic-gate * by value. 4627c478bd9Sstevel@tonic-gate */ 4637c478bd9Sstevel@tonic-gate if (key_p->is_lib_obj) { 4647c478bd9Sstevel@tonic-gate digest_update.du_session = session_p->k_session; 4657c478bd9Sstevel@tonic-gate } else { 4667c478bd9Sstevel@tonic-gate digest_key.dk_session = session_p->k_session; 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 469b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate if (!key_p->is_lib_obj) { 472ba5f469cSkrishna if (session_p->digest.flags & CRYPTO_EMULATE) { 473ba5f469cSkrishna rv = CKR_FUNCTION_NOT_SUPPORTED; 474ba5f469cSkrishna goto clean_exit; 475ba5f469cSkrishna } 4767c478bd9Sstevel@tonic-gate digest_key.dk_key.ck_format = CRYPTO_KEY_REFERENCE; 4777c478bd9Sstevel@tonic-gate digest_key.dk_key.ck_obj_id = key_p->k_handle; 4787c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_DIGEST_KEY, 4797c478bd9Sstevel@tonic-gate &digest_key)) < 0) { 4807c478bd9Sstevel@tonic-gate if (errno != EINTR) 4817c478bd9Sstevel@tonic-gate break; 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate if (r < 0) { 4847c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 4857c478bd9Sstevel@tonic-gate } else { 4867c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number( 4877c478bd9Sstevel@tonic-gate digest_key.dk_return_value); 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate } else { 4907c478bd9Sstevel@tonic-gate ulPartLen = OBJ_SEC_VALUE_LEN(key_p); 4917c478bd9Sstevel@tonic-gate if (ulPartLen == 0) { 4927c478bd9Sstevel@tonic-gate rv = CKR_KEY_SIZE_RANGE; 4937c478bd9Sstevel@tonic-gate goto clean_exit; 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate pPart = (CK_BYTE_PTR) OBJ_SEC_VALUE(key_p); 4977c478bd9Sstevel@tonic-gate if (pPart == NULL) { 4987c478bd9Sstevel@tonic-gate rv = CKR_KEY_HANDLE_INVALID; 4997c478bd9Sstevel@tonic-gate goto clean_exit; 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 502ba5f469cSkrishna (void) pthread_mutex_lock(&session_p->session_mutex); 503b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 504ba5f469cSkrishna if (session_p->digest.flags & CRYPTO_EMULATE) { 505ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 506b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 507ba5f469cSkrishna rv = emulate_update(session_p, pPart, 508ba5f469cSkrishna ulPartLen, OP_DIGEST); 509ba5f469cSkrishna goto done; 510ba5f469cSkrishna } 511ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 512b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 513ba5f469cSkrishna 5147c478bd9Sstevel@tonic-gate digest_update.du_datalen = ulPartLen; 5157c478bd9Sstevel@tonic-gate digest_update.du_databuf = (char *)pPart; 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_DIGEST_UPDATE, 5187c478bd9Sstevel@tonic-gate &digest_update)) < 0) { 5197c478bd9Sstevel@tonic-gate if (errno != EINTR) 5207c478bd9Sstevel@tonic-gate break; 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate if (r < 0) { 5237c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 5247c478bd9Sstevel@tonic-gate } else { 5257c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number( 5267c478bd9Sstevel@tonic-gate digest_update.du_return_value); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 530ba5f469cSkrishna done: 5317c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * Decrement the session reference count. 5347c478bd9Sstevel@tonic-gate * We do not hold the session lock. 5357c478bd9Sstevel@tonic-gate */ 53601223cbaSmcpowers OBJ_REFRELE(key_p); 53701223cbaSmcpowers REFRELE(session_p, ses_lock_held); 5387c478bd9Sstevel@tonic-gate return (CKR_OK); 5397c478bd9Sstevel@tonic-gate } 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate clean_exit: 54201223cbaSmcpowers OBJ_REFRELE(key_p); 5437c478bd9Sstevel@tonic-gate /* 5447c478bd9Sstevel@tonic-gate * After an error occurred, terminate the current digest 5457c478bd9Sstevel@tonic-gate * operation by resetting the active and update flags. 5467c478bd9Sstevel@tonic-gate */ 5477c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 548b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 549ba5f469cSkrishna REINIT_OPBUF(&session_p->digest); 5507c478bd9Sstevel@tonic-gate session_p->digest.flags = 0; 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate /* 5537c478bd9Sstevel@tonic-gate * Decrement the session reference count. 5547c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 5557c478bd9Sstevel@tonic-gate * will release the session lock for us. 5567c478bd9Sstevel@tonic-gate */ 5577c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 5587c478bd9Sstevel@tonic-gate return (rv); 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate CK_RV 5637c478bd9Sstevel@tonic-gate C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, 5647c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulDigestLen) 5657c478bd9Sstevel@tonic-gate { 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate CK_RV rv; 5687c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 569b232b5fcSZdenek Kotala boolean_t ses_lock_held = B_FALSE; 5707c478bd9Sstevel@tonic-gate crypto_digest_final_t digest_final; 5717c478bd9Sstevel@tonic-gate int r; 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate if (!kernel_initialized) 5747c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate /* 5777c478bd9Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session 5787c478bd9Sstevel@tonic-gate * reference count. 5797c478bd9Sstevel@tonic-gate */ 5807c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 5817c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 5827c478bd9Sstevel@tonic-gate return (rv); 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate if (pulDigestLen == NULL) { 5857c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 5867c478bd9Sstevel@tonic-gate goto clean_exit; 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate /* Acquire the session lock */ 5907c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 591b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate /* 5947c478bd9Sstevel@tonic-gate * Application must call C_DigestInit before calling 5957c478bd9Sstevel@tonic-gate * C_DigestFinal. 5967c478bd9Sstevel@tonic-gate */ 5977c478bd9Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) { 5987c478bd9Sstevel@tonic-gate /* 5997c478bd9Sstevel@tonic-gate * Decrement the session reference count. 6007c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 6017c478bd9Sstevel@tonic-gate * will release the session lock for us. 6027c478bd9Sstevel@tonic-gate */ 6037c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 6047c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate 607ba5f469cSkrishna /* The order of checks is important here */ 608ba5f469cSkrishna if (session_p->digest.flags & CRYPTO_EMULATE_USING_SW) { 609ba5f469cSkrishna if (session_p->digest.flags & CRYPTO_EMULATE_UPDATE_DONE) { 610ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 611b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 612ba5f469cSkrishna rv = do_soft_digest(get_spp(&session_p->digest), 613ba5f469cSkrishna NULL, NULL, NULL, pDigest, pulDigestLen, OP_FINAL); 614ba5f469cSkrishna } else { 615ba5f469cSkrishna /* 616ba5f469cSkrishna * We end up here if an earlier C_DigestFinal() call 617ba5f469cSkrishna * took the C_Digest() path and it had returned 618ba5f469cSkrishna * CKR_BUFFER_TOO_SMALL. 619ba5f469cSkrishna */ 620ba5f469cSkrishna digest_buf_t *bufp = session_p->digest.context; 621ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 622b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 623ba5f469cSkrishna if (bufp == NULL || bufp->buf == NULL) { 624ba5f469cSkrishna rv = CKR_ARGUMENTS_BAD; 625ba5f469cSkrishna goto clean_exit; 626ba5f469cSkrishna } 627ba5f469cSkrishna rv = do_soft_digest(get_spp(&session_p->digest), 628ba5f469cSkrishna NULL, bufp->buf, bufp->indata_len, 629ba5f469cSkrishna pDigest, pulDigestLen, OP_SINGLE); 630ba5f469cSkrishna } 631ba5f469cSkrishna goto done; 632ba5f469cSkrishna } else if (session_p->digest.flags & CRYPTO_EMULATE) { 633ba5f469cSkrishna digest_buf_t *bufp = session_p->digest.context; 634ba5f469cSkrishna 635ba5f469cSkrishna /* 636ba5f469cSkrishna * We are emulating a single-part operation now. 637ba5f469cSkrishna * So, clear the flag. 638ba5f469cSkrishna */ 639ba5f469cSkrishna session_p->digest.flags &= ~CRYPTO_OPERATION_UPDATE; 640ba5f469cSkrishna if (bufp == NULL || bufp->buf == NULL) { 641ba5f469cSkrishna rv = CKR_ARGUMENTS_BAD; 642ba5f469cSkrishna goto clean_exit; 643ba5f469cSkrishna } 644ba5f469cSkrishna REFRELE(session_p, ses_lock_held); 645ba5f469cSkrishna rv = C_Digest(hSession, bufp->buf, bufp->indata_len, 646ba5f469cSkrishna pDigest, pulDigestLen); 647ba5f469cSkrishna return (rv); 648ba5f469cSkrishna } 649ba5f469cSkrishna 6507c478bd9Sstevel@tonic-gate digest_final.df_session = session_p->k_session; 6517c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 652b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 6537c478bd9Sstevel@tonic-gate digest_final.df_digestlen = *pulDigestLen; 6547c478bd9Sstevel@tonic-gate digest_final.df_digestbuf = (char *)pDigest; 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_DIGEST_FINAL, &digest_final)) < 0) { 6577c478bd9Sstevel@tonic-gate if (errno != EINTR) 6587c478bd9Sstevel@tonic-gate break; 6597c478bd9Sstevel@tonic-gate } 6607c478bd9Sstevel@tonic-gate if (r < 0) { 6617c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 6627c478bd9Sstevel@tonic-gate } else { 6637c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(digest_final.df_return_value); 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate if ((rv == CKR_OK) || (rv == CKR_BUFFER_TOO_SMALL)) 6677c478bd9Sstevel@tonic-gate *pulDigestLen = digest_final.df_digestlen; 6687c478bd9Sstevel@tonic-gate 669ba5f469cSkrishna done: 6707c478bd9Sstevel@tonic-gate if ((rv == CKR_BUFFER_TOO_SMALL) || 6717c478bd9Sstevel@tonic-gate (rv == CKR_OK && pDigest == NULL)) { 6727c478bd9Sstevel@tonic-gate /* 6737c478bd9Sstevel@tonic-gate * We will not terminate the active digest operation flag, 6747c478bd9Sstevel@tonic-gate * when the application-supplied buffer is too small, or 6757c478bd9Sstevel@tonic-gate * the application asks for the length of buffer to hold 6767c478bd9Sstevel@tonic-gate * the message digest. 6777c478bd9Sstevel@tonic-gate * 6787c478bd9Sstevel@tonic-gate * Decrement the session reference count. 6797c478bd9Sstevel@tonic-gate * We do not hold the session lock. 6807c478bd9Sstevel@tonic-gate */ 6817c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 6827c478bd9Sstevel@tonic-gate return (rv); 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate clean_exit: 6867c478bd9Sstevel@tonic-gate /* Terminates the active digest operation */ 6877c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 688b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 689ba5f469cSkrishna REINIT_OPBUF(&session_p->digest); 6907c478bd9Sstevel@tonic-gate session_p->digest.flags = 0; 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate /* 6937c478bd9Sstevel@tonic-gate * Decrement the session reference count. 6947c478bd9Sstevel@tonic-gate * We hold the session lock, and REFRELE() 6957c478bd9Sstevel@tonic-gate * will release the session lock for us. 6967c478bd9Sstevel@tonic-gate */ 6977c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate return (rv); 7007c478bd9Sstevel@tonic-gate } 701