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