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 <strings.h>
270Sstevel@tonic-gate #include <md5.h>
280Sstevel@tonic-gate #include <pthread.h>
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <sys/sha1.h>
31676Sizick #include <sys/sha2.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <security/cryptoki.h>
340Sstevel@tonic-gate #include "softGlobal.h"
350Sstevel@tonic-gate #include "softOps.h"
360Sstevel@tonic-gate #include "softSession.h"
370Sstevel@tonic-gate #include "softObject.h"
380Sstevel@tonic-gate
390Sstevel@tonic-gate
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate * soft_digest_init()
420Sstevel@tonic-gate *
430Sstevel@tonic-gate * Arguments:
440Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
450Sstevel@tonic-gate * pMechanism: pointer to CK_MECHANISM struct provided by application
460Sstevel@tonic-gate *
470Sstevel@tonic-gate * Description:
480Sstevel@tonic-gate * called by C_DigestInit(). This function allocates space for
490Sstevel@tonic-gate * context, then calls the corresponding software provided digest
500Sstevel@tonic-gate * init routine based on the mechanism.
510Sstevel@tonic-gate *
520Sstevel@tonic-gate * Returns:
530Sstevel@tonic-gate * CKR_OK: success
540Sstevel@tonic-gate * CKR_HOST_MEMORY: run out of system memory
550Sstevel@tonic-gate * CKR_MECHANISM_INVALID: invalid mechanism type
560Sstevel@tonic-gate */
570Sstevel@tonic-gate CK_RV
soft_digest_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism)580Sstevel@tonic-gate soft_digest_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism)
590Sstevel@tonic-gate {
600Sstevel@tonic-gate
610Sstevel@tonic-gate switch (pMechanism->mechanism) {
620Sstevel@tonic-gate
630Sstevel@tonic-gate case CKM_MD5:
640Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
650Sstevel@tonic-gate
660Sstevel@tonic-gate session_p->digest.context = malloc(sizeof (MD5_CTX));
670Sstevel@tonic-gate
680Sstevel@tonic-gate if (session_p->digest.context == NULL) {
690Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
700Sstevel@tonic-gate return (CKR_HOST_MEMORY);
710Sstevel@tonic-gate }
720Sstevel@tonic-gate
730Sstevel@tonic-gate session_p->digest.mech.mechanism = CKM_MD5;
740Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
750Sstevel@tonic-gate
760Sstevel@tonic-gate MD5Init((MD5_CTX *)session_p->digest.context);
770Sstevel@tonic-gate
780Sstevel@tonic-gate break;
790Sstevel@tonic-gate
800Sstevel@tonic-gate case CKM_SHA_1:
810Sstevel@tonic-gate
820Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
830Sstevel@tonic-gate
840Sstevel@tonic-gate session_p->digest.context = malloc(sizeof (SHA1_CTX));
850Sstevel@tonic-gate
860Sstevel@tonic-gate if (session_p->digest.context == NULL) {
870Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
880Sstevel@tonic-gate return (CKR_HOST_MEMORY);
890Sstevel@tonic-gate }
900Sstevel@tonic-gate
910Sstevel@tonic-gate session_p->digest.mech.mechanism = CKM_SHA_1;
92872Sizick session_p->digest.mech.pParameter = pMechanism->pParameter;
93872Sizick session_p->digest.mech.ulParameterLen =
94872Sizick pMechanism->ulParameterLen;
950Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
960Sstevel@tonic-gate
970Sstevel@tonic-gate SHA1Init((SHA1_CTX *)session_p->digest.context);
980Sstevel@tonic-gate
990Sstevel@tonic-gate break;
1000Sstevel@tonic-gate
101676Sizick case CKM_SHA256:
102676Sizick case CKM_SHA384:
103676Sizick case CKM_SHA512:
104676Sizick
105676Sizick (void) pthread_mutex_lock(&session_p->session_mutex);
106676Sizick
107676Sizick session_p->digest.context = malloc(sizeof (SHA2_CTX));
108676Sizick
109676Sizick if (session_p->digest.context == NULL) {
110676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
111676Sizick return (CKR_HOST_MEMORY);
112676Sizick }
113676Sizick
114676Sizick switch (pMechanism->mechanism) {
115676Sizick case CKM_SHA256:
116676Sizick session_p->digest.mech.mechanism = CKM_SHA256;
117676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
118676Sizick SHA2Init(SHA256,
119676Sizick (SHA2_CTX *)session_p->digest.context);
120676Sizick break;
121676Sizick
122676Sizick case CKM_SHA384:
123676Sizick session_p->digest.mech.mechanism = CKM_SHA384;
124676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
125676Sizick SHA2Init(SHA384,
126676Sizick (SHA2_CTX *)session_p->digest.context);
127676Sizick break;
128676Sizick
129676Sizick case CKM_SHA512:
130676Sizick session_p->digest.mech.mechanism = CKM_SHA512;
131676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
132676Sizick SHA2Init(SHA512,
133676Sizick (SHA2_CTX *)session_p->digest.context);
134676Sizick break;
135676Sizick }
136676Sizick break;
137676Sizick
1380Sstevel@tonic-gate default:
1390Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate return (CKR_OK);
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate /*
1470Sstevel@tonic-gate * soft_digest_common()
1480Sstevel@tonic-gate *
1490Sstevel@tonic-gate * Arguments:
1500Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
1510Sstevel@tonic-gate * pData: pointer to the input data to be digested
1520Sstevel@tonic-gate * ulDataLen: length of the input data
1530Sstevel@tonic-gate * pDigest: pointer to the output data after digesting
1540Sstevel@tonic-gate * pulDigestLen: length of the output data
1550Sstevel@tonic-gate *
1560Sstevel@tonic-gate * Description:
1570Sstevel@tonic-gate * called by soft_digest() or soft_digest_final(). This function
1580Sstevel@tonic-gate * determines the length of output buffer and calls the corresponding
1590Sstevel@tonic-gate * software provided digest routine based on the mechanism.
1600Sstevel@tonic-gate *
1610Sstevel@tonic-gate * Returns:
1620Sstevel@tonic-gate * CKR_OK: success
1630Sstevel@tonic-gate * CKR_MECHANISM_INVALID: invalid mechanism type
1640Sstevel@tonic-gate * CKR_BUFFER_TOO_SMALL: the output buffer provided by application
1650Sstevel@tonic-gate * is too small
1660Sstevel@tonic-gate */
1670Sstevel@tonic-gate CK_RV
soft_digest_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)1680Sstevel@tonic-gate soft_digest_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1690Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
1700Sstevel@tonic-gate {
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate CK_ULONG digestLen = 0;
1730Sstevel@tonic-gate size_t len = 0;
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate /*
1760Sstevel@tonic-gate * Determine the output data length based on the mechanism
1770Sstevel@tonic-gate */
1780Sstevel@tonic-gate switch (session_p->digest.mech.mechanism) {
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate case CKM_MD5:
1810Sstevel@tonic-gate digestLen = 16;
1820Sstevel@tonic-gate break;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate case CKM_SHA_1:
1850Sstevel@tonic-gate digestLen = 20;
1860Sstevel@tonic-gate break;
1870Sstevel@tonic-gate
188676Sizick case CKM_SHA256:
189676Sizick digestLen = 32;
190676Sizick break;
191676Sizick
192676Sizick case CKM_SHA384:
193676Sizick digestLen = 48;
194676Sizick break;
195676Sizick
196676Sizick case CKM_SHA512:
197676Sizick digestLen = 64;
198676Sizick break;
199676Sizick
2000Sstevel@tonic-gate default:
2010Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate if (pDigest == NULL) {
2050Sstevel@tonic-gate /*
2060Sstevel@tonic-gate * Application only wants to know the length of the
2070Sstevel@tonic-gate * buffer needed to hold the message digest.
2080Sstevel@tonic-gate */
2090Sstevel@tonic-gate *pulDigestLen = digestLen;
2100Sstevel@tonic-gate return (CKR_OK);
2110Sstevel@tonic-gate }
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate if (*pulDigestLen < digestLen) {
2140Sstevel@tonic-gate /*
2150Sstevel@tonic-gate * Application provides buffer too small to hold the
2160Sstevel@tonic-gate * digest message. Return the length of buffer needed
2170Sstevel@tonic-gate * to the application.
2180Sstevel@tonic-gate */
2190Sstevel@tonic-gate *pulDigestLen = digestLen;
2200Sstevel@tonic-gate return (CKR_BUFFER_TOO_SMALL);
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate /*
2240Sstevel@tonic-gate * Call the corresponding system provided software digest routine.
2250Sstevel@tonic-gate * If the soft_digest_common() is called by soft_digest_final()
2260Sstevel@tonic-gate * the pData is NULL, and the ulDataLen is zero.
2270Sstevel@tonic-gate */
2280Sstevel@tonic-gate switch (session_p->digest.mech.mechanism) {
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate case CKM_MD5:
2310Sstevel@tonic-gate if (pData != NULL) {
2320Sstevel@tonic-gate /*
2330Sstevel@tonic-gate * this is called by soft_digest()
2340Sstevel@tonic-gate */
2350Sstevel@tonic-gate #ifdef __sparcv9
2360Sstevel@tonic-gate MD5Update((MD5_CTX *)session_p->digest.context,
2370Sstevel@tonic-gate /* LINTED */
2380Sstevel@tonic-gate pData, (uint_t)ulDataLen);
2390Sstevel@tonic-gate #else /* !__sparcv9 */
2400Sstevel@tonic-gate MD5Update((MD5_CTX *)session_p->digest.context,
2410Sstevel@tonic-gate pData, ulDataLen);
2420Sstevel@tonic-gate #endif /* __sparcv9 */
2430Sstevel@tonic-gate MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
2440Sstevel@tonic-gate } else {
2450Sstevel@tonic-gate /*
2460Sstevel@tonic-gate * this is called by soft_digest_final()
2470Sstevel@tonic-gate */
2480Sstevel@tonic-gate MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
2490Sstevel@tonic-gate len = sizeof (MD5_CTX);
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate break;
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate case CKM_SHA_1:
2540Sstevel@tonic-gate if (pData != NULL) {
2550Sstevel@tonic-gate /*
2560Sstevel@tonic-gate * this is called by soft_digest()
2570Sstevel@tonic-gate */
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate #ifdef __sparcv9
2600Sstevel@tonic-gate SHA1Update((SHA1_CTX *)session_p->digest.context,
2610Sstevel@tonic-gate /* LINTED */
2620Sstevel@tonic-gate pData, (uint32_t)ulDataLen);
2630Sstevel@tonic-gate #else /* !__sparcv9 */
2640Sstevel@tonic-gate SHA1Update((SHA1_CTX *)session_p->digest.context,
2650Sstevel@tonic-gate pData, ulDataLen);
2660Sstevel@tonic-gate #endif /* __sparcv9 */
2670Sstevel@tonic-gate SHA1Final(pDigest,
2680Sstevel@tonic-gate (SHA1_CTX *)session_p->digest.context);
2690Sstevel@tonic-gate } else {
2700Sstevel@tonic-gate /*
2710Sstevel@tonic-gate * this is called by soft_digest_final()
2720Sstevel@tonic-gate */
2730Sstevel@tonic-gate SHA1Final(pDigest,
2740Sstevel@tonic-gate (SHA1_CTX *)session_p->digest.context);
2750Sstevel@tonic-gate len = sizeof (SHA1_CTX);
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate break;
278676Sizick case CKM_SHA256:
279676Sizick case CKM_SHA384:
280676Sizick case CKM_SHA512:
281676Sizick if (pData != NULL) {
282676Sizick /*
283676Sizick * this is called by soft_digest()
284676Sizick */
285676Sizick
286676Sizick SHA2Update((SHA2_CTX *)session_p->digest.context,
287676Sizick pData, ulDataLen);
288676Sizick
289676Sizick SHA2Final(pDigest,
290676Sizick (SHA2_CTX *)session_p->digest.context);
291676Sizick } else {
292676Sizick /*
293676Sizick * this is called by soft_digest_final()
294676Sizick */
295676Sizick SHA2Final(pDigest,
296676Sizick (SHA2_CTX *)session_p->digest.context);
297676Sizick len = sizeof (SHA2_CTX);
298676Sizick }
299676Sizick
300676Sizick break;
3010Sstevel@tonic-gate }
3020Sstevel@tonic-gate
3030Sstevel@tonic-gate /* Paranoia on behalf of C_DigestKey callers: bzero the context */
3040Sstevel@tonic-gate if (session_p->digest.flags & CRYPTO_KEY_DIGESTED) {
3050Sstevel@tonic-gate bzero(session_p->digest.context, len);
3060Sstevel@tonic-gate session_p->digest.flags &= ~CRYPTO_KEY_DIGESTED;
3070Sstevel@tonic-gate }
3080Sstevel@tonic-gate *pulDigestLen = digestLen;
3090Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
3100Sstevel@tonic-gate free(session_p->digest.context);
3110Sstevel@tonic-gate session_p->digest.context = NULL;
3120Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate return (CKR_OK);
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate /*
3190Sstevel@tonic-gate * soft_digest()
3200Sstevel@tonic-gate *
3210Sstevel@tonic-gate * Arguments:
3220Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
3230Sstevel@tonic-gate * pData: pointer to the input data to be digested
3240Sstevel@tonic-gate * ulDataLen: length of the input data
3250Sstevel@tonic-gate * pDigest: pointer to the output data after digesting
3260Sstevel@tonic-gate * pulDigestLen: length of the output data
3270Sstevel@tonic-gate *
3280Sstevel@tonic-gate * Description:
3290Sstevel@tonic-gate * called by C_Digest(). This function calls soft_digest_common().
3300Sstevel@tonic-gate *
3310Sstevel@tonic-gate * Returns:
3320Sstevel@tonic-gate * see return values in soft_digest_common().
3330Sstevel@tonic-gate */
3340Sstevel@tonic-gate CK_RV
soft_digest(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)3350Sstevel@tonic-gate soft_digest(soft_session_t *session_p, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
3360Sstevel@tonic-gate CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate
3390Sstevel@tonic-gate return (soft_digest_common(session_p, pData, ulDataLen,
3400Sstevel@tonic-gate pDigest, pulDigestLen));
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate /*
3450Sstevel@tonic-gate * soft_digest_update()
3460Sstevel@tonic-gate *
3470Sstevel@tonic-gate * Arguments:
3480Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
3490Sstevel@tonic-gate * pPart: pointer to the input data to be digested
3500Sstevel@tonic-gate * ulPartLen: length of the input data
3510Sstevel@tonic-gate *
3520Sstevel@tonic-gate * Description:
3530Sstevel@tonic-gate * called by C_DigestUpdate(). This function calls the corresponding
3540Sstevel@tonic-gate * software provided digest update routine based on the mechanism.
3550Sstevel@tonic-gate *
3560Sstevel@tonic-gate * Returns:
3570Sstevel@tonic-gate * CKR_OK: success
3580Sstevel@tonic-gate * CKR_MECHANISM_INVALID: invalid MECHANISM type.
3590Sstevel@tonic-gate */
3600Sstevel@tonic-gate CK_RV
soft_digest_update(soft_session_t * session_p,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)3610Sstevel@tonic-gate soft_digest_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
3620Sstevel@tonic-gate CK_ULONG ulPartLen)
3630Sstevel@tonic-gate {
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate switch (session_p->digest.mech.mechanism) {
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate case CKM_MD5:
3680Sstevel@tonic-gate #ifdef __sparcv9
3690Sstevel@tonic-gate MD5Update((MD5_CTX *)session_p->digest.context,
3700Sstevel@tonic-gate /* LINTED */
3710Sstevel@tonic-gate pPart, (uint_t)ulPartLen);
3720Sstevel@tonic-gate #else /* !__sparcv9 */
3730Sstevel@tonic-gate MD5Update((MD5_CTX *)session_p->digest.context,
3740Sstevel@tonic-gate pPart, ulPartLen);
3750Sstevel@tonic-gate #endif /* __sparcv9 */
3760Sstevel@tonic-gate break;
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate case CKM_SHA_1:
3790Sstevel@tonic-gate #ifdef __sparcv9
3800Sstevel@tonic-gate SHA1Update((SHA1_CTX *)session_p->digest.context,
3810Sstevel@tonic-gate /* LINTED */
3820Sstevel@tonic-gate pPart, (uint32_t)ulPartLen);
3830Sstevel@tonic-gate #else /* !__sparcv9 */
3840Sstevel@tonic-gate SHA1Update((SHA1_CTX *)session_p->digest.context,
3850Sstevel@tonic-gate pPart, ulPartLen);
3860Sstevel@tonic-gate #endif /* __sparcv9 */
3870Sstevel@tonic-gate break;
3880Sstevel@tonic-gate
389676Sizick case CKM_SHA256:
390676Sizick case CKM_SHA384:
391676Sizick case CKM_SHA512:
392676Sizick SHA2Update((SHA2_CTX *)session_p->digest.context,
393676Sizick pPart, ulPartLen);
394676Sizick break;
395676Sizick
3960Sstevel@tonic-gate default:
3970Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate
4000Sstevel@tonic-gate return (CKR_OK);
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate
4040Sstevel@tonic-gate /*
4050Sstevel@tonic-gate * soft_digest_final()
4060Sstevel@tonic-gate *
4070Sstevel@tonic-gate * Arguments:
4080Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
4090Sstevel@tonic-gate * pDigest: pointer to the output data after digesting
4100Sstevel@tonic-gate * pulDigestLen: length of the output data
4110Sstevel@tonic-gate *
4120Sstevel@tonic-gate * Description:
4130Sstevel@tonic-gate * called by C_DigestFinal(). This function calls soft_digest_common().
4140Sstevel@tonic-gate *
4150Sstevel@tonic-gate * Returns:
4160Sstevel@tonic-gate * see return values in soft_digest_common().
4170Sstevel@tonic-gate */
4180Sstevel@tonic-gate CK_RV
soft_digest_final(soft_session_t * session_p,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)4190Sstevel@tonic-gate soft_digest_final(soft_session_t *session_p, CK_BYTE_PTR pDigest,
4200Sstevel@tonic-gate CK_ULONG_PTR pulDigestLen)
4210Sstevel@tonic-gate {
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate return (soft_digest_common(session_p, NULL, 0,
4240Sstevel@tonic-gate pDigest, pulDigestLen));
4250Sstevel@tonic-gate }
4260Sstevel@tonic-gate
4270Sstevel@tonic-gate /*
4280Sstevel@tonic-gate * Perform digest init operation internally for the support of
4290Sstevel@tonic-gate * CKM_MD5_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_SHA1_KEY_DERIVATION
4300Sstevel@tonic-gate * and CKM_MD5_KEY_DERIVATION mechanisms.
4310Sstevel@tonic-gate *
4320Sstevel@tonic-gate * This function is called with the session being held, and without
4330Sstevel@tonic-gate * its mutex taken.
4340Sstevel@tonic-gate */
4350Sstevel@tonic-gate CK_RV
soft_digest_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism)4360Sstevel@tonic-gate soft_digest_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
4370Sstevel@tonic-gate pMechanism)
4380Sstevel@tonic-gate {
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate CK_RV rv;
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
4430Sstevel@tonic-gate
4440Sstevel@tonic-gate /* Check to see if digest operation is already active */
4450Sstevel@tonic-gate if (session_p->digest.flags & CRYPTO_OPERATION_ACTIVE) {
4460Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
4470Sstevel@tonic-gate return (CKR_OPERATION_ACTIVE);
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate session_p->digest.flags = CRYPTO_OPERATION_ACTIVE;
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
4530Sstevel@tonic-gate
4540Sstevel@tonic-gate rv = soft_digest_init(session_p, pMechanism);
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate if (rv != CKR_OK) {
4570Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
4580Sstevel@tonic-gate session_p->digest.flags &= ~CRYPTO_OPERATION_ACTIVE;
4590Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
4600Sstevel@tonic-gate }
4610Sstevel@tonic-gate
4620Sstevel@tonic-gate return (rv);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate /*
4660Sstevel@tonic-gate * Call soft_digest_update() function with the value of a secret key.
4670Sstevel@tonic-gate */
4680Sstevel@tonic-gate CK_RV
soft_digest_key(soft_session_t * session_p,soft_object_t * key_p)4690Sstevel@tonic-gate soft_digest_key(soft_session_t *session_p, soft_object_t *key_p)
4700Sstevel@tonic-gate {
4710Sstevel@tonic-gate
4720Sstevel@tonic-gate CK_RV rv;
4730Sstevel@tonic-gate
4740Sstevel@tonic-gate /* Only secret key is allowed to be digested */
4750Sstevel@tonic-gate if (key_p->class != CKO_SECRET_KEY)
4760Sstevel@tonic-gate return (CKR_KEY_INDIGESTIBLE);
4770Sstevel@tonic-gate
4780Sstevel@tonic-gate if ((OBJ_SEC_VALUE(key_p) == NULL) ||
4790Sstevel@tonic-gate (OBJ_SEC_VALUE_LEN(key_p) == 0))
4800Sstevel@tonic-gate return (CKR_KEY_SIZE_RANGE);
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate rv = soft_digest_update(session_p, OBJ_SEC_VALUE(key_p),
4830Sstevel@tonic-gate OBJ_SEC_VALUE_LEN(key_p));
4840Sstevel@tonic-gate
4850Sstevel@tonic-gate return (rv);
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate }
488*7690SAlexandr.Nedvedicky@Sun.COM
489*7690SAlexandr.Nedvedicky@Sun.COM /*
490*7690SAlexandr.Nedvedicky@Sun.COM * This function releases allocated digest context. The caller
491*7690SAlexandr.Nedvedicky@Sun.COM * may (lock_held == B_TRUE) or may not (lock_held == B_FALSE)
492*7690SAlexandr.Nedvedicky@Sun.COM * hold a session mutex.
493*7690SAlexandr.Nedvedicky@Sun.COM */
494*7690SAlexandr.Nedvedicky@Sun.COM void
soft_digest_cleanup(soft_session_t * session_p,boolean_t lock_held)495*7690SAlexandr.Nedvedicky@Sun.COM soft_digest_cleanup(soft_session_t *session_p, boolean_t lock_held)
496*7690SAlexandr.Nedvedicky@Sun.COM {
497*7690SAlexandr.Nedvedicky@Sun.COM boolean_t lock_true = B_TRUE;
498*7690SAlexandr.Nedvedicky@Sun.COM
499*7690SAlexandr.Nedvedicky@Sun.COM if (!lock_held)
500*7690SAlexandr.Nedvedicky@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
501*7690SAlexandr.Nedvedicky@Sun.COM
502*7690SAlexandr.Nedvedicky@Sun.COM if (session_p->digest.context != NULL) {
503*7690SAlexandr.Nedvedicky@Sun.COM free(session_p->digest.context);
504*7690SAlexandr.Nedvedicky@Sun.COM session_p->digest.context = NULL;
505*7690SAlexandr.Nedvedicky@Sun.COM }
506*7690SAlexandr.Nedvedicky@Sun.COM
507*7690SAlexandr.Nedvedicky@Sun.COM session_p->digest.flags = 0;
508*7690SAlexandr.Nedvedicky@Sun.COM
509*7690SAlexandr.Nedvedicky@Sun.COM if (!lock_held)
510*7690SAlexandr.Nedvedicky@Sun.COM SES_REFRELE(session_p, lock_true);
511*7690SAlexandr.Nedvedicky@Sun.COM
512*7690SAlexandr.Nedvedicky@Sun.COM }
513