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