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