10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7690SAlexandr.Nedvedicky@Sun.COM * Common Development and Distribution License (the "License").
6*7690SAlexandr.Nedvedicky@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*7690SAlexandr.Nedvedicky@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <pthread.h>
270Sstevel@tonic-gate #include <security/cryptoki.h>
280Sstevel@tonic-gate #include "softGlobal.h"
290Sstevel@tonic-gate #include "softOps.h"
300Sstevel@tonic-gate #include "softSession.h"
310Sstevel@tonic-gate
320Sstevel@tonic-gate
330Sstevel@tonic-gate CK_RV
C_DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)340Sstevel@tonic-gate C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
350Sstevel@tonic-gate {
360Sstevel@tonic-gate
370Sstevel@tonic-gate CK_RV rv;
380Sstevel@tonic-gate soft_session_t *session_p;
390Sstevel@tonic-gate boolean_t lock_held = B_TRUE;
400Sstevel@tonic-gate
410Sstevel@tonic-gate if (!softtoken_initialized)
420Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
430Sstevel@tonic-gate
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
460Sstevel@tonic-gate * reference count.
470Sstevel@tonic-gate */
480Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
490Sstevel@tonic-gate if (rv != CKR_OK)
500Sstevel@tonic-gate return (rv);
510Sstevel@tonic-gate
520Sstevel@tonic-gate if (pMechanism == NULL) {
530Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD;
540Sstevel@tonic-gate goto clean_exit;
550Sstevel@tonic-gate }
560Sstevel@tonic-gate
570Sstevel@tonic-gate /* Acquire the session lock */
580Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
590Sstevel@tonic-gate
600Sstevel@tonic-gate /* Check to see if digest operation is already active */
610Sstevel@tonic-gate if (session_p->digest.flags & CRYPTO_OPERATION_ACTIVE) {
620Sstevel@tonic-gate /*
630Sstevel@tonic-gate * Free the memory to avoid memory leak.
640Sstevel@tonic-gate * digest.context is only a flat structure.
650Sstevel@tonic-gate */
66*7690SAlexandr.Nedvedicky@Sun.COM soft_digest_cleanup(session_p, lock_held);
670Sstevel@tonic-gate }
680Sstevel@tonic-gate
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate * This active flag will remain ON until application calls either
710Sstevel@tonic-gate * C_Digest or C_DigestFinal to actually obtain the value of
720Sstevel@tonic-gate * the message digest.
730Sstevel@tonic-gate */
740Sstevel@tonic-gate session_p->digest.flags = CRYPTO_OPERATION_ACTIVE;
750Sstevel@tonic-gate
760Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
770Sstevel@tonic-gate
780Sstevel@tonic-gate rv = soft_digest_init(session_p, pMechanism);
790Sstevel@tonic-gate
800Sstevel@tonic-gate if (rv != CKR_OK) {
810Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
820Sstevel@tonic-gate session_p->digest.flags &= ~CRYPTO_OPERATION_ACTIVE;
830Sstevel@tonic-gate /*
840Sstevel@tonic-gate * Decrement the session reference count.
850Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
860Sstevel@tonic-gate * will release the session lock for us.
870Sstevel@tonic-gate */
880Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
890Sstevel@tonic-gate return (rv);
900Sstevel@tonic-gate }
910Sstevel@tonic-gate
920Sstevel@tonic-gate clean_exit:
930Sstevel@tonic-gate /*
940Sstevel@tonic-gate * Decrement the session reference count.
950Sstevel@tonic-gate * We do not hold the session lock.
960Sstevel@tonic-gate */
970Sstevel@tonic-gate lock_held = B_FALSE;
980Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
990Sstevel@tonic-gate return (rv);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate CK_RV
C_Digest(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)1040Sstevel@tonic-gate C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1050Sstevel@tonic-gate CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate CK_RV rv;
1090Sstevel@tonic-gate soft_session_t *session_p;
1100Sstevel@tonic-gate boolean_t lock_held = B_TRUE;
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate if (!softtoken_initialized)
1130Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
1170Sstevel@tonic-gate * reference count.
1180Sstevel@tonic-gate */
1190Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
1200Sstevel@tonic-gate if (rv != CKR_OK)
1210Sstevel@tonic-gate return (rv);
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate if (pData == NULL || pulDigestLen == NULL) {
1240Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD;
1250Sstevel@tonic-gate goto clean_exit;
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate /* Acquire the session lock */
1290Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate /* Application must call C_DigestInit before calling C_Digest */
1320Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) {
1330Sstevel@tonic-gate /*
1340Sstevel@tonic-gate * Decrement the session reference count.
1350Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
1360Sstevel@tonic-gate * will release the session lock for us.
1370Sstevel@tonic-gate */
1380Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
1390Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED);
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate /*
1430Sstevel@tonic-gate * C_Digest must be called without intervening C_DigestUpdate
1440Sstevel@tonic-gate * calls.
1450Sstevel@tonic-gate */
1460Sstevel@tonic-gate if (session_p->digest.flags & CRYPTO_OPERATION_UPDATE) {
1470Sstevel@tonic-gate /*
1480Sstevel@tonic-gate * C_Digest can not be used to terminate a multi-part
1490Sstevel@tonic-gate * operation, so we'll leave the active digest operation
1500Sstevel@tonic-gate * flag on and let the application continue with the
1510Sstevel@tonic-gate * digest update operation.
1520Sstevel@tonic-gate *
1530Sstevel@tonic-gate * Decrement the session reference count.
1540Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
1550Sstevel@tonic-gate * will release the session lock for us.
1560Sstevel@tonic-gate */
1570Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
1580Sstevel@tonic-gate return (CKR_FUNCTION_FAILED);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate rv = soft_digest(session_p, pData, ulDataLen, pDigest, pulDigestLen);
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate if ((rv == CKR_BUFFER_TOO_SMALL) ||
1660Sstevel@tonic-gate (pDigest == NULL && rv == CKR_OK)) {
1670Sstevel@tonic-gate /*
1680Sstevel@tonic-gate * We will not terminate the active digest operation flag,
1690Sstevel@tonic-gate * when the application-supplied buffer is too small, or
1700Sstevel@tonic-gate * the application asks for the length of buffer to hold
1710Sstevel@tonic-gate * the message digest.
1720Sstevel@tonic-gate *
1730Sstevel@tonic-gate * Decrement the session reference count.
1740Sstevel@tonic-gate * We do not hold the session lock.
1750Sstevel@tonic-gate */
1760Sstevel@tonic-gate lock_held = B_FALSE;
1770Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
1780Sstevel@tonic-gate return (rv);
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate clean_exit:
1820Sstevel@tonic-gate /*
1830Sstevel@tonic-gate * Terminates the active digest operation.
1840Sstevel@tonic-gate * Application needs to call C_DigestInit again for next
1850Sstevel@tonic-gate * digest operation.
1860Sstevel@tonic-gate */
1870Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
188*7690SAlexandr.Nedvedicky@Sun.COM
189*7690SAlexandr.Nedvedicky@Sun.COM soft_digest_cleanup(session_p, lock_held);
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate /*
1920Sstevel@tonic-gate * Decrement the session reference count.
1930Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
1940Sstevel@tonic-gate * will release the session lock for us.
1950Sstevel@tonic-gate */
1960Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate return (rv);
1990Sstevel@tonic-gate }
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate CK_RV
C_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)2030Sstevel@tonic-gate C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
2040Sstevel@tonic-gate CK_ULONG ulPartLen)
2050Sstevel@tonic-gate {
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate CK_RV rv;
2080Sstevel@tonic-gate soft_session_t *session_p;
2090Sstevel@tonic-gate boolean_t lock_held = B_TRUE;
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate if (!softtoken_initialized)
2120Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate /*
2150Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
2160Sstevel@tonic-gate * reference count.
2170Sstevel@tonic-gate */
2180Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
2190Sstevel@tonic-gate if (rv != CKR_OK)
2200Sstevel@tonic-gate return (rv);
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate if (pPart == NULL) {
2230Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD;
2240Sstevel@tonic-gate goto clean_exit;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate /* Acquire the session lock */
2280Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate /*
2310Sstevel@tonic-gate * Application must call C_DigestInit before calling
2320Sstevel@tonic-gate * C_DigestUpdate.
2330Sstevel@tonic-gate */
2340Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) {
2350Sstevel@tonic-gate /*
2360Sstevel@tonic-gate * Decrement the session reference count.
2370Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
2380Sstevel@tonic-gate * will release the session lock for us.
2390Sstevel@tonic-gate */
2400Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
2410Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED);
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate /* Set update flag to protect C_Digest */
2450Sstevel@tonic-gate session_p->digest.flags |= CRYPTO_OPERATION_UPDATE;
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate rv = soft_digest_update(session_p, pPart, ulPartLen);
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate if (rv == CKR_OK) {
2520Sstevel@tonic-gate /*
2530Sstevel@tonic-gate * Decrement the session reference count.
2540Sstevel@tonic-gate * We do not hold the session lock.
2550Sstevel@tonic-gate */
2560Sstevel@tonic-gate lock_held = B_FALSE;
2570Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
2580Sstevel@tonic-gate return (CKR_OK);
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate
2610Sstevel@tonic-gate clean_exit:
2620Sstevel@tonic-gate /*
2630Sstevel@tonic-gate * After an error occurred, terminate the current digest
2640Sstevel@tonic-gate * operation by resetting the active and update flags.
2650Sstevel@tonic-gate */
2660Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
267*7690SAlexandr.Nedvedicky@Sun.COM
268*7690SAlexandr.Nedvedicky@Sun.COM soft_digest_cleanup(session_p, lock_held);
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate /*
2710Sstevel@tonic-gate * Decrement the session reference count.
2720Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
2730Sstevel@tonic-gate * will release the session lock for us.
2740Sstevel@tonic-gate */
2750Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate return (rv);
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate CK_RV
C_DigestKey(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hKey)2820Sstevel@tonic-gate C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
2830Sstevel@tonic-gate {
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate CK_RV rv;
2860Sstevel@tonic-gate soft_session_t *session_p;
2870Sstevel@tonic-gate soft_object_t *key_p;
2880Sstevel@tonic-gate boolean_t lock_held = B_TRUE;
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate if (!softtoken_initialized)
2910Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate /*
2940Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
2950Sstevel@tonic-gate * reference count.
2960Sstevel@tonic-gate */
2970Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
2980Sstevel@tonic-gate if (rv != CKR_OK)
2990Sstevel@tonic-gate return (rv);
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate /* Obtain the object pointer. */
3020Sstevel@tonic-gate HANDLE2OBJECT(hKey, key_p, rv);
3030Sstevel@tonic-gate if (rv != CKR_OK)
3040Sstevel@tonic-gate goto clean_exit;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate /*
3090Sstevel@tonic-gate * Application must call C_DigestInit before calling
3100Sstevel@tonic-gate * C_DigestKey.
3110Sstevel@tonic-gate */
3120Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) {
3130Sstevel@tonic-gate /*
3140Sstevel@tonic-gate * Decrement the session reference count.
3150Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
3160Sstevel@tonic-gate * will release the session lock for us.
3170Sstevel@tonic-gate */
3180Sstevel@tonic-gate OBJ_REFRELE(key_p);
3190Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
3200Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED);
3210Sstevel@tonic-gate }
3220Sstevel@tonic-gate
3230Sstevel@tonic-gate /*
3240Sstevel@tonic-gate * Remember the fact that a key was thrown into the mix, so that
3250Sstevel@tonic-gate * C_DigestFinal bzero()'s the digest context before freeing it.
3260Sstevel@tonic-gate */
3270Sstevel@tonic-gate session_p->digest.flags |= (CRYPTO_KEY_DIGESTED |
3280Sstevel@tonic-gate CRYPTO_OPERATION_UPDATE);
3290Sstevel@tonic-gate
3300Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate rv = soft_digest_key(session_p, key_p);
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate if (rv == CKR_OK) {
3350Sstevel@tonic-gate /*
3360Sstevel@tonic-gate * Decrement the session reference count.
3370Sstevel@tonic-gate * We do not hold the session lock.
3380Sstevel@tonic-gate */
3390Sstevel@tonic-gate lock_held = B_FALSE;
3400Sstevel@tonic-gate OBJ_REFRELE(key_p);
3410Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
3420Sstevel@tonic-gate return (CKR_OK);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate OBJ_REFRELE(key_p);
3460Sstevel@tonic-gate clean_exit:
3470Sstevel@tonic-gate /*
3480Sstevel@tonic-gate * After an error occurred, terminate the current digest
3490Sstevel@tonic-gate * operation by resetting the active and update flags.
3500Sstevel@tonic-gate */
3510Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
352*7690SAlexandr.Nedvedicky@Sun.COM
353*7690SAlexandr.Nedvedicky@Sun.COM soft_digest_cleanup(session_p, lock_held);
3540Sstevel@tonic-gate
3550Sstevel@tonic-gate /*
3560Sstevel@tonic-gate * Decrement the session reference count.
3570Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
3580Sstevel@tonic-gate * will release the session lock for us.
3590Sstevel@tonic-gate */
3600Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
3610Sstevel@tonic-gate return (rv);
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate CK_RV
C_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)3660Sstevel@tonic-gate C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
3670Sstevel@tonic-gate CK_ULONG_PTR pulDigestLen)
3680Sstevel@tonic-gate {
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate CK_RV rv;
3710Sstevel@tonic-gate soft_session_t *session_p;
3720Sstevel@tonic-gate boolean_t lock_held = B_TRUE;
3730Sstevel@tonic-gate
3740Sstevel@tonic-gate if (!softtoken_initialized)
3750Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
3760Sstevel@tonic-gate
3770Sstevel@tonic-gate /*
3780Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
3790Sstevel@tonic-gate * reference count.
3800Sstevel@tonic-gate */
3810Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
3820Sstevel@tonic-gate if (rv != CKR_OK)
3830Sstevel@tonic-gate return (rv);
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate if (pulDigestLen == NULL) {
3860Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD;
3870Sstevel@tonic-gate goto clean_exit;
3880Sstevel@tonic-gate }
3890Sstevel@tonic-gate
3900Sstevel@tonic-gate /* Acquire the session lock */
3910Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate /*
3940Sstevel@tonic-gate * Application must call C_DigestInit before calling
3950Sstevel@tonic-gate * C_DigestFinal.
3960Sstevel@tonic-gate */
3970Sstevel@tonic-gate if (!(session_p->digest.flags & CRYPTO_OPERATION_ACTIVE)) {
3980Sstevel@tonic-gate /*
3990Sstevel@tonic-gate * Decrement the session reference count.
4000Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
4010Sstevel@tonic-gate * will release the session lock for us.
4020Sstevel@tonic-gate */
4030Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
4040Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED);
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate rv = soft_digest_final(session_p, pDigest, pulDigestLen);
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate if ((rv == CKR_BUFFER_TOO_SMALL) ||
4120Sstevel@tonic-gate (pDigest == NULL && rv == CKR_OK)) {
4130Sstevel@tonic-gate /*
4140Sstevel@tonic-gate * We will not terminate the active digest operation flag,
4150Sstevel@tonic-gate * when the application-supplied buffer is too small, or
4160Sstevel@tonic-gate * the application asks for the length of buffer to hold
4170Sstevel@tonic-gate * the message digest.
4180Sstevel@tonic-gate *
4190Sstevel@tonic-gate * Decrement the session reference count.
4200Sstevel@tonic-gate * We do not hold the session lock.
4210Sstevel@tonic-gate */
4220Sstevel@tonic-gate lock_held = B_FALSE;
4230Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
4240Sstevel@tonic-gate return (rv);
4250Sstevel@tonic-gate }
4260Sstevel@tonic-gate
4270Sstevel@tonic-gate clean_exit:
4280Sstevel@tonic-gate /* Terminates the active digest operation */
4290Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
430*7690SAlexandr.Nedvedicky@Sun.COM
431*7690SAlexandr.Nedvedicky@Sun.COM soft_digest_cleanup(session_p, lock_held);
4320Sstevel@tonic-gate
4330Sstevel@tonic-gate /*
4340Sstevel@tonic-gate * Decrement the session reference count.
4350Sstevel@tonic-gate * We hold the session lock, and SES_REFRELE()
4360Sstevel@tonic-gate * will release the session lock for us.
4370Sstevel@tonic-gate */
4380Sstevel@tonic-gate SES_REFRELE(session_p, lock_held);
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate return (rv);
4410Sstevel@tonic-gate }
442