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
soft_digest_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism)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
soft_digest_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)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
soft_digest(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)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
soft_digest_update(soft_session_t * session_p,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)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
soft_digest_final(soft_session_t * session_p,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)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
soft_digest_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism)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
soft_digest_key(soft_session_t * session_p,soft_object_t * key_p)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
soft_digest_cleanup(soft_session_t * session_p,boolean_t lock_held)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