xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_softtoken/common/softMAC.c (revision 89b2a9fbeabf42fa54594df0e5927bcc50a07cc9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <pthread.h>
30 #include <sys/md5.h>
31 #include <sys/sha1.h>
32 #include <sys/sha2.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <strings.h>
36 #include <sys/types.h>
37 #include <security/cryptoki.h>
38 #include "softObject.h"
39 #include "softOps.h"
40 #include "softSession.h"
41 #include "softMAC.h"
42 
43 /*
44  * IPAD = 0x36 repeated 48 times for ssl md5, repeated 40 times for ssl sha1
45  * OPAD = 0x5C repeated 48 times for SSL md5, repeated 40 times for ssl sha1
46  */
47 const uint32_t md5_ssl_ipad[] = {
48 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
49 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
50 	0x36363636, 0x36363636};
51 const uint32_t sha1_ssl_ipad[] = {
52 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
53 	0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636};
54 const uint32_t md5_ssl_opad[] = {
55 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
56 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
57 	0x5c5c5c5c, 0x5c5c5c5c};
58 const uint32_t sha1_ssl_opad[] = {
59 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
60 	0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c};
61 
62 /*
63  * Allocate and initialize a HMAC context, and save the context pointer in
64  * the session struct. For General-length HMAC, checks the length in the
65  * parameter to see if it is in the right range.
66  */
67 CK_RV
68 soft_hmac_sign_verify_init_common(soft_session_t *session_p,
69     CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op)
70 {
71 
72 	soft_hmac_ctx_t *hmac_ctx;
73 	CK_RV rv = CKR_OK;
74 
75 	if ((key_p->class != CKO_SECRET_KEY) ||
76 	    (key_p->key_type != CKK_GENERIC_SECRET)) {
77 		return (CKR_KEY_TYPE_INCONSISTENT);
78 	}
79 
80 	hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
81 
82 	if (hmac_ctx == NULL) {
83 		return (CKR_HOST_MEMORY);
84 	}
85 
86 	switch (pMechanism->mechanism) {
87 	case CKM_MD5_HMAC:
88 		hmac_ctx->hmac_len = MD5_HASH_SIZE;
89 		break;
90 
91 	case CKM_SHA_1_HMAC:
92 		hmac_ctx->hmac_len = SHA1_HASH_SIZE;
93 		break;
94 
95 	case CKM_SHA256_HMAC:
96 		hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
97 		break;
98 
99 	case CKM_SHA384_HMAC:
100 		hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
101 		break;
102 
103 	case CKM_SHA512_HMAC:
104 		hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
105 		break;
106 
107 	case CKM_MD5_HMAC_GENERAL:
108 	case CKM_SSL3_MD5_MAC:
109 		if ((pMechanism->ulParameterLen !=
110 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
111 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
112 			MD5_HASH_SIZE)) {
113 				free(hmac_ctx);
114 				return (CKR_MECHANISM_PARAM_INVALID);
115 			}
116 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
117 		    pMechanism->pParameter);
118 		break;
119 
120 	case CKM_SSL3_SHA1_MAC:
121 	case CKM_SHA_1_HMAC_GENERAL:
122 		if ((pMechanism->ulParameterLen !=
123 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
124 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
125 			SHA1_HASH_SIZE)) {
126 			free(hmac_ctx);
127 			return (CKR_MECHANISM_PARAM_INVALID);
128 		}
129 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
130 		    pMechanism->pParameter);
131 		break;
132 
133 	case CKM_SHA256_HMAC_GENERAL:
134 		if ((pMechanism->ulParameterLen !=
135 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
136 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
137 			SHA256_DIGEST_LENGTH)) {
138 			free(hmac_ctx);
139 			return (CKR_MECHANISM_PARAM_INVALID);
140 		}
141 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
142 		    pMechanism->pParameter);
143 		break;
144 
145 	case CKM_SHA384_HMAC_GENERAL:
146 	case CKM_SHA512_HMAC_GENERAL:
147 		if ((pMechanism->ulParameterLen !=
148 		    sizeof (CK_MAC_GENERAL_PARAMS)) &&
149 		    (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
150 			SHA512_DIGEST_LENGTH)) {
151 			free(hmac_ctx);
152 			return (CKR_MECHANISM_PARAM_INVALID);
153 		}
154 
155 		hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
156 		    pMechanism->pParameter);
157 		break;
158 
159 	}
160 
161 
162 	/* Initialize a MAC context. */
163 	rv = mac_init_ctx(session_p, key_p, hmac_ctx, pMechanism->mechanism);
164 	if (rv != CKR_OK)
165 		return (rv);
166 
167 	(void) pthread_mutex_lock(&session_p->session_mutex);
168 
169 	if (sign_op) {
170 		session_p->sign.mech.mechanism = pMechanism->mechanism;
171 		session_p->sign.context = hmac_ctx;
172 	} else {
173 		session_p->verify.mech.mechanism = pMechanism->mechanism;
174 		session_p->verify.context = hmac_ctx;
175 	}
176 
177 	(void) pthread_mutex_unlock(&session_p->session_mutex);
178 
179 	return (CKR_OK);
180 }
181 
182 
183 /*
184  * Initialize a HMAC context.
185  */
186 CK_RV
187 mac_init_ctx(soft_session_t *session_p, soft_object_t *key,
188     soft_hmac_ctx_t *ctx, CK_MECHANISM_TYPE mech)
189 {
190 	CK_RV rv = CKR_OK;
191 
192 	switch (mech) {
193 	case CKM_SSL3_MD5_MAC:
194 	{
195 		CK_BYTE md5_ipad[MD5_SSL_PAD_AND_KEY_SIZE];
196 		CK_BYTE md5_opad[MD5_SSL_PAD_AND_KEY_SIZE];
197 
198 		if (OBJ_SEC(key)->sk_value_len > MD5_SSL_PAD_AND_KEY_SIZE) {
199 			return (CKR_KEY_SIZE_RANGE);
200 		}
201 
202 		bzero(md5_ipad, MD5_SSL_PAD_AND_KEY_SIZE);
203 		bzero(md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
204 
205 		/* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
206 		(void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
207 		    OBJ_SEC(key)->sk_value_len);
208 		(void) memcpy(&md5_ipad[OBJ_SEC(key)->sk_value_len],
209 		    md5_ssl_ipad, MD5_SSL_PAD_SIZE);
210 		(void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
211 		    OBJ_SEC(key)->sk_value_len);
212 		(void) memcpy(&md5_opad[OBJ_SEC(key)->sk_value_len],
213 		    md5_ssl_opad, MD5_SSL_PAD_SIZE);
214 
215 		SOFT_MAC_INIT_CTX(MD5, &(ctx->hc_ctx_u.md5_ctx),
216 		    md5_ipad, md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
217 
218 		break;
219 	}
220 	case CKM_MD5_HMAC_GENERAL:
221 	case CKM_MD5_HMAC:
222 	{
223 		uint32_t md5_ipad[MD5_HMAC_INTS_PER_BLOCK];
224 		uint32_t md5_opad[MD5_HMAC_INTS_PER_BLOCK];
225 		CK_MECHANISM digest_mech;
226 		CK_ULONG hash_len = MD5_HASH_SIZE;
227 
228 		bzero(md5_ipad, MD5_HMAC_BLOCK_SIZE);
229 		bzero(md5_opad, MD5_HMAC_BLOCK_SIZE);
230 
231 		if (OBJ_SEC(key)->sk_value_len > MD5_HMAC_BLOCK_SIZE) {
232 			/*
233 			 * Hash the key when it is longer than 64 bytes.
234 			 */
235 			digest_mech.mechanism = CKM_MD5;
236 			digest_mech.pParameter = NULL_PTR;
237 			digest_mech.ulParameterLen = 0;
238 			rv = soft_digest_init_internal(session_p, &digest_mech);
239 			if (rv != CKR_OK)
240 				return (rv);
241 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
242 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)md5_ipad,
243 			    &hash_len);
244 			session_p->digest.flags = 0;
245 			if (rv != CKR_OK)
246 				return (rv);
247 			(void) memcpy(md5_opad, md5_ipad, hash_len);
248 		} else {
249 			(void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
250 			    OBJ_SEC(key)->sk_value_len);
251 			(void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
252 			    OBJ_SEC(key)->sk_value_len);
253 		}
254 
255 		md5_hmac_ctx_init(&ctx->hc_ctx_u.md5_ctx, md5_ipad, md5_opad);
256 		break;
257 	}
258 
259 	case CKM_SSL3_SHA1_MAC:
260 	{
261 		CK_BYTE sha1_ipad[SHA1_SSL_PAD_AND_KEY_SIZE];
262 		CK_BYTE sha1_opad[SHA1_SSL_PAD_AND_KEY_SIZE];
263 
264 		if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
265 			return (CKR_KEY_SIZE_RANGE);
266 		}
267 
268 		bzero(sha1_ipad, SHA1_SSL_PAD_AND_KEY_SIZE);
269 		bzero(sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
270 
271 		/* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
272 		(void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
273 		    OBJ_SEC(key)->sk_value_len);
274 		(void) memcpy(&sha1_ipad[OBJ_SEC(key)->sk_value_len],
275 		    sha1_ssl_ipad, SHA1_SSL_PAD_SIZE);
276 		(void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
277 		    OBJ_SEC(key)->sk_value_len);
278 		(void) memcpy(&sha1_opad[OBJ_SEC(key)->sk_value_len],
279 		    sha1_ssl_opad, SHA1_SSL_PAD_SIZE);
280 
281 		SOFT_MAC_INIT_CTX(SHA1, &(ctx->hc_ctx_u.sha1_ctx),
282 		    sha1_ipad, sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
283 
284 		break;
285 	}
286 	case CKM_SHA_1_HMAC_GENERAL:
287 	case CKM_SHA_1_HMAC:
288 	{
289 		uint32_t sha1_ipad[SHA1_HMAC_INTS_PER_BLOCK];
290 		uint32_t sha1_opad[SHA1_HMAC_INTS_PER_BLOCK];
291 		CK_MECHANISM digest_mech;
292 		CK_ULONG hash_len = SHA1_HASH_SIZE;
293 
294 		bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
295 		bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
296 
297 		if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
298 			/*
299 			 * Hash the key when it is longer than 64 bytes.
300 			 */
301 			digest_mech.mechanism = CKM_SHA_1;
302 			digest_mech.pParameter = NULL_PTR;
303 			digest_mech.ulParameterLen = 0;
304 			rv = soft_digest_init_internal(session_p, &digest_mech);
305 			if (rv != CKR_OK)
306 				return (rv);
307 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
308 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha1_ipad,
309 			    &hash_len);
310 			session_p->digest.flags = 0;
311 			if (rv != CKR_OK)
312 				return (rv);
313 			(void) memcpy(sha1_opad, sha1_ipad, hash_len);
314 		} else {
315 			(void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
316 			    OBJ_SEC(key)->sk_value_len);
317 			(void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
318 			    OBJ_SEC(key)->sk_value_len);
319 		}
320 
321 		sha1_hmac_ctx_init(&ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
322 		    sha1_opad);
323 
324 		break;
325 	}
326 	case CKM_SHA256_HMAC:
327 	case CKM_SHA256_HMAC_GENERAL:
328 	{
329 		uint64_t sha_ipad[SHA256_HMAC_INTS_PER_BLOCK];
330 		uint64_t sha_opad[SHA256_HMAC_INTS_PER_BLOCK];
331 		CK_MECHANISM digest_mech;
332 		CK_ULONG hash_len = SHA256_DIGEST_LENGTH;
333 
334 		bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
335 		bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
336 
337 		if (OBJ_SEC(key)->sk_value_len > SHA256_HMAC_BLOCK_SIZE) {
338 			/*
339 			 * Hash the key when it is longer than 64 bytes.
340 			 */
341 			digest_mech.mechanism = CKM_SHA256;
342 			digest_mech.pParameter = NULL_PTR;
343 			digest_mech.ulParameterLen = 0;
344 			rv = soft_digest_init_internal(session_p, &digest_mech);
345 			if (rv != CKR_OK)
346 				return (rv);
347 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
348 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
349 			    &hash_len);
350 			session_p->digest.flags = 0;
351 			if (rv != CKR_OK)
352 				return (rv);
353 			(void) memcpy(sha_opad, sha_ipad, hash_len);
354 		} else {
355 			(void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
356 			    OBJ_SEC(key)->sk_value_len);
357 			(void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
358 			    OBJ_SEC(key)->sk_value_len);
359 		}
360 
361 		sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
362 		    sha_ipad, sha_opad, SHA256_HMAC_INTS_PER_BLOCK,
363 		    SHA256_HMAC_BLOCK_SIZE);
364 
365 		break;
366 	}
367 	case CKM_SHA384_HMAC:
368 	case CKM_SHA384_HMAC_GENERAL:
369 	{
370 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
371 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
372 		CK_MECHANISM digest_mech;
373 		CK_ULONG hash_len = SHA384_DIGEST_LENGTH;
374 
375 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
376 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
377 
378 		if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
379 			/*
380 			 * Hash the key when it is longer than 64 bytes.
381 			 */
382 			digest_mech.mechanism = CKM_SHA384;
383 			digest_mech.pParameter = NULL_PTR;
384 			digest_mech.ulParameterLen = 0;
385 			rv = soft_digest_init_internal(session_p, &digest_mech);
386 			if (rv != CKR_OK)
387 				return (rv);
388 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
389 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
390 			    &hash_len);
391 			session_p->digest.flags = 0;
392 			if (rv != CKR_OK)
393 				return (rv);
394 			(void) memcpy(sha_opad, sha_ipad, hash_len);
395 		} else {
396 			(void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
397 			    OBJ_SEC(key)->sk_value_len);
398 			(void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
399 			    OBJ_SEC(key)->sk_value_len);
400 		}
401 
402 		sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
403 		    sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
404 		    SHA512_HMAC_BLOCK_SIZE);
405 
406 		break;
407 	}
408 	case CKM_SHA512_HMAC:
409 	case CKM_SHA512_HMAC_GENERAL:
410 	{
411 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
412 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
413 		CK_MECHANISM digest_mech;
414 		CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
415 
416 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
417 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
418 
419 		if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
420 			/*
421 			 * Hash the key when it is longer than 64 bytes.
422 			 */
423 			digest_mech.mechanism = CKM_SHA512;
424 			digest_mech.pParameter = NULL_PTR;
425 			digest_mech.ulParameterLen = 0;
426 			rv = soft_digest_init_internal(session_p, &digest_mech);
427 			if (rv != CKR_OK)
428 				return (rv);
429 			rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
430 			    OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
431 			    &hash_len);
432 			session_p->digest.flags = 0;
433 			if (rv != CKR_OK)
434 				return (rv);
435 			(void) memcpy(sha_opad, sha_ipad, hash_len);
436 		} else {
437 			(void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
438 			    OBJ_SEC(key)->sk_value_len);
439 			(void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
440 			    OBJ_SEC(key)->sk_value_len);
441 		}
442 
443 		sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
444 		    sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
445 		    SHA512_HMAC_BLOCK_SIZE);
446 
447 		break;
448 	}
449 	}
450 	return (rv);
451 }
452 
453 
454 /*
455  * Called by soft_sign(), soft_sign_final(), soft_verify() or
456  * soft_verify_final().
457  */
458 CK_RV
459 soft_hmac_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
460     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen,
461     boolean_t sign_op)
462 {
463 
464 	soft_hmac_ctx_t	*hmac_ctx;
465 	CK_MECHANISM_TYPE	mechanism;
466 #ifdef	__sparcv9
467 	/* LINTED */
468 	uint_t datalen = (uint_t)ulDataLen;
469 #else	/* __sparcv9 */
470 	uint_t datalen = ulDataLen;
471 #endif	/* __sparcv9 */
472 
473 	if (sign_op) {
474 		hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
475 		mechanism = session_p->sign.mech.mechanism;
476 
477 		/*
478 		 * If application asks for the length of the output buffer
479 		 * to hold the signature?
480 		 */
481 		if (pSigned == NULL) {
482 			*pulSignedLen = hmac_ctx->hmac_len;
483 			return (CKR_OK);
484 		}
485 
486 		/* Is the application-supplied buffer large enough? */
487 		if (*pulSignedLen < hmac_ctx->hmac_len) {
488 			*pulSignedLen = hmac_ctx->hmac_len;
489 			return (CKR_BUFFER_TOO_SMALL);
490 		}
491 	} else {
492 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
493 		mechanism = session_p->verify.mech.mechanism;
494 	}
495 
496 	switch (mechanism) {
497 
498 	case CKM_SSL3_MD5_MAC:
499 	case CKM_MD5_HMAC_GENERAL:
500 	case CKM_MD5_HMAC:
501 
502 		if (pData != NULL) {
503 			/* Called by soft_sign() or soft_verify(). */
504 			SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx),
505 			    pData, datalen);
506 		}
507 		SOFT_MAC_FINAL(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pSigned);
508 		break;
509 
510 	case CKM_SSL3_SHA1_MAC:
511 	case CKM_SHA_1_HMAC_GENERAL:
512 	case CKM_SHA_1_HMAC:
513 
514 		if (pData != NULL) {
515 			/* Called by soft_sign() or soft_verify(). */
516 			SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx),
517 			    pData, datalen);
518 		}
519 		SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pSigned);
520 		break;
521 
522 	case CKM_SHA256_HMAC_GENERAL:
523 	case CKM_SHA256_HMAC:
524 		if (pData != NULL)
525 			/* Called by soft_sign() or soft_verify(). */
526 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
527 			    pData, datalen);
528 
529 		SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
530 		    pSigned);
531 		break;
532 
533 	case CKM_SHA384_HMAC_GENERAL:
534 	case CKM_SHA384_HMAC:
535 		if (pData != NULL)
536 			/* Called by soft_sign() or soft_verify(). */
537 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
538 			    pData, datalen);
539 
540 		SOFT_MAC_FINAL_2(SHA384, &(hmac_ctx->hc_ctx_u.sha2_ctx),
541 		    pSigned);
542 		hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
543 		break;
544 
545 	case CKM_SHA512_HMAC_GENERAL:
546 	case CKM_SHA512_HMAC:
547 
548 		if (pData != NULL)
549 			/* Called by soft_sign() or soft_verify(). */
550 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
551 			    pData, datalen);
552 
553 		SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
554 		    pSigned);
555 	};
556 
557 	*pulSignedLen = hmac_ctx->hmac_len;
558 
559 
560 clean_exit:
561 
562 	(void) pthread_mutex_lock(&session_p->session_mutex);
563 
564 	if (sign_op) {
565 		bzero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
566 		free(session_p->sign.context);
567 		session_p->sign.context = NULL;
568 	} else {
569 		bzero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
570 		free(session_p->verify.context);
571 		session_p->verify.context = NULL;
572 	}
573 
574 	(void) pthread_mutex_unlock(&session_p->session_mutex);
575 
576 	return (CKR_OK);
577 }
578 
579 
580 /*
581  * Called by soft_sign_update() or soft_verify_update().
582  */
583 CK_RV
584 soft_hmac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
585 	CK_ULONG ulPartLen, boolean_t sign_op)
586 {
587 
588 	soft_hmac_ctx_t	*hmac_ctx;
589 	CK_MECHANISM_TYPE	mechanism;
590 #ifdef	__sparcv9
591 	/* LINTED */
592 	uint_t partlen = (uint_t)ulPartLen;
593 #else	/* __sparcv9 */
594 	uint_t partlen = ulPartLen;
595 #endif	/* __sparcv9 */
596 
597 	if (sign_op) {
598 		hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
599 		mechanism = session_p->sign.mech.mechanism;
600 	} else {
601 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
602 		mechanism = session_p->verify.mech.mechanism;
603 	}
604 
605 	switch (mechanism) {
606 
607 	case CKM_SSL3_MD5_MAC:
608 	case CKM_MD5_HMAC_GENERAL:
609 	case CKM_MD5_HMAC:
610 
611 		SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pPart,
612 		    partlen);
613 		break;
614 
615 	case CKM_SSL3_SHA1_MAC:
616 	case CKM_SHA_1_HMAC_GENERAL:
617 	case CKM_SHA_1_HMAC:
618 
619 		SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pPart,
620 		    partlen);
621 
622 		break;
623 
624 	case CKM_SHA256_HMAC_GENERAL:
625 	case CKM_SHA256_HMAC:
626 	case CKM_SHA384_HMAC_GENERAL:
627 	case CKM_SHA384_HMAC:
628 	case CKM_SHA512_HMAC_GENERAL:
629 	case CKM_SHA512_HMAC:
630 
631 		SOFT_MAC_UPDATE(SHA2, &(hmac_ctx->hc_ctx_u.sha2_ctx), pPart,
632 		    partlen);
633 		break;
634 
635 	}
636 	return (CKR_OK);
637 }
638 
639 /*
640  * The following 2 functions expect the MAC key to be alreay copied in
641  * the ipad and opad
642  */
643 void
644 md5_hmac_ctx_init(md5_hc_ctx_t *md5_hmac_ctx, uint32_t *ipad, uint32_t *opad)
645 {
646 	int i;
647 	/* XOR key with ipad (0x36) and opad (0x5c) */
648 	for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
649 		ipad[i] ^= 0x36363636;
650 		opad[i] ^= 0x5c5c5c5c;
651 	}
652 	SOFT_MAC_INIT_CTX(MD5, md5_hmac_ctx, ipad, opad, MD5_HMAC_BLOCK_SIZE);
653 }
654 
655 void
656 sha1_hmac_ctx_init(sha1_hc_ctx_t *sha1_hmac_ctx, uint32_t *ipad, uint32_t *opad)
657 {
658 	int i;
659 	/* XOR key with ipad (0x36) and opad (0x5c) */
660 	for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
661 		ipad[i] ^= 0x36363636;
662 		opad[i] ^= 0x5c5c5c5c;
663 	}
664 	SOFT_MAC_INIT_CTX(SHA1, sha1_hmac_ctx, (const uchar_t *)ipad,
665 	    (const uchar_t *)opad, SHA1_HMAC_BLOCK_SIZE);
666 }
667 
668 
669 void
670 sha2_hmac_ctx_init(uint_t mech, sha2_hc_ctx_t *ctx, uint64_t *ipad,
671     uint64_t *opad, uint_t blocks_per_int64, uint_t block_size)
672 {
673 	int i;
674 
675 	/* XOR key with ipad (0x36) and opad (0x5c) */
676 	for (i = 0; i < blocks_per_int64; i ++) {
677 		ipad[i] ^= 0x3636363636363636ULL;
678 		opad[i] ^= 0x5c5c5c5c5c5c5c5cULL;
679 	}
680 
681 	/* perform SHA2 on ipad */
682 	SHA2Init(mech, &ctx->hc_icontext);
683 	SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
684 
685 	/* perform SHA2 on opad */
686 	SHA2Init(mech, &ctx->hc_ocontext);
687 	SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
688 
689 }
690