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