dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softMAC.c
blobf608d1b42b4446ca8e2810f66bc99591ae0d8514
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 uint_t datalen = ulDataLen;
468 if (sign_op) {
469 hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
470 mechanism = session_p->sign.mech.mechanism;
473 * If application asks for the length of the output buffer
474 * to hold the signature?
476 if (pSigned == NULL) {
477 *pulSignedLen = hmac_ctx->hmac_len;
478 return (CKR_OK);
481 /* Is the application-supplied buffer large enough? */
482 if (*pulSignedLen < hmac_ctx->hmac_len) {
483 *pulSignedLen = hmac_ctx->hmac_len;
484 return (CKR_BUFFER_TOO_SMALL);
486 } else {
487 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
488 mechanism = session_p->verify.mech.mechanism;
491 switch (mechanism) {
493 case CKM_SSL3_MD5_MAC:
494 case CKM_MD5_HMAC_GENERAL:
495 case CKM_MD5_HMAC:
497 if (pData != NULL) {
498 /* Called by soft_sign() or soft_verify(). */
499 SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx),
500 pData, datalen);
502 SOFT_MAC_FINAL(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pSigned);
503 break;
505 case CKM_SSL3_SHA1_MAC:
506 case CKM_SHA_1_HMAC_GENERAL:
507 case CKM_SHA_1_HMAC:
509 if (pData != NULL) {
510 /* Called by soft_sign() or soft_verify(). */
511 SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx),
512 pData, datalen);
514 SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pSigned);
515 break;
517 case CKM_SHA256_HMAC_GENERAL:
518 case CKM_SHA256_HMAC:
519 if (pData != NULL)
520 /* Called by soft_sign() or soft_verify(). */
521 SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
522 pData, datalen);
524 SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
525 pSigned);
526 break;
528 case CKM_SHA384_HMAC_GENERAL:
529 case CKM_SHA384_HMAC:
530 if (pData != NULL)
531 /* Called by soft_sign() or soft_verify(). */
532 SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
533 pData, datalen);
535 SOFT_MAC_FINAL_2(SHA384, &(hmac_ctx->hc_ctx_u.sha2_ctx),
536 pSigned);
537 hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
538 break;
540 case CKM_SHA512_HMAC_GENERAL:
541 case CKM_SHA512_HMAC:
543 if (pData != NULL)
544 /* Called by soft_sign() or soft_verify(). */
545 SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
546 pData, datalen);
548 SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
549 pSigned);
552 *pulSignedLen = hmac_ctx->hmac_len;
555 clean_exit:
557 (void) pthread_mutex_lock(&session_p->session_mutex);
559 if (sign_op) {
560 bzero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
561 free(session_p->sign.context);
562 session_p->sign.context = NULL;
563 } else {
564 bzero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
565 free(session_p->verify.context);
566 session_p->verify.context = NULL;
569 (void) pthread_mutex_unlock(&session_p->session_mutex);
571 return (CKR_OK);
576 * Called by soft_sign_update() or soft_verify_update().
578 CK_RV
579 soft_hmac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
580 CK_ULONG ulPartLen, boolean_t sign_op)
583 soft_hmac_ctx_t *hmac_ctx;
584 CK_MECHANISM_TYPE mechanism;
585 uint_t partlen = ulPartLen;
587 if (sign_op) {
588 hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
589 mechanism = session_p->sign.mech.mechanism;
590 } else {
591 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
592 mechanism = session_p->verify.mech.mechanism;
595 switch (mechanism) {
597 case CKM_SSL3_MD5_MAC:
598 case CKM_MD5_HMAC_GENERAL:
599 case CKM_MD5_HMAC:
601 SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pPart,
602 partlen);
603 break;
605 case CKM_SSL3_SHA1_MAC:
606 case CKM_SHA_1_HMAC_GENERAL:
607 case CKM_SHA_1_HMAC:
609 SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pPart,
610 partlen);
612 break;
614 case CKM_SHA256_HMAC_GENERAL:
615 case CKM_SHA256_HMAC:
616 case CKM_SHA384_HMAC_GENERAL:
617 case CKM_SHA384_HMAC:
618 case CKM_SHA512_HMAC_GENERAL:
619 case CKM_SHA512_HMAC:
621 SOFT_MAC_UPDATE(SHA2, &(hmac_ctx->hc_ctx_u.sha2_ctx), pPart,
622 partlen);
623 break;
626 return (CKR_OK);
630 * The following 2 functions expect the MAC key to be alreay copied in
631 * the ipad and opad
633 void
634 md5_hmac_ctx_init(md5_hc_ctx_t *md5_hmac_ctx, uint32_t *ipad, uint32_t *opad)
636 int i;
637 /* XOR key with ipad (0x36) and opad (0x5c) */
638 for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
639 ipad[i] ^= 0x36363636;
640 opad[i] ^= 0x5c5c5c5c;
642 SOFT_MAC_INIT_CTX(MD5, md5_hmac_ctx, ipad, opad, MD5_HMAC_BLOCK_SIZE);
645 void
646 sha1_hmac_ctx_init(sha1_hc_ctx_t *sha1_hmac_ctx, uint32_t *ipad, uint32_t *opad)
648 int i;
649 /* XOR key with ipad (0x36) and opad (0x5c) */
650 for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
651 ipad[i] ^= 0x36363636;
652 opad[i] ^= 0x5c5c5c5c;
654 SOFT_MAC_INIT_CTX(SHA1, sha1_hmac_ctx, (const uchar_t *)ipad,
655 (const uchar_t *)opad, SHA1_HMAC_BLOCK_SIZE);
659 void
660 sha2_hmac_ctx_init(uint_t mech, sha2_hc_ctx_t *ctx, uint64_t *ipad,
661 uint64_t *opad, uint_t blocks_per_int64, uint_t block_size)
663 int i;
665 /* XOR key with ipad (0x36) and opad (0x5c) */
666 for (i = 0; i < blocks_per_int64; i ++) {
667 ipad[i] ^= 0x3636363636363636ULL;
668 opad[i] ^= 0x5c5c5c5c5c5c5c5cULL;
671 /* perform SHA2 on ipad */
672 SHA2Init(mech, &ctx->hc_icontext);
673 SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
675 /* perform SHA2 on opad */
676 SHA2Init(mech, &ctx->hc_ocontext);
677 SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);