xref: /titanic_52/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDigestUtil.c (revision 588a1af05d98e04562709dbfc4827a5f46f8f2fd)
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
5*588a1af0SAlexandr Nedvedicky  * Common Development and Distribution License (the "License").
6*588a1af0SAlexandr Nedvedicky  * 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  */
217c478bd9Sstevel@tonic-gate /*
22*588a1af0SAlexandr Nedvedicky  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <strings.h>
277c478bd9Sstevel@tonic-gate #include <md5.h>
287c478bd9Sstevel@tonic-gate #include <pthread.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <sys/sha1.h>
31f66d273dSizick #include <sys/sha2.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
347c478bd9Sstevel@tonic-gate #include "softGlobal.h"
357c478bd9Sstevel@tonic-gate #include "softOps.h"
367c478bd9Sstevel@tonic-gate #include "softSession.h"
377c478bd9Sstevel@tonic-gate #include "softObject.h"
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * soft_digest_init()
427c478bd9Sstevel@tonic-gate  *
437c478bd9Sstevel@tonic-gate  * Arguments:
447c478bd9Sstevel@tonic-gate  *	session_p:	pointer to soft_session_t struct
457c478bd9Sstevel@tonic-gate  *	pMechanism:	pointer to CK_MECHANISM struct provided by application
467c478bd9Sstevel@tonic-gate  *
477c478bd9Sstevel@tonic-gate  * Description:
487c478bd9Sstevel@tonic-gate  *	called by C_DigestInit(). This function allocates space for
497c478bd9Sstevel@tonic-gate  *  	context, then calls the corresponding software provided digest
507c478bd9Sstevel@tonic-gate  *	init routine based on the mechanism.
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  * Returns:
537c478bd9Sstevel@tonic-gate  *	CKR_OK: success
547c478bd9Sstevel@tonic-gate  *	CKR_HOST_MEMORY: run out of system memory
557c478bd9Sstevel@tonic-gate  *	CKR_MECHANISM_INVALID: invalid mechanism type
567c478bd9Sstevel@tonic-gate  */
577c478bd9Sstevel@tonic-gate CK_RV
587c478bd9Sstevel@tonic-gate soft_digest_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism)
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate 	switch (pMechanism->mechanism) {
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate 	case CKM_MD5:
647c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate 		session_p->digest.context = malloc(sizeof (MD5_CTX));
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 		if (session_p->digest.context == NULL) {
697c478bd9Sstevel@tonic-gate 			(void) pthread_mutex_unlock(&session_p->session_mutex);
707c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
717c478bd9Sstevel@tonic-gate 		}
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 		session_p->digest.mech.mechanism = CKM_MD5;
747c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 		MD5Init((MD5_CTX *)session_p->digest.context);
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 		break;
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 		session_p->digest.context = malloc(sizeof (SHA1_CTX));
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 		if (session_p->digest.context == NULL) {
877c478bd9Sstevel@tonic-gate 			(void) pthread_mutex_unlock(&session_p->session_mutex);
887c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
897c478bd9Sstevel@tonic-gate 		}
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 		session_p->digest.mech.mechanism = CKM_SHA_1;
9260722cc8Sizick 		session_p->digest.mech.pParameter = pMechanism->pParameter;
9360722cc8Sizick 		session_p->digest.mech.ulParameterLen =
9460722cc8Sizick 		    pMechanism->ulParameterLen;
957c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 		SHA1Init((SHA1_CTX *)session_p->digest.context);
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 		break;
1007c478bd9Sstevel@tonic-gate 
101f66d273dSizick 	case CKM_SHA256:
102f66d273dSizick 	case CKM_SHA384:
103f66d273dSizick 	case CKM_SHA512:
104f66d273dSizick 
105f66d273dSizick 		(void) pthread_mutex_lock(&session_p->session_mutex);
106f66d273dSizick 
107f66d273dSizick 		session_p->digest.context = malloc(sizeof (SHA2_CTX));
108f66d273dSizick 
109f66d273dSizick 		if (session_p->digest.context == NULL) {
110f66d273dSizick 			(void) pthread_mutex_unlock(&session_p->session_mutex);
111f66d273dSizick 			return (CKR_HOST_MEMORY);
112f66d273dSizick 		}
113f66d273dSizick 
114f66d273dSizick 		switch (pMechanism->mechanism) {
115f66d273dSizick 		case CKM_SHA256:
116f66d273dSizick 			session_p->digest.mech.mechanism = CKM_SHA256;
117f66d273dSizick 			(void) pthread_mutex_unlock(&session_p->session_mutex);
118f66d273dSizick 			SHA2Init(SHA256,
119f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
120f66d273dSizick 			break;
121f66d273dSizick 
122f66d273dSizick 		case CKM_SHA384:
123f66d273dSizick 			session_p->digest.mech.mechanism = CKM_SHA384;
124f66d273dSizick 			(void) pthread_mutex_unlock(&session_p->session_mutex);
125f66d273dSizick 			SHA2Init(SHA384,
126f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
127f66d273dSizick 			break;
128f66d273dSizick 
129f66d273dSizick 		case CKM_SHA512:
130f66d273dSizick 			session_p->digest.mech.mechanism = CKM_SHA512;
131f66d273dSizick 			(void) pthread_mutex_unlock(&session_p->session_mutex);
132f66d273dSizick 			SHA2Init(SHA512,
133f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
134f66d273dSizick 			break;
135f66d273dSizick 		}
136f66d273dSizick 		break;
137f66d273dSizick 
1387c478bd9Sstevel@tonic-gate 	default:
1397c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
1407c478bd9Sstevel@tonic-gate 	}
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	return (CKR_OK);
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate /*
1477c478bd9Sstevel@tonic-gate  * soft_digest_common()
1487c478bd9Sstevel@tonic-gate  *
1497c478bd9Sstevel@tonic-gate  * Arguments:
1507c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
1517c478bd9Sstevel@tonic-gate  *	pData:		pointer to the input data to be digested
1527c478bd9Sstevel@tonic-gate  *	ulDataLen:	length of the input data
1537c478bd9Sstevel@tonic-gate  *	pDigest:	pointer to the output data after digesting
1547c478bd9Sstevel@tonic-gate  *	pulDigestLen:	length of the output data
1557c478bd9Sstevel@tonic-gate  *
1567c478bd9Sstevel@tonic-gate  * Description:
1577c478bd9Sstevel@tonic-gate  *      called by soft_digest() or soft_digest_final(). This function
1587c478bd9Sstevel@tonic-gate  *      determines the length of output buffer and calls the corresponding
1597c478bd9Sstevel@tonic-gate  *	software provided digest routine based on the mechanism.
1607c478bd9Sstevel@tonic-gate  *
1617c478bd9Sstevel@tonic-gate  * Returns:
1627c478bd9Sstevel@tonic-gate  *      CKR_OK: success
1637c478bd9Sstevel@tonic-gate  *      CKR_MECHANISM_INVALID: invalid mechanism type
1647c478bd9Sstevel@tonic-gate  *      CKR_BUFFER_TOO_SMALL: the output buffer provided by application
1657c478bd9Sstevel@tonic-gate  *			      is too small
1667c478bd9Sstevel@tonic-gate  */
1677c478bd9Sstevel@tonic-gate CK_RV
1687c478bd9Sstevel@tonic-gate soft_digest_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1697c478bd9Sstevel@tonic-gate 	CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
1707c478bd9Sstevel@tonic-gate {
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	CK_ULONG digestLen = 0;
1737c478bd9Sstevel@tonic-gate 	size_t len = 0;
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	/*
1767c478bd9Sstevel@tonic-gate 	 * Determine the output data length based on the mechanism
1777c478bd9Sstevel@tonic-gate 	 */
1787c478bd9Sstevel@tonic-gate 	switch (session_p->digest.mech.mechanism) {
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	case CKM_MD5:
1817c478bd9Sstevel@tonic-gate 		digestLen = 16;
1827c478bd9Sstevel@tonic-gate 		break;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
1857c478bd9Sstevel@tonic-gate 		digestLen = 20;
1867c478bd9Sstevel@tonic-gate 		break;
1877c478bd9Sstevel@tonic-gate 
188f66d273dSizick 	case CKM_SHA256:
189f66d273dSizick 		digestLen = 32;
190f66d273dSizick 		break;
191f66d273dSizick 
192f66d273dSizick 	case CKM_SHA384:
193f66d273dSizick 		digestLen = 48;
194f66d273dSizick 		break;
195f66d273dSizick 
196f66d273dSizick 	case CKM_SHA512:
197f66d273dSizick 		digestLen = 64;
198f66d273dSizick 		break;
199f66d273dSizick 
2007c478bd9Sstevel@tonic-gate 	default:
2017c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
2027c478bd9Sstevel@tonic-gate 	}
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	if (pDigest == NULL) {
2057c478bd9Sstevel@tonic-gate 		/*
2067c478bd9Sstevel@tonic-gate 		 * Application only wants to know the length of the
2077c478bd9Sstevel@tonic-gate 		 * buffer needed to hold the message digest.
2087c478bd9Sstevel@tonic-gate 		 */
2097c478bd9Sstevel@tonic-gate 		*pulDigestLen = digestLen;
2107c478bd9Sstevel@tonic-gate 		return (CKR_OK);
2117c478bd9Sstevel@tonic-gate 	}
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	if (*pulDigestLen < digestLen) {
2147c478bd9Sstevel@tonic-gate 		/*
2157c478bd9Sstevel@tonic-gate 		 * Application provides buffer too small to hold the
2167c478bd9Sstevel@tonic-gate 		 * digest message. Return the length of buffer needed
2177c478bd9Sstevel@tonic-gate 		 * to the application.
2187c478bd9Sstevel@tonic-gate 		 */
2197c478bd9Sstevel@tonic-gate 		*pulDigestLen = digestLen;
2207c478bd9Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
2217c478bd9Sstevel@tonic-gate 	}
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	/*
2247c478bd9Sstevel@tonic-gate 	 * Call the corresponding system provided software digest routine.
2257c478bd9Sstevel@tonic-gate 	 * If the soft_digest_common() is called by soft_digest_final()
2267c478bd9Sstevel@tonic-gate 	 * the pData is NULL, and the ulDataLen is zero.
2277c478bd9Sstevel@tonic-gate 	 */
2287c478bd9Sstevel@tonic-gate 	switch (session_p->digest.mech.mechanism) {
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	case CKM_MD5:
2317c478bd9Sstevel@tonic-gate 		if (pData != NULL) {
2327c478bd9Sstevel@tonic-gate 			/*
2337c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest()
2347c478bd9Sstevel@tonic-gate 			 */
2357c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
2367c478bd9Sstevel@tonic-gate 			MD5Update((MD5_CTX *)session_p->digest.context,
2377c478bd9Sstevel@tonic-gate 			    /* LINTED */
2387c478bd9Sstevel@tonic-gate 			    pData, (uint_t)ulDataLen);
2397c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
2407c478bd9Sstevel@tonic-gate 			MD5Update((MD5_CTX *)session_p->digest.context,
2417c478bd9Sstevel@tonic-gate 			    pData, ulDataLen);
2427c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
2437c478bd9Sstevel@tonic-gate 			MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
2447c478bd9Sstevel@tonic-gate 		} else {
2457c478bd9Sstevel@tonic-gate 			/*
2467c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest_final()
2477c478bd9Sstevel@tonic-gate 			 */
2487c478bd9Sstevel@tonic-gate 			MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
2497c478bd9Sstevel@tonic-gate 			len = sizeof (MD5_CTX);
2507c478bd9Sstevel@tonic-gate 		}
2517c478bd9Sstevel@tonic-gate 		break;
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
2547c478bd9Sstevel@tonic-gate 		if (pData != NULL) {
2557c478bd9Sstevel@tonic-gate 			/*
2567c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest()
2577c478bd9Sstevel@tonic-gate 			 */
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
2607c478bd9Sstevel@tonic-gate 			SHA1Update((SHA1_CTX *)session_p->digest.context,
2617c478bd9Sstevel@tonic-gate 			    /* LINTED */
2627c478bd9Sstevel@tonic-gate 			    pData, (uint32_t)ulDataLen);
2637c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
2647c478bd9Sstevel@tonic-gate 			SHA1Update((SHA1_CTX *)session_p->digest.context,
2657c478bd9Sstevel@tonic-gate 			    pData, ulDataLen);
2667c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
2677c478bd9Sstevel@tonic-gate 			SHA1Final(pDigest,
2687c478bd9Sstevel@tonic-gate 			    (SHA1_CTX *)session_p->digest.context);
2697c478bd9Sstevel@tonic-gate 		} else {
2707c478bd9Sstevel@tonic-gate 			/*
2717c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest_final()
2727c478bd9Sstevel@tonic-gate 			 */
2737c478bd9Sstevel@tonic-gate 			SHA1Final(pDigest,
2747c478bd9Sstevel@tonic-gate 			    (SHA1_CTX *)session_p->digest.context);
2757c478bd9Sstevel@tonic-gate 			len = sizeof (SHA1_CTX);
2767c478bd9Sstevel@tonic-gate 		}
2777c478bd9Sstevel@tonic-gate 		break;
278f66d273dSizick 	case CKM_SHA256:
279f66d273dSizick 	case CKM_SHA384:
280f66d273dSizick 	case CKM_SHA512:
281f66d273dSizick 		if (pData != NULL) {
282f66d273dSizick 			/*
283f66d273dSizick 			 * this is called by soft_digest()
284f66d273dSizick 			 */
285f66d273dSizick 
286f66d273dSizick 			SHA2Update((SHA2_CTX *)session_p->digest.context,
287f66d273dSizick 			    pData, ulDataLen);
288f66d273dSizick 
289f66d273dSizick 			SHA2Final(pDigest,
290f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
291f66d273dSizick 		} else {
292f66d273dSizick 			/*
293f66d273dSizick 			 * this is called by soft_digest_final()
294f66d273dSizick 			 */
295f66d273dSizick 			SHA2Final(pDigest,
296f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
297f66d273dSizick 			len = sizeof (SHA2_CTX);
298f66d273dSizick 		}
299f66d273dSizick 
300f66d273dSizick 		break;
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	/* Paranoia on behalf of C_DigestKey callers: bzero the context */
3047c478bd9Sstevel@tonic-gate 	if (session_p->digest.flags & CRYPTO_KEY_DIGESTED) {
3057c478bd9Sstevel@tonic-gate 		bzero(session_p->digest.context, len);
3067c478bd9Sstevel@tonic-gate 		session_p->digest.flags &= ~CRYPTO_KEY_DIGESTED;
3077c478bd9Sstevel@tonic-gate 	}
3087c478bd9Sstevel@tonic-gate 	*pulDigestLen = digestLen;
3097c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
3107c478bd9Sstevel@tonic-gate 	free(session_p->digest.context);
3117c478bd9Sstevel@tonic-gate 	session_p->digest.context = NULL;
3127c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 	return (CKR_OK);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate /*
3197c478bd9Sstevel@tonic-gate  * soft_digest()
3207c478bd9Sstevel@tonic-gate  *
3217c478bd9Sstevel@tonic-gate  * Arguments:
3227c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
3237c478bd9Sstevel@tonic-gate  *      pData:		pointer to the input data to be digested
3247c478bd9Sstevel@tonic-gate  *      ulDataLen:	length of the input data
3257c478bd9Sstevel@tonic-gate  *      pDigest:	pointer to the output data after digesting
3267c478bd9Sstevel@tonic-gate  *      pulDigestLen:	length of the output data
3277c478bd9Sstevel@tonic-gate  *
3287c478bd9Sstevel@tonic-gate  * Description:
3297c478bd9Sstevel@tonic-gate  *      called by C_Digest(). This function calls soft_digest_common().
3307c478bd9Sstevel@tonic-gate  *
3317c478bd9Sstevel@tonic-gate  * Returns:
3327c478bd9Sstevel@tonic-gate  *      see return values in soft_digest_common().
3337c478bd9Sstevel@tonic-gate  */
3347c478bd9Sstevel@tonic-gate CK_RV
3357c478bd9Sstevel@tonic-gate soft_digest(soft_session_t *session_p, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
3367c478bd9Sstevel@tonic-gate 	CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	return (soft_digest_common(session_p, pData, ulDataLen,
3407c478bd9Sstevel@tonic-gate 	    pDigest, pulDigestLen));
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate /*
3457c478bd9Sstevel@tonic-gate  * soft_digest_update()
3467c478bd9Sstevel@tonic-gate  *
3477c478bd9Sstevel@tonic-gate  * Arguments:
3487c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
3497c478bd9Sstevel@tonic-gate  *      pPart:		pointer to the input data to be digested
3507c478bd9Sstevel@tonic-gate  *      ulPartLen:	length of the input data
3517c478bd9Sstevel@tonic-gate  *
3527c478bd9Sstevel@tonic-gate  * Description:
3537c478bd9Sstevel@tonic-gate  *      called by C_DigestUpdate(). This function calls the corresponding
3547c478bd9Sstevel@tonic-gate  *	software provided digest update routine based on the mechanism.
3557c478bd9Sstevel@tonic-gate  *
3567c478bd9Sstevel@tonic-gate  * Returns:
3577c478bd9Sstevel@tonic-gate  *      CKR_OK: success
3587c478bd9Sstevel@tonic-gate  *      CKR_MECHANISM_INVALID: invalid MECHANISM type.
3597c478bd9Sstevel@tonic-gate  */
3607c478bd9Sstevel@tonic-gate CK_RV
3617c478bd9Sstevel@tonic-gate soft_digest_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
3627c478bd9Sstevel@tonic-gate 	CK_ULONG ulPartLen)
3637c478bd9Sstevel@tonic-gate {
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 	switch (session_p->digest.mech.mechanism) {
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	case CKM_MD5:
3687c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
3697c478bd9Sstevel@tonic-gate 		MD5Update((MD5_CTX *)session_p->digest.context,
3707c478bd9Sstevel@tonic-gate 		    /* LINTED */
3717c478bd9Sstevel@tonic-gate 		    pPart, (uint_t)ulPartLen);
3727c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
3737c478bd9Sstevel@tonic-gate 		MD5Update((MD5_CTX *)session_p->digest.context,
3747c478bd9Sstevel@tonic-gate 		    pPart, ulPartLen);
3757c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
3767c478bd9Sstevel@tonic-gate 		break;
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
3797c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
3807c478bd9Sstevel@tonic-gate 		SHA1Update((SHA1_CTX *)session_p->digest.context,
3817c478bd9Sstevel@tonic-gate 		    /* LINTED */
3827c478bd9Sstevel@tonic-gate 		    pPart, (uint32_t)ulPartLen);
3837c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
3847c478bd9Sstevel@tonic-gate 		SHA1Update((SHA1_CTX *)session_p->digest.context,
3857c478bd9Sstevel@tonic-gate 		    pPart, ulPartLen);
3867c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
3877c478bd9Sstevel@tonic-gate 		break;
3887c478bd9Sstevel@tonic-gate 
389f66d273dSizick 	case CKM_SHA256:
390f66d273dSizick 	case CKM_SHA384:
391f66d273dSizick 	case CKM_SHA512:
392f66d273dSizick 		SHA2Update((SHA2_CTX *)session_p->digest.context,
393f66d273dSizick 		    pPart, ulPartLen);
394f66d273dSizick 		break;
395f66d273dSizick 
3967c478bd9Sstevel@tonic-gate 	default:
3977c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
3987c478bd9Sstevel@tonic-gate 	}
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	return (CKR_OK);
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate /*
4057c478bd9Sstevel@tonic-gate  * soft_digest_final()
4067c478bd9Sstevel@tonic-gate  *
4077c478bd9Sstevel@tonic-gate  * Arguments:
4087c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
4097c478bd9Sstevel@tonic-gate  *      pDigest:	pointer to the output data after digesting
4107c478bd9Sstevel@tonic-gate  *      pulDigestLen:	length of the output data
4117c478bd9Sstevel@tonic-gate  *
4127c478bd9Sstevel@tonic-gate  * Description:
4137c478bd9Sstevel@tonic-gate  *      called by C_DigestFinal(). This function calls soft_digest_common().
4147c478bd9Sstevel@tonic-gate  *
4157c478bd9Sstevel@tonic-gate  * Returns:
4167c478bd9Sstevel@tonic-gate  *	see return values in soft_digest_common().
4177c478bd9Sstevel@tonic-gate  */
4187c478bd9Sstevel@tonic-gate CK_RV
4197c478bd9Sstevel@tonic-gate soft_digest_final(soft_session_t *session_p, CK_BYTE_PTR pDigest,
4207c478bd9Sstevel@tonic-gate 	CK_ULONG_PTR pulDigestLen)
4217c478bd9Sstevel@tonic-gate {
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 	return (soft_digest_common(session_p, NULL, 0,
4247c478bd9Sstevel@tonic-gate 	    pDigest, pulDigestLen));
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate /*
4287c478bd9Sstevel@tonic-gate  * Perform digest init operation internally for the support of
4297c478bd9Sstevel@tonic-gate  * CKM_MD5_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_SHA1_KEY_DERIVATION
4307c478bd9Sstevel@tonic-gate  * and CKM_MD5_KEY_DERIVATION mechanisms.
4317c478bd9Sstevel@tonic-gate  *
4327c478bd9Sstevel@tonic-gate  * This function is called with the session being held, and without
4337c478bd9Sstevel@tonic-gate  * its mutex taken.
4347c478bd9Sstevel@tonic-gate  */
4357c478bd9Sstevel@tonic-gate CK_RV
4367c478bd9Sstevel@tonic-gate soft_digest_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
4377c478bd9Sstevel@tonic-gate 	pMechanism)
4387c478bd9Sstevel@tonic-gate {
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 	CK_RV rv;
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 	/* Check to see if digest operation is already active */
4457c478bd9Sstevel@tonic-gate 	if (session_p->digest.flags & CRYPTO_OPERATION_ACTIVE) {
4467c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
4477c478bd9Sstevel@tonic-gate 		return (CKR_OPERATION_ACTIVE);
4487c478bd9Sstevel@tonic-gate 	}
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 	session_p->digest.flags = CRYPTO_OPERATION_ACTIVE;
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 	rv = soft_digest_init(session_p, pMechanism);
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
4577c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
4587c478bd9Sstevel@tonic-gate 		session_p->digest.flags &= ~CRYPTO_OPERATION_ACTIVE;
4597c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
4607c478bd9Sstevel@tonic-gate 	}
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 	return (rv);
4637c478bd9Sstevel@tonic-gate }
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate /*
4667c478bd9Sstevel@tonic-gate  * Call soft_digest_update() function with the value of a secret key.
4677c478bd9Sstevel@tonic-gate  */
4687c478bd9Sstevel@tonic-gate CK_RV
4697c478bd9Sstevel@tonic-gate soft_digest_key(soft_session_t *session_p, soft_object_t *key_p)
4707c478bd9Sstevel@tonic-gate {
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	CK_RV rv;
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	/* Only secret key is allowed to be digested */
4757c478bd9Sstevel@tonic-gate 	if (key_p->class != CKO_SECRET_KEY)
4767c478bd9Sstevel@tonic-gate 		return (CKR_KEY_INDIGESTIBLE);
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	if ((OBJ_SEC_VALUE(key_p) == NULL) ||
4797c478bd9Sstevel@tonic-gate 	    (OBJ_SEC_VALUE_LEN(key_p) == 0))
4807c478bd9Sstevel@tonic-gate 		return (CKR_KEY_SIZE_RANGE);
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 	rv = soft_digest_update(session_p, OBJ_SEC_VALUE(key_p),
4837c478bd9Sstevel@tonic-gate 	    OBJ_SEC_VALUE_LEN(key_p));
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate 	return (rv);
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate }
488*588a1af0SAlexandr Nedvedicky 
489*588a1af0SAlexandr Nedvedicky /*
490*588a1af0SAlexandr Nedvedicky  * This function releases allocated digest context. The caller
491*588a1af0SAlexandr Nedvedicky  * may (lock_held == B_TRUE) or may not (lock_held == B_FALSE)
492*588a1af0SAlexandr Nedvedicky  * hold a session mutex.
493*588a1af0SAlexandr Nedvedicky  */
494*588a1af0SAlexandr Nedvedicky void
495*588a1af0SAlexandr Nedvedicky soft_digest_cleanup(soft_session_t *session_p, boolean_t lock_held)
496*588a1af0SAlexandr Nedvedicky {
497*588a1af0SAlexandr Nedvedicky 	boolean_t lock_true = B_TRUE;
498*588a1af0SAlexandr Nedvedicky 
499*588a1af0SAlexandr Nedvedicky 	if (!lock_held)
500*588a1af0SAlexandr Nedvedicky 		(void) pthread_mutex_lock(&session_p->session_mutex);
501*588a1af0SAlexandr Nedvedicky 
502*588a1af0SAlexandr Nedvedicky 	if (session_p->digest.context != NULL) {
503*588a1af0SAlexandr Nedvedicky 		free(session_p->digest.context);
504*588a1af0SAlexandr Nedvedicky 		session_p->digest.context = NULL;
505*588a1af0SAlexandr Nedvedicky 	}
506*588a1af0SAlexandr Nedvedicky 
507*588a1af0SAlexandr Nedvedicky 	session_p->digest.flags = 0;
508*588a1af0SAlexandr Nedvedicky 
509*588a1af0SAlexandr Nedvedicky 	if (!lock_held)
510*588a1af0SAlexandr Nedvedicky 		SES_REFRELE(session_p, lock_true);
511*588a1af0SAlexandr Nedvedicky 
512*588a1af0SAlexandr Nedvedicky }
513