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