xref: /titanic_51/usr/src/lib/pkcs11/pkcs11_softtoken/common/softMAC.c (revision 60722cc87944966611a21fa3bebb86e9b77e8e9c)
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
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23f66d273dSizick  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <pthread.h>
307c478bd9Sstevel@tonic-gate #include <sys/md5.h>
317c478bd9Sstevel@tonic-gate #include <sys/sha1.h>
32f66d273dSizick #include <sys/sha2.h>
337c478bd9Sstevel@tonic-gate #include <stdlib.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
367c478bd9Sstevel@tonic-gate #include <sys/types.h>
377c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
387c478bd9Sstevel@tonic-gate #include "softObject.h"
397c478bd9Sstevel@tonic-gate #include "softOps.h"
407c478bd9Sstevel@tonic-gate #include "softSession.h"
417c478bd9Sstevel@tonic-gate #include "softMAC.h"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /*
447c478bd9Sstevel@tonic-gate  * IPAD = 0x36 repeated 48 times for ssl md5, repeated 40 times for ssl sha1
457c478bd9Sstevel@tonic-gate  * OPAD = 0x5C repeated 48 times for SSL md5, repeated 40 times for ssl sha1
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate const uint32_t md5_ssl_ipad[] = {
487c478bd9Sstevel@tonic-gate 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
497c478bd9Sstevel@tonic-gate 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
507c478bd9Sstevel@tonic-gate 	0x36363636, 0x36363636};
517c478bd9Sstevel@tonic-gate const uint32_t sha1_ssl_ipad[] = {
527c478bd9Sstevel@tonic-gate 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
537c478bd9Sstevel@tonic-gate 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636};
547c478bd9Sstevel@tonic-gate const uint32_t md5_ssl_opad[] = {
557c478bd9Sstevel@tonic-gate 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
567c478bd9Sstevel@tonic-gate 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
577c478bd9Sstevel@tonic-gate 	0x5c5c5c5c, 0x5c5c5c5c};
587c478bd9Sstevel@tonic-gate const uint32_t sha1_ssl_opad[] = {
597c478bd9Sstevel@tonic-gate 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
607c478bd9Sstevel@tonic-gate 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c};
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate /*
637c478bd9Sstevel@tonic-gate  * Allocate and initialize a HMAC context, and save the context pointer in
647c478bd9Sstevel@tonic-gate  * the session struct. For General-length HMAC, checks the length in the
657c478bd9Sstevel@tonic-gate  * parameter to see if it is in the right range.
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate CK_RV
687c478bd9Sstevel@tonic-gate soft_hmac_sign_verify_init_common(soft_session_t *session_p,
697c478bd9Sstevel@tonic-gate     CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op)
707c478bd9Sstevel@tonic-gate {
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	soft_hmac_ctx_t *hmac_ctx;
737c478bd9Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	if ((key_p->class != CKO_SECRET_KEY) ||
767c478bd9Sstevel@tonic-gate 	    (key_p->key_type != CKK_GENERIC_SECRET)) {
777c478bd9Sstevel@tonic-gate 		return (CKR_KEY_TYPE_INCONSISTENT);
787c478bd9Sstevel@tonic-gate 	}
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 	hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	if (hmac_ctx == NULL) {
837c478bd9Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
847c478bd9Sstevel@tonic-gate 	}
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	switch (pMechanism->mechanism) {
87f66d273dSizick 	case CKM_MD5_HMAC:
88f66d273dSizick 		hmac_ctx->hmac_len = MD5_HASH_SIZE;
89f66d273dSizick 		break;
907c478bd9Sstevel@tonic-gate 
91f66d273dSizick 	case CKM_SHA_1_HMAC:
92f66d273dSizick 		hmac_ctx->hmac_len = SHA1_HASH_SIZE;
93f66d273dSizick 		break;
94f66d273dSizick 
95f66d273dSizick 	case CKM_SHA256_HMAC:
96f66d273dSizick 		hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
97f66d273dSizick 		break;
98f66d273dSizick 
99f66d273dSizick 	case CKM_SHA384_HMAC:
100f66d273dSizick 		hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
101f66d273dSizick 		break;
102f66d273dSizick 
103f66d273dSizick 	case CKM_SHA512_HMAC:
104f66d273dSizick 		hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
105f66d273dSizick 		break;
106f66d273dSizick 
1077c478bd9Sstevel@tonic-gate 	case CKM_MD5_HMAC_GENERAL:
108f66d273dSizick 	case CKM_SSL3_MD5_MAC:
109f66d273dSizick 		if ((pMechanism->ulParameterLen !=
110f66d273dSizick 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
111f66d273dSizick 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
112f66d273dSizick 			MD5_HASH_SIZE)) {
113f66d273dSizick 				free(hmac_ctx);
114f66d273dSizick 				return (CKR_MECHANISM_PARAM_INVALID);
115f66d273dSizick 			}
116f66d273dSizick 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
117f66d273dSizick 		    pMechanism->pParameter);
118f66d273dSizick 		break;
119f66d273dSizick 
120f66d273dSizick 	case CKM_SSL3_SHA1_MAC:
1217c478bd9Sstevel@tonic-gate 	case CKM_SHA_1_HMAC_GENERAL:
122f66d273dSizick 		if ((pMechanism->ulParameterLen !=
123f66d273dSizick 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
124f66d273dSizick 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
125f66d273dSizick 			SHA1_HASH_SIZE)) {
126f66d273dSizick 			free(hmac_ctx);
127f66d273dSizick 			return (CKR_MECHANISM_PARAM_INVALID);
128f66d273dSizick 		}
129f66d273dSizick 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
130f66d273dSizick 		    pMechanism->pParameter);
131f66d273dSizick 		break;
1327c478bd9Sstevel@tonic-gate 
133f66d273dSizick 	case CKM_SHA256_HMAC_GENERAL:
134f66d273dSizick 		if ((pMechanism->ulParameterLen !=
135f66d273dSizick 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
136f66d273dSizick 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
137f66d273dSizick 			SHA256_DIGEST_LENGTH)) {
1387c478bd9Sstevel@tonic-gate 			free(hmac_ctx);
1397c478bd9Sstevel@tonic-gate 			return (CKR_MECHANISM_PARAM_INVALID);
1407c478bd9Sstevel@tonic-gate 		}
141f66d273dSizick 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
142f66d273dSizick 		    pMechanism->pParameter);
143f66d273dSizick 		break;
1447c478bd9Sstevel@tonic-gate 
145f66d273dSizick 	case CKM_SHA384_HMAC_GENERAL:
146f66d273dSizick 	case CKM_SHA512_HMAC_GENERAL:
147f66d273dSizick 		if ((pMechanism->ulParameterLen !=
148f66d273dSizick 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
149f66d273dSizick 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
150f66d273dSizick 			SHA512_DIGEST_LENGTH)) {
1517c478bd9Sstevel@tonic-gate 			free(hmac_ctx);
1527c478bd9Sstevel@tonic-gate 			return (CKR_MECHANISM_PARAM_INVALID);
1537c478bd9Sstevel@tonic-gate 		}
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
1567c478bd9Sstevel@tonic-gate 		    pMechanism->pParameter);
157f66d273dSizick 		break;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	}
1607c478bd9Sstevel@tonic-gate 
161f66d273dSizick 
1627c478bd9Sstevel@tonic-gate 	/* Initialize a MAC context. */
163f66d273dSizick 	rv = mac_init_ctx(session_p, key_p, hmac_ctx, pMechanism->mechanism);
1647c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
1657c478bd9Sstevel@tonic-gate 		return (rv);
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	if (sign_op) {
170f66d273dSizick 		session_p->sign.mech.mechanism = pMechanism->mechanism;
1717c478bd9Sstevel@tonic-gate 		session_p->sign.context = hmac_ctx;
1727c478bd9Sstevel@tonic-gate 	} else {
173f66d273dSizick 		session_p->verify.mech.mechanism = pMechanism->mechanism;
1747c478bd9Sstevel@tonic-gate 		session_p->verify.context = hmac_ctx;
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	return (CKR_OK);
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate /*
1847c478bd9Sstevel@tonic-gate  * Initialize a HMAC context.
1857c478bd9Sstevel@tonic-gate  */
1867c478bd9Sstevel@tonic-gate CK_RV
1877c478bd9Sstevel@tonic-gate mac_init_ctx(soft_session_t *session_p, soft_object_t *key,
1887c478bd9Sstevel@tonic-gate     soft_hmac_ctx_t *ctx, CK_MECHANISM_TYPE mech)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	switch (mech) {
1937c478bd9Sstevel@tonic-gate 	case CKM_SSL3_MD5_MAC:
1947c478bd9Sstevel@tonic-gate 	{
1957c478bd9Sstevel@tonic-gate 		CK_BYTE md5_ipad[MD5_SSL_PAD_AND_KEY_SIZE];
1967c478bd9Sstevel@tonic-gate 		CK_BYTE md5_opad[MD5_SSL_PAD_AND_KEY_SIZE];
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 		if (OBJ_SEC(key)->sk_value_len > MD5_SSL_PAD_AND_KEY_SIZE) {
1997c478bd9Sstevel@tonic-gate 			return (CKR_KEY_SIZE_RANGE);
2007c478bd9Sstevel@tonic-gate 		}
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 		bzero(md5_ipad, MD5_SSL_PAD_AND_KEY_SIZE);
2037c478bd9Sstevel@tonic-gate 		bzero(md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 		/* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
2067c478bd9Sstevel@tonic-gate 		(void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
2077c478bd9Sstevel@tonic-gate 		    OBJ_SEC(key)->sk_value_len);
2087c478bd9Sstevel@tonic-gate 		(void) memcpy(&md5_ipad[OBJ_SEC(key)->sk_value_len],
2097c478bd9Sstevel@tonic-gate 		    md5_ssl_ipad, MD5_SSL_PAD_SIZE);
2107c478bd9Sstevel@tonic-gate 		(void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
2117c478bd9Sstevel@tonic-gate 		    OBJ_SEC(key)->sk_value_len);
2127c478bd9Sstevel@tonic-gate 		(void) memcpy(&md5_opad[OBJ_SEC(key)->sk_value_len],
2137c478bd9Sstevel@tonic-gate 		    md5_ssl_opad, MD5_SSL_PAD_SIZE);
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 		SOFT_MAC_INIT_CTX(MD5, &(ctx->hc_ctx_u.md5_ctx),
2167c478bd9Sstevel@tonic-gate 		    md5_ipad, md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 		break;
2197c478bd9Sstevel@tonic-gate 	}
2207c478bd9Sstevel@tonic-gate 	case CKM_MD5_HMAC_GENERAL:
2217c478bd9Sstevel@tonic-gate 	case CKM_MD5_HMAC:
2227c478bd9Sstevel@tonic-gate 	{
2237c478bd9Sstevel@tonic-gate 		uint32_t md5_ipad[MD5_HMAC_INTS_PER_BLOCK];
2247c478bd9Sstevel@tonic-gate 		uint32_t md5_opad[MD5_HMAC_INTS_PER_BLOCK];
2257c478bd9Sstevel@tonic-gate 		CK_MECHANISM digest_mech;
2267c478bd9Sstevel@tonic-gate 		CK_ULONG hash_len = MD5_HASH_SIZE;
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 		bzero(md5_ipad, MD5_HMAC_BLOCK_SIZE);
2297c478bd9Sstevel@tonic-gate 		bzero(md5_opad, MD5_HMAC_BLOCK_SIZE);
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 		if (OBJ_SEC(key)->sk_value_len > MD5_HMAC_BLOCK_SIZE) {
2327c478bd9Sstevel@tonic-gate 			/*
2337c478bd9Sstevel@tonic-gate 			 * Hash the key when it is longer than 64 bytes.
2347c478bd9Sstevel@tonic-gate 			 */
2357c478bd9Sstevel@tonic-gate 			digest_mech.mechanism = CKM_MD5;
2367c478bd9Sstevel@tonic-gate 			digest_mech.pParameter = NULL_PTR;
2377c478bd9Sstevel@tonic-gate 			digest_mech.ulParameterLen = 0;
2387c478bd9Sstevel@tonic-gate 			rv = soft_digest_init_internal(session_p, &digest_mech);
2397c478bd9Sstevel@tonic-gate 			if (rv != CKR_OK)
2407c478bd9Sstevel@tonic-gate 				return (rv);
2417c478bd9Sstevel@tonic-gate 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
2427c478bd9Sstevel@tonic-gate 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)md5_ipad,
2437c478bd9Sstevel@tonic-gate 			    &hash_len);
2447c478bd9Sstevel@tonic-gate 			session_p->digest.flags = 0;
2457c478bd9Sstevel@tonic-gate 			if (rv != CKR_OK)
2467c478bd9Sstevel@tonic-gate 				return (rv);
2477c478bd9Sstevel@tonic-gate 			(void) memcpy(md5_opad, md5_ipad, hash_len);
2487c478bd9Sstevel@tonic-gate 		} else {
2497c478bd9Sstevel@tonic-gate 			(void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
2507c478bd9Sstevel@tonic-gate 			    OBJ_SEC(key)->sk_value_len);
2517c478bd9Sstevel@tonic-gate 			(void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
2527c478bd9Sstevel@tonic-gate 			    OBJ_SEC(key)->sk_value_len);
2537c478bd9Sstevel@tonic-gate 		}
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 		md5_hmac_ctx_init(&ctx->hc_ctx_u.md5_ctx, md5_ipad, md5_opad);
2567c478bd9Sstevel@tonic-gate 		break;
2577c478bd9Sstevel@tonic-gate 	}
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	case CKM_SSL3_SHA1_MAC:
2607c478bd9Sstevel@tonic-gate 	{
2617c478bd9Sstevel@tonic-gate 		CK_BYTE sha1_ipad[SHA1_SSL_PAD_AND_KEY_SIZE];
2627c478bd9Sstevel@tonic-gate 		CK_BYTE sha1_opad[SHA1_SSL_PAD_AND_KEY_SIZE];
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 		if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
2657c478bd9Sstevel@tonic-gate 			return (CKR_KEY_SIZE_RANGE);
2667c478bd9Sstevel@tonic-gate 		}
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 		bzero(sha1_ipad, SHA1_SSL_PAD_AND_KEY_SIZE);
2697c478bd9Sstevel@tonic-gate 		bzero(sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 		/* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
2727c478bd9Sstevel@tonic-gate 		(void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
2737c478bd9Sstevel@tonic-gate 		    OBJ_SEC(key)->sk_value_len);
2747c478bd9Sstevel@tonic-gate 		(void) memcpy(&sha1_ipad[OBJ_SEC(key)->sk_value_len],
2757c478bd9Sstevel@tonic-gate 		    sha1_ssl_ipad, SHA1_SSL_PAD_SIZE);
2767c478bd9Sstevel@tonic-gate 		(void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
2777c478bd9Sstevel@tonic-gate 		    OBJ_SEC(key)->sk_value_len);
2787c478bd9Sstevel@tonic-gate 		(void) memcpy(&sha1_opad[OBJ_SEC(key)->sk_value_len],
2797c478bd9Sstevel@tonic-gate 		    sha1_ssl_opad, SHA1_SSL_PAD_SIZE);
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 		SOFT_MAC_INIT_CTX(SHA1, &(ctx->hc_ctx_u.sha1_ctx),
2827c478bd9Sstevel@tonic-gate 		    sha1_ipad, sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 		break;
2857c478bd9Sstevel@tonic-gate 	}
2867c478bd9Sstevel@tonic-gate 	case CKM_SHA_1_HMAC_GENERAL:
2877c478bd9Sstevel@tonic-gate 	case CKM_SHA_1_HMAC:
2887c478bd9Sstevel@tonic-gate 	{
2897c478bd9Sstevel@tonic-gate 		uint32_t sha1_ipad[SHA1_HMAC_INTS_PER_BLOCK];
2907c478bd9Sstevel@tonic-gate 		uint32_t sha1_opad[SHA1_HMAC_INTS_PER_BLOCK];
2917c478bd9Sstevel@tonic-gate 		CK_MECHANISM digest_mech;
2927c478bd9Sstevel@tonic-gate 		CK_ULONG hash_len = SHA1_HASH_SIZE;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 		bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
2957c478bd9Sstevel@tonic-gate 		bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 		if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
2987c478bd9Sstevel@tonic-gate 			/*
2997c478bd9Sstevel@tonic-gate 			 * Hash the key when it is longer than 64 bytes.
3007c478bd9Sstevel@tonic-gate 			 */
3017c478bd9Sstevel@tonic-gate 			digest_mech.mechanism = CKM_SHA_1;
3027c478bd9Sstevel@tonic-gate 			digest_mech.pParameter = NULL_PTR;
3037c478bd9Sstevel@tonic-gate 			digest_mech.ulParameterLen = 0;
3047c478bd9Sstevel@tonic-gate 			rv = soft_digest_init_internal(session_p, &digest_mech);
3057c478bd9Sstevel@tonic-gate 			if (rv != CKR_OK)
3067c478bd9Sstevel@tonic-gate 				return (rv);
3077c478bd9Sstevel@tonic-gate 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
3087c478bd9Sstevel@tonic-gate 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha1_ipad,
3097c478bd9Sstevel@tonic-gate 			    &hash_len);
3107c478bd9Sstevel@tonic-gate 			session_p->digest.flags = 0;
3117c478bd9Sstevel@tonic-gate 			if (rv != CKR_OK)
3127c478bd9Sstevel@tonic-gate 				return (rv);
3137c478bd9Sstevel@tonic-gate 			(void) memcpy(sha1_opad, sha1_ipad, hash_len);
3147c478bd9Sstevel@tonic-gate 		} else {
3157c478bd9Sstevel@tonic-gate 			(void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
3167c478bd9Sstevel@tonic-gate 			    OBJ_SEC(key)->sk_value_len);
3177c478bd9Sstevel@tonic-gate 			(void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
3187c478bd9Sstevel@tonic-gate 			    OBJ_SEC(key)->sk_value_len);
3197c478bd9Sstevel@tonic-gate 		}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 		sha1_hmac_ctx_init(&ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
3227c478bd9Sstevel@tonic-gate 		    sha1_opad);
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 		break;
3257c478bd9Sstevel@tonic-gate 	}
326f66d273dSizick 	case CKM_SHA256_HMAC:
327f66d273dSizick 	case CKM_SHA256_HMAC_GENERAL:
328f66d273dSizick 	{
329f66d273dSizick 		uint64_t sha_ipad[SHA256_HMAC_INTS_PER_BLOCK];
330f66d273dSizick 		uint64_t sha_opad[SHA256_HMAC_INTS_PER_BLOCK];
331f66d273dSizick 		CK_MECHANISM digest_mech;
332f66d273dSizick 		CK_ULONG hash_len = SHA256_DIGEST_LENGTH;
333f66d273dSizick 
334f66d273dSizick 		bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
335f66d273dSizick 		bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
336f66d273dSizick 
337f66d273dSizick 		if (OBJ_SEC(key)->sk_value_len > SHA256_HMAC_BLOCK_SIZE) {
338f66d273dSizick 			/*
339f66d273dSizick 			 * Hash the key when it is longer than 64 bytes.
340f66d273dSizick 			 */
341f66d273dSizick 			digest_mech.mechanism = CKM_SHA256;
342f66d273dSizick 			digest_mech.pParameter = NULL_PTR;
343f66d273dSizick 			digest_mech.ulParameterLen = 0;
344f66d273dSizick 			rv = soft_digest_init_internal(session_p, &digest_mech);
345f66d273dSizick 			if (rv != CKR_OK)
346f66d273dSizick 				return (rv);
347f66d273dSizick 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
348f66d273dSizick 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
349f66d273dSizick 			    &hash_len);
350f66d273dSizick 			session_p->digest.flags = 0;
351f66d273dSizick 			if (rv != CKR_OK)
352f66d273dSizick 				return (rv);
353f66d273dSizick 			(void) memcpy(sha_opad, sha_ipad, hash_len);
354f66d273dSizick 		} else {
355f66d273dSizick 			(void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
356f66d273dSizick 			    OBJ_SEC(key)->sk_value_len);
357f66d273dSizick 			(void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
358f66d273dSizick 			    OBJ_SEC(key)->sk_value_len);
359f66d273dSizick 		}
360f66d273dSizick 
361f66d273dSizick 		sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
362f66d273dSizick 		    sha_ipad, sha_opad, SHA256_HMAC_INTS_PER_BLOCK,
363f66d273dSizick 		    SHA256_HMAC_BLOCK_SIZE);
364f66d273dSizick 
365f66d273dSizick 		break;
366f66d273dSizick 	}
367f66d273dSizick 	case CKM_SHA384_HMAC:
368f66d273dSizick 	case CKM_SHA384_HMAC_GENERAL:
369f66d273dSizick 	{
370f66d273dSizick 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
371f66d273dSizick 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
372f66d273dSizick 		CK_MECHANISM digest_mech;
373f66d273dSizick 		CK_ULONG hash_len = SHA384_DIGEST_LENGTH;
374f66d273dSizick 
375f66d273dSizick 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
376f66d273dSizick 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
377f66d273dSizick 
378f66d273dSizick 		if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
379f66d273dSizick 			/*
380f66d273dSizick 			 * Hash the key when it is longer than 64 bytes.
381f66d273dSizick 			 */
382f66d273dSizick 			digest_mech.mechanism = CKM_SHA384;
383f66d273dSizick 			digest_mech.pParameter = NULL_PTR;
384f66d273dSizick 			digest_mech.ulParameterLen = 0;
385f66d273dSizick 			rv = soft_digest_init_internal(session_p, &digest_mech);
386f66d273dSizick 			if (rv != CKR_OK)
387f66d273dSizick 				return (rv);
388f66d273dSizick 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
389f66d273dSizick 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
390f66d273dSizick 			    &hash_len);
391f66d273dSizick 			session_p->digest.flags = 0;
392f66d273dSizick 			if (rv != CKR_OK)
393f66d273dSizick 				return (rv);
394f66d273dSizick 			(void) memcpy(sha_opad, sha_ipad, hash_len);
395f66d273dSizick 		} else {
396f66d273dSizick 			(void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
397f66d273dSizick 			    OBJ_SEC(key)->sk_value_len);
398f66d273dSizick 			(void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
399f66d273dSizick 			    OBJ_SEC(key)->sk_value_len);
400f66d273dSizick 		}
401f66d273dSizick 
402f66d273dSizick 		sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
403f66d273dSizick 		    sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
404f66d273dSizick 		    SHA512_HMAC_BLOCK_SIZE);
405f66d273dSizick 
406f66d273dSizick 		break;
407f66d273dSizick 	}
408f66d273dSizick 	case CKM_SHA512_HMAC:
409f66d273dSizick 	case CKM_SHA512_HMAC_GENERAL:
410f66d273dSizick 	{
411f66d273dSizick 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
412f66d273dSizick 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
413f66d273dSizick 		CK_MECHANISM digest_mech;
414f66d273dSizick 		CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
415f66d273dSizick 
416f66d273dSizick 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
417f66d273dSizick 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
418f66d273dSizick 
419f66d273dSizick 		if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
420f66d273dSizick 			/*
421f66d273dSizick 			 * Hash the key when it is longer than 64 bytes.
422f66d273dSizick 			 */
423f66d273dSizick 			digest_mech.mechanism = CKM_SHA512;
424f66d273dSizick 			digest_mech.pParameter = NULL_PTR;
425f66d273dSizick 			digest_mech.ulParameterLen = 0;
426f66d273dSizick 			rv = soft_digest_init_internal(session_p, &digest_mech);
427f66d273dSizick 			if (rv != CKR_OK)
428f66d273dSizick 				return (rv);
429f66d273dSizick 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
430f66d273dSizick 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
431f66d273dSizick 			    &hash_len);
432f66d273dSizick 			session_p->digest.flags = 0;
433f66d273dSizick 			if (rv != CKR_OK)
434f66d273dSizick 				return (rv);
435f66d273dSizick 			(void) memcpy(sha_opad, sha_ipad, hash_len);
436f66d273dSizick 		} else {
437f66d273dSizick 			(void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
438f66d273dSizick 			    OBJ_SEC(key)->sk_value_len);
439f66d273dSizick 			(void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
440f66d273dSizick 			    OBJ_SEC(key)->sk_value_len);
441f66d273dSizick 		}
442f66d273dSizick 
443f66d273dSizick 		sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
444f66d273dSizick 		    sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
445f66d273dSizick 		    SHA512_HMAC_BLOCK_SIZE);
446f66d273dSizick 
447f66d273dSizick 		break;
448f66d273dSizick 	}
4497c478bd9Sstevel@tonic-gate 	}
4507c478bd9Sstevel@tonic-gate 	return (rv);
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate /*
4557c478bd9Sstevel@tonic-gate  * Called by soft_sign(), soft_sign_final(), soft_verify() or
4567c478bd9Sstevel@tonic-gate  * soft_verify_final().
4577c478bd9Sstevel@tonic-gate  */
4587c478bd9Sstevel@tonic-gate CK_RV
4597c478bd9Sstevel@tonic-gate soft_hmac_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
4607c478bd9Sstevel@tonic-gate     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen,
4617c478bd9Sstevel@tonic-gate     boolean_t sign_op)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	soft_hmac_ctx_t	*hmac_ctx;
4657c478bd9Sstevel@tonic-gate 	CK_MECHANISM_TYPE	mechanism;
4667c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
4677c478bd9Sstevel@tonic-gate 	/* LINTED */
4687c478bd9Sstevel@tonic-gate 	uint_t datalen = (uint_t)ulDataLen;
4697c478bd9Sstevel@tonic-gate #else	/* __sparcv9 */
4707c478bd9Sstevel@tonic-gate 	uint_t datalen = ulDataLen;
4717c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate 	if (sign_op) {
4747c478bd9Sstevel@tonic-gate 		hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
4757c478bd9Sstevel@tonic-gate 		mechanism = session_p->sign.mech.mechanism;
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 		/*
4787c478bd9Sstevel@tonic-gate 		 * If application asks for the length of the output buffer
4797c478bd9Sstevel@tonic-gate 		 * to hold the signature?
4807c478bd9Sstevel@tonic-gate 		 */
4817c478bd9Sstevel@tonic-gate 		if (pSigned == NULL) {
4827c478bd9Sstevel@tonic-gate 			*pulSignedLen = hmac_ctx->hmac_len;
4837c478bd9Sstevel@tonic-gate 			return (CKR_OK);
4847c478bd9Sstevel@tonic-gate 		}
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 		/* Is the application-supplied buffer large enough? */
4877c478bd9Sstevel@tonic-gate 		if (*pulSignedLen < hmac_ctx->hmac_len) {
4887c478bd9Sstevel@tonic-gate 			*pulSignedLen = hmac_ctx->hmac_len;
4897c478bd9Sstevel@tonic-gate 			return (CKR_BUFFER_TOO_SMALL);
4907c478bd9Sstevel@tonic-gate 		}
4917c478bd9Sstevel@tonic-gate 	} else {
4927c478bd9Sstevel@tonic-gate 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
4937c478bd9Sstevel@tonic-gate 		mechanism = session_p->verify.mech.mechanism;
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	switch (mechanism) {
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	case CKM_SSL3_MD5_MAC:
4997c478bd9Sstevel@tonic-gate 	case CKM_MD5_HMAC_GENERAL:
5007c478bd9Sstevel@tonic-gate 	case CKM_MD5_HMAC:
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 		if (pData != NULL) {
5037c478bd9Sstevel@tonic-gate 			/* Called by soft_sign() or soft_verify(). */
5047c478bd9Sstevel@tonic-gate 			SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx),
5057c478bd9Sstevel@tonic-gate 			    pData, datalen);
5067c478bd9Sstevel@tonic-gate 		}
5077c478bd9Sstevel@tonic-gate 		SOFT_MAC_FINAL(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pSigned);
5087c478bd9Sstevel@tonic-gate 		break;
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	case CKM_SSL3_SHA1_MAC:
5117c478bd9Sstevel@tonic-gate 	case CKM_SHA_1_HMAC_GENERAL:
5127c478bd9Sstevel@tonic-gate 	case CKM_SHA_1_HMAC:
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 		if (pData != NULL) {
5157c478bd9Sstevel@tonic-gate 			/* Called by soft_sign() or soft_verify(). */
5167c478bd9Sstevel@tonic-gate 			SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx),
5177c478bd9Sstevel@tonic-gate 			    pData, datalen);
5187c478bd9Sstevel@tonic-gate 		}
5197c478bd9Sstevel@tonic-gate 		SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pSigned);
520f66d273dSizick 		break;
521f66d273dSizick 
522f66d273dSizick 	case CKM_SHA256_HMAC_GENERAL:
523f66d273dSizick 	case CKM_SHA256_HMAC:
524f66d273dSizick 		if (pData != NULL)
525f66d273dSizick 			/* Called by soft_sign() or soft_verify(). */
526f66d273dSizick 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
527f66d273dSizick 			    pData, datalen);
528f66d273dSizick 
529f66d273dSizick 		SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
530f66d273dSizick 		    pSigned);
531f66d273dSizick 		break;
532f66d273dSizick 
533f66d273dSizick 	case CKM_SHA384_HMAC_GENERAL:
534f66d273dSizick 	case CKM_SHA384_HMAC:
535f66d273dSizick 		if (pData != NULL)
536f66d273dSizick 			/* Called by soft_sign() or soft_verify(). */
537f66d273dSizick 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
538f66d273dSizick 			    pData, datalen);
539f66d273dSizick 
540f66d273dSizick 		SOFT_MAC_FINAL_2(SHA384, &(hmac_ctx->hc_ctx_u.sha2_ctx),
541f66d273dSizick 		    pSigned);
542f66d273dSizick 		hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
543f66d273dSizick 		break;
544f66d273dSizick 
545f66d273dSizick 	case CKM_SHA512_HMAC_GENERAL:
546f66d273dSizick 	case CKM_SHA512_HMAC:
547f66d273dSizick 
548f66d273dSizick 		if (pData != NULL)
549f66d273dSizick 			/* Called by soft_sign() or soft_verify(). */
550f66d273dSizick 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
551f66d273dSizick 			    pData, datalen);
552f66d273dSizick 
553f66d273dSizick 		SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
554f66d273dSizick 		    pSigned);
555f66d273dSizick 	};
556f66d273dSizick 
5577c478bd9Sstevel@tonic-gate 	*pulSignedLen = hmac_ctx->hmac_len;
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate clean_exit:
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate 	if (sign_op) {
5657c478bd9Sstevel@tonic-gate 		bzero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
5667c478bd9Sstevel@tonic-gate 		free(session_p->sign.context);
5677c478bd9Sstevel@tonic-gate 		session_p->sign.context = NULL;
5687c478bd9Sstevel@tonic-gate 	} else {
5697c478bd9Sstevel@tonic-gate 		bzero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
5707c478bd9Sstevel@tonic-gate 		free(session_p->verify.context);
5717c478bd9Sstevel@tonic-gate 		session_p->verify.context = NULL;
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	return (CKR_OK);
5777c478bd9Sstevel@tonic-gate }
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate /*
5817c478bd9Sstevel@tonic-gate  * Called by soft_sign_update() or soft_verify_update().
5827c478bd9Sstevel@tonic-gate  */
5837c478bd9Sstevel@tonic-gate CK_RV
5847c478bd9Sstevel@tonic-gate soft_hmac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
5857c478bd9Sstevel@tonic-gate 	CK_ULONG ulPartLen, boolean_t sign_op)
5867c478bd9Sstevel@tonic-gate {
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate 	soft_hmac_ctx_t	*hmac_ctx;
5897c478bd9Sstevel@tonic-gate 	CK_MECHANISM_TYPE	mechanism;
5907c478bd9Sstevel@tonic-gate #ifdef	__sparcv9
5917c478bd9Sstevel@tonic-gate 	/* LINTED */
5927c478bd9Sstevel@tonic-gate 	uint_t partlen = (uint_t)ulPartLen;
5937c478bd9Sstevel@tonic-gate #else	/* __sparcv9 */
5947c478bd9Sstevel@tonic-gate 	uint_t partlen = ulPartLen;
5957c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 	if (sign_op) {
5987c478bd9Sstevel@tonic-gate 		hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
5997c478bd9Sstevel@tonic-gate 		mechanism = session_p->sign.mech.mechanism;
6007c478bd9Sstevel@tonic-gate 	} else {
6017c478bd9Sstevel@tonic-gate 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
6027c478bd9Sstevel@tonic-gate 		mechanism = session_p->verify.mech.mechanism;
6037c478bd9Sstevel@tonic-gate 	}
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate 	switch (mechanism) {
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 	case CKM_SSL3_MD5_MAC:
6087c478bd9Sstevel@tonic-gate 	case CKM_MD5_HMAC_GENERAL:
6097c478bd9Sstevel@tonic-gate 	case CKM_MD5_HMAC:
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 		SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pPart,
6127c478bd9Sstevel@tonic-gate 		    partlen);
6137c478bd9Sstevel@tonic-gate 		break;
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 	case CKM_SSL3_SHA1_MAC:
6167c478bd9Sstevel@tonic-gate 	case CKM_SHA_1_HMAC_GENERAL:
6177c478bd9Sstevel@tonic-gate 	case CKM_SHA_1_HMAC:
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 		SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pPart,
6207c478bd9Sstevel@tonic-gate 		    partlen);
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 		break;
623f66d273dSizick 
624f66d273dSizick 	case CKM_SHA256_HMAC_GENERAL:
625f66d273dSizick 	case CKM_SHA256_HMAC:
626f66d273dSizick 	case CKM_SHA384_HMAC_GENERAL:
627f66d273dSizick 	case CKM_SHA384_HMAC:
628f66d273dSizick 	case CKM_SHA512_HMAC_GENERAL:
629f66d273dSizick 	case CKM_SHA512_HMAC:
630f66d273dSizick 
631f66d273dSizick 		SOFT_MAC_UPDATE(SHA2, &(hmac_ctx->hc_ctx_u.sha2_ctx), pPart,
632f66d273dSizick 		    partlen);
633f66d273dSizick 		break;
634f66d273dSizick 
6357c478bd9Sstevel@tonic-gate 	}
6367c478bd9Sstevel@tonic-gate 	return (CKR_OK);
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate /*
6407c478bd9Sstevel@tonic-gate  * The following 2 functions expect the MAC key to be alreay copied in
6417c478bd9Sstevel@tonic-gate  * the ipad and opad
6427c478bd9Sstevel@tonic-gate  */
6437c478bd9Sstevel@tonic-gate void
6447c478bd9Sstevel@tonic-gate md5_hmac_ctx_init(md5_hc_ctx_t *md5_hmac_ctx, uint32_t *ipad, uint32_t *opad)
6457c478bd9Sstevel@tonic-gate {
6467c478bd9Sstevel@tonic-gate 	int i;
6477c478bd9Sstevel@tonic-gate 	/* XOR key with ipad (0x36) and opad (0x5c) */
6487c478bd9Sstevel@tonic-gate 	for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
6497c478bd9Sstevel@tonic-gate 		ipad[i] ^= 0x36363636;
6507c478bd9Sstevel@tonic-gate 		opad[i] ^= 0x5c5c5c5c;
6517c478bd9Sstevel@tonic-gate 	}
6527c478bd9Sstevel@tonic-gate 	SOFT_MAC_INIT_CTX(MD5, md5_hmac_ctx, ipad, opad, MD5_HMAC_BLOCK_SIZE);
6537c478bd9Sstevel@tonic-gate }
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate void
6567c478bd9Sstevel@tonic-gate sha1_hmac_ctx_init(sha1_hc_ctx_t *sha1_hmac_ctx, uint32_t *ipad, uint32_t *opad)
6577c478bd9Sstevel@tonic-gate {
6587c478bd9Sstevel@tonic-gate 	int i;
6597c478bd9Sstevel@tonic-gate 	/* XOR key with ipad (0x36) and opad (0x5c) */
6607c478bd9Sstevel@tonic-gate 	for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
6617c478bd9Sstevel@tonic-gate 		ipad[i] ^= 0x36363636;
6627c478bd9Sstevel@tonic-gate 		opad[i] ^= 0x5c5c5c5c;
6637c478bd9Sstevel@tonic-gate 	}
6647c478bd9Sstevel@tonic-gate 	SOFT_MAC_INIT_CTX(SHA1, sha1_hmac_ctx, (const uchar_t *)ipad,
6657c478bd9Sstevel@tonic-gate 	    (const uchar_t *)opad, SHA1_HMAC_BLOCK_SIZE);
6667c478bd9Sstevel@tonic-gate }
667f66d273dSizick 
668f66d273dSizick 
669f66d273dSizick void
670f66d273dSizick sha2_hmac_ctx_init(uint_t mech, sha2_hc_ctx_t *ctx, uint64_t *ipad,
671f66d273dSizick     uint64_t *opad, uint_t blocks_per_int64, uint_t block_size)
672f66d273dSizick {
673f66d273dSizick 	int i;
674f66d273dSizick 
675f66d273dSizick 	/* XOR key with ipad (0x36) and opad (0x5c) */
676f66d273dSizick 	for (i = 0; i < blocks_per_int64; i ++) {
677*60722cc8Sizick 		ipad[i] ^= 0x3636363636363636ULL;
678*60722cc8Sizick 		opad[i] ^= 0x5c5c5c5c5c5c5c5cULL;
679f66d273dSizick 	}
680f66d273dSizick 
681f66d273dSizick 	/* perform SHA2 on ipad */
682f66d273dSizick 	SHA2Init(mech, &ctx->hc_icontext);
683f66d273dSizick 	SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
684f66d273dSizick 
685f66d273dSizick 	/* perform SHA2 on opad */
686f66d273dSizick 	SHA2Init(mech, &ctx->hc_ocontext);
687f66d273dSizick 	SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
688f66d273dSizick 
689f66d273dSizick }
690