8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softMAC.c
blobb5930bf89ef596cb7fe2d727fef46c7ec37df9ff
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
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"
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
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};
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.
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)
72 soft_hmac_ctx_t *hmac_ctx;
73 CK_RV rv = CKR_OK;
75 if ((key_p->class != CKO_SECRET_KEY) ||
76 (key_p->key_type != CKK_GENERIC_SECRET)) {
77 return (CKR_KEY_TYPE_INCONSISTENT);
80 hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
82 if (hmac_ctx == NULL) {
83 return (CKR_HOST_MEMORY);
86 switch (pMechanism->mechanism) {
87 case CKM_MD5_HMAC:
88 hmac_ctx->hmac_len = MD5_HASH_SIZE;
89 break;
91 case CKM_SHA_1_HMAC:
92 hmac_ctx->hmac_len = SHA1_HASH_SIZE;
93 break;
95 case CKM_SHA256_HMAC:
96 hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
97 break;
99 case CKM_SHA384_HMAC:
100 hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
101 break;
103 case CKM_SHA512_HMAC:
104 hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
105 break;
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);
116 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
117 pMechanism->pParameter);
118 break;
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);
129 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
130 pMechanism->pParameter);
131 break;
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);
141 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
142 pMechanism->pParameter);
143 break;
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);
155 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
156 pMechanism->pParameter);
157 break;
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);
167 (void) pthread_mutex_lock(&session_p->session_mutex);
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;
177 (void) pthread_mutex_unlock(&session_p->session_mutex);
179 return (CKR_OK);
184 * Initialize a HMAC context.
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)
190 CK_RV rv = CKR_OK;
192 switch (mech) {
193 case CKM_SSL3_MD5_MAC:
195 CK_BYTE md5_ipad[MD5_SSL_PAD_AND_KEY_SIZE];
196 CK_BYTE md5_opad[MD5_SSL_PAD_AND_KEY_SIZE];
198 if (OBJ_SEC(key)->sk_value_len > MD5_SSL_PAD_AND_KEY_SIZE) {
199 return (CKR_KEY_SIZE_RANGE);
202 bzero(md5_ipad, MD5_SSL_PAD_AND_KEY_SIZE);
203 bzero(md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
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);
215 SOFT_MAC_INIT_CTX(MD5, &(ctx->hc_ctx_u.md5_ctx),
216 md5_ipad, md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
218 break;
220 case CKM_MD5_HMAC_GENERAL:
221 case CKM_MD5_HMAC:
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;
228 bzero(md5_ipad, MD5_HMAC_BLOCK_SIZE);
229 bzero(md5_opad, MD5_HMAC_BLOCK_SIZE);
231 if (OBJ_SEC(key)->sk_value_len > MD5_HMAC_BLOCK_SIZE) {
233 * Hash the key when it is longer than 64 bytes.
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);
255 md5_hmac_ctx_init(&ctx->hc_ctx_u.md5_ctx, md5_ipad, md5_opad);
256 break;
259 case CKM_SSL3_SHA1_MAC:
261 CK_BYTE sha1_ipad[SHA1_SSL_PAD_AND_KEY_SIZE];
262 CK_BYTE sha1_opad[SHA1_SSL_PAD_AND_KEY_SIZE];
264 if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
265 return (CKR_KEY_SIZE_RANGE);
268 bzero(sha1_ipad, SHA1_SSL_PAD_AND_KEY_SIZE);
269 bzero(sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
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);
281 SOFT_MAC_INIT_CTX(SHA1, &(ctx->hc_ctx_u.sha1_ctx),
282 sha1_ipad, sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
284 break;
286 case CKM_SHA_1_HMAC_GENERAL:
287 case CKM_SHA_1_HMAC:
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;
294 bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
295 bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
297 if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
299 * Hash the key when it is longer than 64 bytes.
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);
321 sha1_hmac_ctx_init(&ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
322 sha1_opad);
324 break;
326 case CKM_SHA256_HMAC:
327 case CKM_SHA256_HMAC_GENERAL:
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;
334 bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
335 bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
337 if (OBJ_SEC(key)->sk_value_len > SHA256_HMAC_BLOCK_SIZE) {
339 * Hash the key when it is longer than 64 bytes.
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);
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);
365 break;
367 case CKM_SHA384_HMAC:
368 case CKM_SHA384_HMAC_GENERAL:
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;
375 bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
376 bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
378 if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
380 * Hash the key when it is longer than 64 bytes.
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);
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);
406 break;
408 case CKM_SHA512_HMAC:
409 case CKM_SHA512_HMAC_GENERAL:
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;
416 bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
417 bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
419 if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
421 * Hash the key when it is longer than 64 bytes.
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);
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);
447 break;
450 return (rv);
455 * Called by soft_sign(), soft_sign_final(), soft_verify() or
456 * soft_verify_final().
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)
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 */
473 if (sign_op) {
474 hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
475 mechanism = session_p->sign.mech.mechanism;
478 * If application asks for the length of the output buffer
479 * to hold the signature?
481 if (pSigned == NULL) {
482 *pulSignedLen = hmac_ctx->hmac_len;
483 return (CKR_OK);
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);
491 } else {
492 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
493 mechanism = session_p->verify.mech.mechanism;
496 switch (mechanism) {
498 case CKM_SSL3_MD5_MAC:
499 case CKM_MD5_HMAC_GENERAL:
500 case CKM_MD5_HMAC:
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);
507 SOFT_MAC_FINAL(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pSigned);
508 break;
510 case CKM_SSL3_SHA1_MAC:
511 case CKM_SHA_1_HMAC_GENERAL:
512 case CKM_SHA_1_HMAC:
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);
519 SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pSigned);
520 break;
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);
529 SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
530 pSigned);
531 break;
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);
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;
545 case CKM_SHA512_HMAC_GENERAL:
546 case CKM_SHA512_HMAC:
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);
553 SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
554 pSigned);
557 *pulSignedLen = hmac_ctx->hmac_len;
560 clean_exit:
562 (void) pthread_mutex_lock(&session_p->session_mutex);
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;
574 (void) pthread_mutex_unlock(&session_p->session_mutex);
576 return (CKR_OK);
581 * Called by soft_sign_update() or soft_verify_update().
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)
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 */
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;
605 switch (mechanism) {
607 case CKM_SSL3_MD5_MAC:
608 case CKM_MD5_HMAC_GENERAL:
609 case CKM_MD5_HMAC:
611 SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pPart,
612 partlen);
613 break;
615 case CKM_SSL3_SHA1_MAC:
616 case CKM_SHA_1_HMAC_GENERAL:
617 case CKM_SHA_1_HMAC:
619 SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pPart,
620 partlen);
622 break;
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:
631 SOFT_MAC_UPDATE(SHA2, &(hmac_ctx->hc_ctx_u.sha2_ctx), pPart,
632 partlen);
633 break;
636 return (CKR_OK);
640 * The following 2 functions expect the MAC key to be alreay copied in
641 * the ipad and opad
643 void
644 md5_hmac_ctx_init(md5_hc_ctx_t *md5_hmac_ctx, uint32_t *ipad, uint32_t *opad)
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;
652 SOFT_MAC_INIT_CTX(MD5, md5_hmac_ctx, ipad, opad, MD5_HMAC_BLOCK_SIZE);
655 void
656 sha1_hmac_ctx_init(sha1_hc_ctx_t *sha1_hmac_ctx, uint32_t *ipad, uint32_t *opad)
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;
664 SOFT_MAC_INIT_CTX(SHA1, sha1_hmac_ctx, (const uchar_t *)ipad,
665 (const uchar_t *)opad, SHA1_HMAC_BLOCK_SIZE);
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)
673 int i;
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;
681 /* perform SHA2 on ipad */
682 SHA2Init(mech, &ctx->hc_icontext);
683 SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
685 /* perform SHA2 on opad */
686 SHA2Init(mech, &ctx->hc_ocontext);
687 SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);