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
5588a1af0SAlexandr Nedvedicky  * Common Development and Distribution License (the "License").
6588a1af0SAlexandr 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 /*
22588a1af0SAlexandr Nedvedicky  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24a8793c76SJason King  * Copyright (c) 2018, Joyent, Inc.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <strings.h>
287c478bd9Sstevel@tonic-gate #include <md5.h>
297c478bd9Sstevel@tonic-gate #include <pthread.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <sys/sha1.h>
32f66d273dSizick #include <sys/sha2.h>
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
357c478bd9Sstevel@tonic-gate #include "softGlobal.h"
367c478bd9Sstevel@tonic-gate #include "softOps.h"
377c478bd9Sstevel@tonic-gate #include "softSession.h"
387c478bd9Sstevel@tonic-gate #include "softObject.h"
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * soft_digest_init()
437c478bd9Sstevel@tonic-gate  *
447c478bd9Sstevel@tonic-gate  * Arguments:
457c478bd9Sstevel@tonic-gate  *	session_p:	pointer to soft_session_t struct
467c478bd9Sstevel@tonic-gate  *	pMechanism:	pointer to CK_MECHANISM struct provided by application
477c478bd9Sstevel@tonic-gate  *
487c478bd9Sstevel@tonic-gate  * Description:
497c478bd9Sstevel@tonic-gate  *	called by C_DigestInit(). This function allocates space for
50a8793c76SJason King  *	context, then calls the corresponding software provided digest
517c478bd9Sstevel@tonic-gate  *	init routine based on the mechanism.
527c478bd9Sstevel@tonic-gate  *
537c478bd9Sstevel@tonic-gate  * Returns:
547c478bd9Sstevel@tonic-gate  *	CKR_OK: success
557c478bd9Sstevel@tonic-gate  *	CKR_HOST_MEMORY: run out of system memory
567c478bd9Sstevel@tonic-gate  *	CKR_MECHANISM_INVALID: invalid mechanism type
577c478bd9Sstevel@tonic-gate  */
587c478bd9Sstevel@tonic-gate CK_RV
soft_digest_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism)597c478bd9Sstevel@tonic-gate soft_digest_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism)
607c478bd9Sstevel@tonic-gate {
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	switch (pMechanism->mechanism) {
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	case CKM_MD5:
657c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 		session_p->digest.context = malloc(sizeof (MD5_CTX));
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate 		if (session_p->digest.context == NULL) {
707c478bd9Sstevel@tonic-gate 			(void) pthread_mutex_unlock(&session_p->session_mutex);
717c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
727c478bd9Sstevel@tonic-gate 		}
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 		session_p->digest.mech.mechanism = CKM_MD5;
757c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 		MD5Init((MD5_CTX *)session_p->digest.context);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 		break;
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 		session_p->digest.context = malloc(sizeof (SHA1_CTX));
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 		if (session_p->digest.context == NULL) {
887c478bd9Sstevel@tonic-gate 			(void) pthread_mutex_unlock(&session_p->session_mutex);
897c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
907c478bd9Sstevel@tonic-gate 		}
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 		session_p->digest.mech.mechanism = CKM_SHA_1;
9360722cc8Sizick 		session_p->digest.mech.pParameter = pMechanism->pParameter;
9460722cc8Sizick 		session_p->digest.mech.ulParameterLen =
9560722cc8Sizick 		    pMechanism->ulParameterLen;
967c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 		SHA1Init((SHA1_CTX *)session_p->digest.context);
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 		break;
1017c478bd9Sstevel@tonic-gate 
102f66d273dSizick 	case CKM_SHA256:
103f66d273dSizick 	case CKM_SHA384:
104f66d273dSizick 	case CKM_SHA512:
105*05204290SJason King 	case CKM_SHA512_224:
106*05204290SJason King 	case CKM_SHA512_256:
107f66d273dSizick 
108f66d273dSizick 		(void) pthread_mutex_lock(&session_p->session_mutex);
109f66d273dSizick 
110f66d273dSizick 		session_p->digest.context = malloc(sizeof (SHA2_CTX));
111f66d273dSizick 
112f66d273dSizick 		if (session_p->digest.context == NULL) {
113f66d273dSizick 			(void) pthread_mutex_unlock(&session_p->session_mutex);
114f66d273dSizick 			return (CKR_HOST_MEMORY);
115f66d273dSizick 		}
116f66d273dSizick 
117*05204290SJason King 		session_p->digest.mech.mechanism = pMechanism->mechanism;
118*05204290SJason King 		(void) pthread_mutex_unlock(&session_p->session_mutex);
119*05204290SJason King 
120f66d273dSizick 		switch (pMechanism->mechanism) {
121f66d273dSizick 		case CKM_SHA256:
122f66d273dSizick 			SHA2Init(SHA256,
123f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
124f66d273dSizick 			break;
125f66d273dSizick 
126f66d273dSizick 		case CKM_SHA384:
127f66d273dSizick 			SHA2Init(SHA384,
128f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
129f66d273dSizick 			break;
130f66d273dSizick 
131f66d273dSizick 		case CKM_SHA512:
132f66d273dSizick 			SHA2Init(SHA512,
133f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
134f66d273dSizick 			break;
135*05204290SJason King 		case CKM_SHA512_224:
136*05204290SJason King 			SHA2Init(SHA512_224,
137*05204290SJason King 			    (SHA2_CTX *)session_p->digest.context);
138*05204290SJason King 			break;
139*05204290SJason King 		case CKM_SHA512_256:
140*05204290SJason King 			SHA2Init(SHA512_256,
141*05204290SJason King 			    (SHA2_CTX *)session_p->digest.context);
142*05204290SJason King 			break;
143f66d273dSizick 		}
144f66d273dSizick 		break;
145f66d273dSizick 
1467c478bd9Sstevel@tonic-gate 	default:
1477c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
1487c478bd9Sstevel@tonic-gate 	}
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	return (CKR_OK);
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate /*
1557c478bd9Sstevel@tonic-gate  * soft_digest_common()
1567c478bd9Sstevel@tonic-gate  *
1577c478bd9Sstevel@tonic-gate  * Arguments:
1587c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
1597c478bd9Sstevel@tonic-gate  *	pData:		pointer to the input data to be digested
1607c478bd9Sstevel@tonic-gate  *	ulDataLen:	length of the input data
1617c478bd9Sstevel@tonic-gate  *	pDigest:	pointer to the output data after digesting
1627c478bd9Sstevel@tonic-gate  *	pulDigestLen:	length of the output data
1637c478bd9Sstevel@tonic-gate  *
1647c478bd9Sstevel@tonic-gate  * Description:
1657c478bd9Sstevel@tonic-gate  *      called by soft_digest() or soft_digest_final(). This function
1667c478bd9Sstevel@tonic-gate  *      determines the length of output buffer and calls the corresponding
1677c478bd9Sstevel@tonic-gate  *	software provided digest routine based on the mechanism.
1687c478bd9Sstevel@tonic-gate  *
1697c478bd9Sstevel@tonic-gate  * Returns:
1707c478bd9Sstevel@tonic-gate  *      CKR_OK: success
1717c478bd9Sstevel@tonic-gate  *      CKR_MECHANISM_INVALID: invalid mechanism type
1727c478bd9Sstevel@tonic-gate  *      CKR_BUFFER_TOO_SMALL: the output buffer provided by application
1737c478bd9Sstevel@tonic-gate  *			      is too small
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@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)1767c478bd9Sstevel@tonic-gate soft_digest_common(soft_session_t *session_p, CK_BYTE_PTR pData,
177a8793c76SJason King     CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
1787c478bd9Sstevel@tonic-gate {
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	CK_ULONG digestLen = 0;
1817c478bd9Sstevel@tonic-gate 	size_t len = 0;
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	/*
1847c478bd9Sstevel@tonic-gate 	 * Determine the output data length based on the mechanism
1857c478bd9Sstevel@tonic-gate 	 */
1867c478bd9Sstevel@tonic-gate 	switch (session_p->digest.mech.mechanism) {
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	case CKM_MD5:
1897c478bd9Sstevel@tonic-gate 		digestLen = 16;
1907c478bd9Sstevel@tonic-gate 		break;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
193*05204290SJason King 		digestLen = SHA1_DIGEST_LENGTH;
1947c478bd9Sstevel@tonic-gate 		break;
1957c478bd9Sstevel@tonic-gate 
196f66d273dSizick 	case CKM_SHA256:
197*05204290SJason King 		digestLen = SHA256_DIGEST_LENGTH;
198f66d273dSizick 		break;
199f66d273dSizick 
200f66d273dSizick 	case CKM_SHA384:
201*05204290SJason King 		digestLen = SHA384_DIGEST_LENGTH;
202f66d273dSizick 		break;
203f66d273dSizick 
204f66d273dSizick 	case CKM_SHA512:
205*05204290SJason King 		digestLen = SHA512_DIGEST_LENGTH;
206*05204290SJason King 		break;
207*05204290SJason King 
208*05204290SJason King 	case CKM_SHA512_224:
209*05204290SJason King 		digestLen = SHA512_224_DIGEST_LENGTH;
210*05204290SJason King 		break;
211*05204290SJason King 
212*05204290SJason King 	case CKM_SHA512_256:
213*05204290SJason King 		digestLen = SHA512_256_DIGEST_LENGTH;
214f66d273dSizick 		break;
215f66d273dSizick 
2167c478bd9Sstevel@tonic-gate 	default:
2177c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
2187c478bd9Sstevel@tonic-gate 	}
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	if (pDigest == NULL) {
2217c478bd9Sstevel@tonic-gate 		/*
2227c478bd9Sstevel@tonic-gate 		 * Application only wants to know the length of the
2237c478bd9Sstevel@tonic-gate 		 * buffer needed to hold the message digest.
2247c478bd9Sstevel@tonic-gate 		 */
2257c478bd9Sstevel@tonic-gate 		*pulDigestLen = digestLen;
2267c478bd9Sstevel@tonic-gate 		return (CKR_OK);
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	if (*pulDigestLen < digestLen) {
2307c478bd9Sstevel@tonic-gate 		/*
2317c478bd9Sstevel@tonic-gate 		 * Application provides buffer too small to hold the
2327c478bd9Sstevel@tonic-gate 		 * digest message. Return the length of buffer needed
2337c478bd9Sstevel@tonic-gate 		 * to the application.
2347c478bd9Sstevel@tonic-gate 		 */
2357c478bd9Sstevel@tonic-gate 		*pulDigestLen = digestLen;
2367c478bd9Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
2377c478bd9Sstevel@tonic-gate 	}
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	/*
2407c478bd9Sstevel@tonic-gate 	 * Call the corresponding system provided software digest routine.
2417c478bd9Sstevel@tonic-gate 	 * If the soft_digest_common() is called by soft_digest_final()
2427c478bd9Sstevel@tonic-gate 	 * the pData is NULL, and the ulDataLen is zero.
2437c478bd9Sstevel@tonic-gate 	 */
2447c478bd9Sstevel@tonic-gate 	switch (session_p->digest.mech.mechanism) {
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate 	case CKM_MD5:
2477c478bd9Sstevel@tonic-gate 		if (pData != NULL) {
2487c478bd9Sstevel@tonic-gate 			/*
2497c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest()
2507c478bd9Sstevel@tonic-gate 			 */
2517c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
2527c478bd9Sstevel@tonic-gate 			MD5Update((MD5_CTX *)session_p->digest.context,
2537c478bd9Sstevel@tonic-gate 			    /* LINTED */
2547c478bd9Sstevel@tonic-gate 			    pData, (uint_t)ulDataLen);
2557c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
2567c478bd9Sstevel@tonic-gate 			MD5Update((MD5_CTX *)session_p->digest.context,
2577c478bd9Sstevel@tonic-gate 			    pData, ulDataLen);
2587c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
2597c478bd9Sstevel@tonic-gate 			MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
2607c478bd9Sstevel@tonic-gate 		} else {
2617c478bd9Sstevel@tonic-gate 			/*
2627c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest_final()
2637c478bd9Sstevel@tonic-gate 			 */
2647c478bd9Sstevel@tonic-gate 			MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
2657c478bd9Sstevel@tonic-gate 			len = sizeof (MD5_CTX);
2667c478bd9Sstevel@tonic-gate 		}
2677c478bd9Sstevel@tonic-gate 		break;
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
2707c478bd9Sstevel@tonic-gate 		if (pData != NULL) {
2717c478bd9Sstevel@tonic-gate 			/*
2727c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest()
2737c478bd9Sstevel@tonic-gate 			 */
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
2767c478bd9Sstevel@tonic-gate 			SHA1Update((SHA1_CTX *)session_p->digest.context,
2777c478bd9Sstevel@tonic-gate 			    /* LINTED */
2787c478bd9Sstevel@tonic-gate 			    pData, (uint32_t)ulDataLen);
2797c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
2807c478bd9Sstevel@tonic-gate 			SHA1Update((SHA1_CTX *)session_p->digest.context,
2817c478bd9Sstevel@tonic-gate 			    pData, ulDataLen);
2827c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
2837c478bd9Sstevel@tonic-gate 			SHA1Final(pDigest,
2847c478bd9Sstevel@tonic-gate 			    (SHA1_CTX *)session_p->digest.context);
2857c478bd9Sstevel@tonic-gate 		} else {
2867c478bd9Sstevel@tonic-gate 			/*
2877c478bd9Sstevel@tonic-gate 			 * this is called by soft_digest_final()
2887c478bd9Sstevel@tonic-gate 			 */
2897c478bd9Sstevel@tonic-gate 			SHA1Final(pDigest,
2907c478bd9Sstevel@tonic-gate 			    (SHA1_CTX *)session_p->digest.context);
2917c478bd9Sstevel@tonic-gate 			len = sizeof (SHA1_CTX);
2927c478bd9Sstevel@tonic-gate 		}
293f66d273dSizick 		break;
294f66d273dSizick 	case CKM_SHA256:
295f66d273dSizick 	case CKM_SHA384:
296f66d273dSizick 	case CKM_SHA512:
297*05204290SJason King 	case CKM_SHA512_224:
298*05204290SJason King 	case CKM_SHA512_256:
299f66d273dSizick 		if (pData != NULL) {
300f66d273dSizick 			/*
301f66d273dSizick 			 * this is called by soft_digest()
302f66d273dSizick 			 */
303f66d273dSizick 
304f66d273dSizick 			SHA2Update((SHA2_CTX *)session_p->digest.context,
305f66d273dSizick 			    pData, ulDataLen);
306f66d273dSizick 
307f66d273dSizick 			SHA2Final(pDigest,
308f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
309f66d273dSizick 		} else {
310f66d273dSizick 			/*
311f66d273dSizick 			 * this is called by soft_digest_final()
312f66d273dSizick 			 */
313f66d273dSizick 			SHA2Final(pDigest,
314f66d273dSizick 			    (SHA2_CTX *)session_p->digest.context);
315f66d273dSizick 			len = sizeof (SHA2_CTX);
316f66d273dSizick 		}
317f66d273dSizick 
3187c478bd9Sstevel@tonic-gate 		break;
3197c478bd9Sstevel@tonic-gate 	}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	/* Paranoia on behalf of C_DigestKey callers: bzero the context */
3227c478bd9Sstevel@tonic-gate 	if (session_p->digest.flags & CRYPTO_KEY_DIGESTED) {
323a8793c76SJason King 		explicit_bzero(session_p->digest.context, len);
3247c478bd9Sstevel@tonic-gate 		session_p->digest.flags &= ~CRYPTO_KEY_DIGESTED;
3257c478bd9Sstevel@tonic-gate 	}
3267c478bd9Sstevel@tonic-gate 	*pulDigestLen = digestLen;
3277c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
3287c478bd9Sstevel@tonic-gate 	free(session_p->digest.context);
3297c478bd9Sstevel@tonic-gate 	session_p->digest.context = NULL;
3307c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	return (CKR_OK);
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate /*
3377c478bd9Sstevel@tonic-gate  * soft_digest()
3387c478bd9Sstevel@tonic-gate  *
3397c478bd9Sstevel@tonic-gate  * Arguments:
3407c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
3417c478bd9Sstevel@tonic-gate  *      pData:		pointer to the input data to be digested
3427c478bd9Sstevel@tonic-gate  *      ulDataLen:	length of the input data
3437c478bd9Sstevel@tonic-gate  *      pDigest:	pointer to the output data after digesting
3447c478bd9Sstevel@tonic-gate  *      pulDigestLen:	length of the output data
3457c478bd9Sstevel@tonic-gate  *
3467c478bd9Sstevel@tonic-gate  * Description:
3477c478bd9Sstevel@tonic-gate  *      called by C_Digest(). This function calls soft_digest_common().
3487c478bd9Sstevel@tonic-gate  *
3497c478bd9Sstevel@tonic-gate  * Returns:
3507c478bd9Sstevel@tonic-gate  *      see return values in soft_digest_common().
3517c478bd9Sstevel@tonic-gate  */
3527c478bd9Sstevel@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)3537c478bd9Sstevel@tonic-gate soft_digest(soft_session_t *session_p, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
354a8793c76SJason King     CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
3557c478bd9Sstevel@tonic-gate {
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 	return (soft_digest_common(session_p, pData, ulDataLen,
3587c478bd9Sstevel@tonic-gate 	    pDigest, pulDigestLen));
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate /*
3637c478bd9Sstevel@tonic-gate  * soft_digest_update()
3647c478bd9Sstevel@tonic-gate  *
3657c478bd9Sstevel@tonic-gate  * Arguments:
3667c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
3677c478bd9Sstevel@tonic-gate  *      pPart:		pointer to the input data to be digested
3687c478bd9Sstevel@tonic-gate  *      ulPartLen:	length of the input data
3697c478bd9Sstevel@tonic-gate  *
3707c478bd9Sstevel@tonic-gate  * Description:
3717c478bd9Sstevel@tonic-gate  *      called by C_DigestUpdate(). This function calls the corresponding
3727c478bd9Sstevel@tonic-gate  *	software provided digest update routine based on the mechanism.
3737c478bd9Sstevel@tonic-gate  *
3747c478bd9Sstevel@tonic-gate  * Returns:
3757c478bd9Sstevel@tonic-gate  *      CKR_OK: success
3767c478bd9Sstevel@tonic-gate  *      CKR_MECHANISM_INVALID: invalid MECHANISM type.
3777c478bd9Sstevel@tonic-gate  */
3787c478bd9Sstevel@tonic-gate CK_RV
soft_digest_update(soft_session_t * session_p,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)3797c478bd9Sstevel@tonic-gate soft_digest_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
380a8793c76SJason King     CK_ULONG ulPartLen)
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 	switch (session_p->digest.mech.mechanism) {
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 	case CKM_MD5:
3867c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
3877c478bd9Sstevel@tonic-gate 		MD5Update((MD5_CTX *)session_p->digest.context,
3887c478bd9Sstevel@tonic-gate 		    /* LINTED */
3897c478bd9Sstevel@tonic-gate 		    pPart, (uint_t)ulPartLen);
3907c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
3917c478bd9Sstevel@tonic-gate 		MD5Update((MD5_CTX *)session_p->digest.context,
3927c478bd9Sstevel@tonic-gate 		    pPart, ulPartLen);
3937c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
3947c478bd9Sstevel@tonic-gate 		break;
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 	case CKM_SHA_1:
3977c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
3987c478bd9Sstevel@tonic-gate 		SHA1Update((SHA1_CTX *)session_p->digest.context,
3997c478bd9Sstevel@tonic-gate 		    /* LINTED */
4007c478bd9Sstevel@tonic-gate 		    pPart, (uint32_t)ulPartLen);
4017c478bd9Sstevel@tonic-gate #else	/* !__sparcv9 */
4027c478bd9Sstevel@tonic-gate 		SHA1Update((SHA1_CTX *)session_p->digest.context,
4037c478bd9Sstevel@tonic-gate 		    pPart, ulPartLen);
4047c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
4057c478bd9Sstevel@tonic-gate 		break;
4067c478bd9Sstevel@tonic-gate 
407f66d273dSizick 	case CKM_SHA256:
408f66d273dSizick 	case CKM_SHA384:
409f66d273dSizick 	case CKM_SHA512:
410*05204290SJason King 	case CKM_SHA512_224:
411*05204290SJason King 	case CKM_SHA512_256:
412f66d273dSizick 		SHA2Update((SHA2_CTX *)session_p->digest.context,
413f66d273dSizick 		    pPart, ulPartLen);
414f66d273dSizick 		break;
415f66d273dSizick 
4167c478bd9Sstevel@tonic-gate 	default:
4177c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	return (CKR_OK);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate /*
4257c478bd9Sstevel@tonic-gate  * soft_digest_final()
4267c478bd9Sstevel@tonic-gate  *
4277c478bd9Sstevel@tonic-gate  * Arguments:
4287c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
4297c478bd9Sstevel@tonic-gate  *      pDigest:	pointer to the output data after digesting
4307c478bd9Sstevel@tonic-gate  *      pulDigestLen:	length of the output data
4317c478bd9Sstevel@tonic-gate  *
4327c478bd9Sstevel@tonic-gate  * Description:
4337c478bd9Sstevel@tonic-gate  *      called by C_DigestFinal(). This function calls soft_digest_common().
4347c478bd9Sstevel@tonic-gate  *
4357c478bd9Sstevel@tonic-gate  * Returns:
4367c478bd9Sstevel@tonic-gate  *	see return values in soft_digest_common().
4377c478bd9Sstevel@tonic-gate  */
4387c478bd9Sstevel@tonic-gate CK_RV
soft_digest_final(soft_session_t * session_p,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)4397c478bd9Sstevel@tonic-gate soft_digest_final(soft_session_t *session_p, CK_BYTE_PTR pDigest,
440a8793c76SJason King     CK_ULONG_PTR pulDigestLen)
4417c478bd9Sstevel@tonic-gate {
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	return (soft_digest_common(session_p, NULL, 0,
4447c478bd9Sstevel@tonic-gate 	    pDigest, pulDigestLen));
4457c478bd9Sstevel@tonic-gate }
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate /*
4487c478bd9Sstevel@tonic-gate  * Perform digest init operation internally for the support of
4497c478bd9Sstevel@tonic-gate  * CKM_MD5_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_SHA1_KEY_DERIVATION
4507c478bd9Sstevel@tonic-gate  * and CKM_MD5_KEY_DERIVATION mechanisms.
4517c478bd9Sstevel@tonic-gate  *
4527c478bd9Sstevel@tonic-gate  * This function is called with the session being held, and without
4537c478bd9Sstevel@tonic-gate  * its mutex taken.
4547c478bd9Sstevel@tonic-gate  */
4557c478bd9Sstevel@tonic-gate CK_RV
soft_digest_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism)456a8793c76SJason King soft_digest_init_internal(soft_session_t *session_p,
457a8793c76SJason King     CK_MECHANISM_PTR pMechanism)
4587c478bd9Sstevel@tonic-gate {
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	CK_RV rv;
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	/* Check to see if digest operation is already active */
4657c478bd9Sstevel@tonic-gate 	if (session_p->digest.flags & CRYPTO_OPERATION_ACTIVE) {
4667c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
4677c478bd9Sstevel@tonic-gate 		return (CKR_OPERATION_ACTIVE);
4687c478bd9Sstevel@tonic-gate 	}
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	session_p->digest.flags = CRYPTO_OPERATION_ACTIVE;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	rv = soft_digest_init(session_p, pMechanism);
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
4777c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
4787c478bd9Sstevel@tonic-gate 		session_p->digest.flags &= ~CRYPTO_OPERATION_ACTIVE;
4797c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
4807c478bd9Sstevel@tonic-gate 	}
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 	return (rv);
4837c478bd9Sstevel@tonic-gate }
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate /*
4867c478bd9Sstevel@tonic-gate  * Call soft_digest_update() function with the value of a secret key.
4877c478bd9Sstevel@tonic-gate  */
4887c478bd9Sstevel@tonic-gate CK_RV
soft_digest_key(soft_session_t * session_p,soft_object_t * key_p)4897c478bd9Sstevel@tonic-gate soft_digest_key(soft_session_t *session_p, soft_object_t *key_p)
4907c478bd9Sstevel@tonic-gate {
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 	CK_RV rv;
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	/* Only secret key is allowed to be digested */
4957c478bd9Sstevel@tonic-gate 	if (key_p->class != CKO_SECRET_KEY)
4967c478bd9Sstevel@tonic-gate 		return (CKR_KEY_INDIGESTIBLE);
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	if ((OBJ_SEC_VALUE(key_p) == NULL) ||
4997c478bd9Sstevel@tonic-gate 	    (OBJ_SEC_VALUE_LEN(key_p) == 0))
5007c478bd9Sstevel@tonic-gate 		return (CKR_KEY_SIZE_RANGE);
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	rv = soft_digest_update(session_p, OBJ_SEC_VALUE(key_p),
5037c478bd9Sstevel@tonic-gate 	    OBJ_SEC_VALUE_LEN(key_p));
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 	return (rv);
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate }
508588a1af0SAlexandr Nedvedicky 
509588a1af0SAlexandr Nedvedicky /*
510588a1af0SAlexandr Nedvedicky  * This function releases allocated digest context. The caller
511588a1af0SAlexandr Nedvedicky  * may (lock_held == B_TRUE) or may not (lock_held == B_FALSE)
512588a1af0SAlexandr Nedvedicky  * hold a session mutex.
513588a1af0SAlexandr Nedvedicky  */
514588a1af0SAlexandr Nedvedicky void
soft_digest_cleanup(soft_session_t * session_p,boolean_t lock_held)515588a1af0SAlexandr Nedvedicky soft_digest_cleanup(soft_session_t *session_p, boolean_t lock_held)
516588a1af0SAlexandr Nedvedicky {
517588a1af0SAlexandr Nedvedicky 	boolean_t lock_true = B_TRUE;
518588a1af0SAlexandr Nedvedicky 
519588a1af0SAlexandr Nedvedicky 	if (!lock_held)
520588a1af0SAlexandr Nedvedicky 		(void) pthread_mutex_lock(&session_p->session_mutex);
521588a1af0SAlexandr Nedvedicky 
522588a1af0SAlexandr Nedvedicky 	if (session_p->digest.context != NULL) {
523588a1af0SAlexandr Nedvedicky 		free(session_p->digest.context);
524588a1af0SAlexandr Nedvedicky 		session_p->digest.context = NULL;
525588a1af0SAlexandr Nedvedicky 	}
526588a1af0SAlexandr Nedvedicky 
527588a1af0SAlexandr Nedvedicky 	session_p->digest.flags = 0;
528588a1af0SAlexandr Nedvedicky 
529588a1af0SAlexandr Nedvedicky 	if (!lock_held)
530588a1af0SAlexandr Nedvedicky 		SES_REFRELE(session_p, lock_true);
531588a1af0SAlexandr Nedvedicky 
532588a1af0SAlexandr Nedvedicky }
533