10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23676Sizick * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <pthread.h>
300Sstevel@tonic-gate #include <sys/md5.h>
310Sstevel@tonic-gate #include <sys/sha1.h>
32676Sizick #include <sys/sha2.h>
330Sstevel@tonic-gate #include <stdlib.h>
340Sstevel@tonic-gate #include <string.h>
350Sstevel@tonic-gate #include <strings.h>
360Sstevel@tonic-gate #include <sys/types.h>
370Sstevel@tonic-gate #include <security/cryptoki.h>
380Sstevel@tonic-gate #include "softObject.h"
390Sstevel@tonic-gate #include "softOps.h"
400Sstevel@tonic-gate #include "softSession.h"
410Sstevel@tonic-gate #include "softMAC.h"
420Sstevel@tonic-gate
430Sstevel@tonic-gate /*
440Sstevel@tonic-gate * IPAD = 0x36 repeated 48 times for ssl md5, repeated 40 times for ssl sha1
450Sstevel@tonic-gate * OPAD = 0x5C repeated 48 times for SSL md5, repeated 40 times for ssl sha1
460Sstevel@tonic-gate */
470Sstevel@tonic-gate const uint32_t md5_ssl_ipad[] = {
480Sstevel@tonic-gate 0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
490Sstevel@tonic-gate 0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
500Sstevel@tonic-gate 0x36363636, 0x36363636};
510Sstevel@tonic-gate const uint32_t sha1_ssl_ipad[] = {
520Sstevel@tonic-gate 0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
530Sstevel@tonic-gate 0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636};
540Sstevel@tonic-gate const uint32_t md5_ssl_opad[] = {
550Sstevel@tonic-gate 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
560Sstevel@tonic-gate 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
570Sstevel@tonic-gate 0x5c5c5c5c, 0x5c5c5c5c};
580Sstevel@tonic-gate const uint32_t sha1_ssl_opad[] = {
590Sstevel@tonic-gate 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
600Sstevel@tonic-gate 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c};
610Sstevel@tonic-gate
620Sstevel@tonic-gate /*
630Sstevel@tonic-gate * Allocate and initialize a HMAC context, and save the context pointer in
640Sstevel@tonic-gate * the session struct. For General-length HMAC, checks the length in the
650Sstevel@tonic-gate * parameter to see if it is in the right range.
660Sstevel@tonic-gate */
670Sstevel@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)680Sstevel@tonic-gate soft_hmac_sign_verify_init_common(soft_session_t *session_p,
690Sstevel@tonic-gate CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op)
700Sstevel@tonic-gate {
710Sstevel@tonic-gate
720Sstevel@tonic-gate soft_hmac_ctx_t *hmac_ctx;
730Sstevel@tonic-gate CK_RV rv = CKR_OK;
740Sstevel@tonic-gate
750Sstevel@tonic-gate if ((key_p->class != CKO_SECRET_KEY) ||
760Sstevel@tonic-gate (key_p->key_type != CKK_GENERIC_SECRET)) {
770Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
780Sstevel@tonic-gate }
790Sstevel@tonic-gate
800Sstevel@tonic-gate hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
810Sstevel@tonic-gate
820Sstevel@tonic-gate if (hmac_ctx == NULL) {
830Sstevel@tonic-gate return (CKR_HOST_MEMORY);
840Sstevel@tonic-gate }
850Sstevel@tonic-gate
860Sstevel@tonic-gate switch (pMechanism->mechanism) {
87676Sizick case CKM_MD5_HMAC:
88676Sizick hmac_ctx->hmac_len = MD5_HASH_SIZE;
89676Sizick break;
900Sstevel@tonic-gate
91676Sizick case CKM_SHA_1_HMAC:
92676Sizick hmac_ctx->hmac_len = SHA1_HASH_SIZE;
93676Sizick break;
94676Sizick
95676Sizick case CKM_SHA256_HMAC:
96676Sizick hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
97676Sizick break;
98676Sizick
99676Sizick case CKM_SHA384_HMAC:
100676Sizick hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
101676Sizick break;
102676Sizick
103676Sizick case CKM_SHA512_HMAC:
104676Sizick hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
105676Sizick break;
106676Sizick
1070Sstevel@tonic-gate case CKM_MD5_HMAC_GENERAL:
108676Sizick case CKM_SSL3_MD5_MAC:
109676Sizick if ((pMechanism->ulParameterLen !=
110676Sizick sizeof (CK_MAC_GENERAL_PARAMS)) &&
111676Sizick (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
112676Sizick MD5_HASH_SIZE)) {
113676Sizick free(hmac_ctx);
114676Sizick return (CKR_MECHANISM_PARAM_INVALID);
115676Sizick }
116676Sizick hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
117676Sizick pMechanism->pParameter);
118676Sizick break;
1190Sstevel@tonic-gate
120676Sizick case CKM_SSL3_SHA1_MAC:
121676Sizick case CKM_SHA_1_HMAC_GENERAL:
122676Sizick if ((pMechanism->ulParameterLen !=
123676Sizick sizeof (CK_MAC_GENERAL_PARAMS)) &&
124676Sizick (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
125676Sizick SHA1_HASH_SIZE)) {
1260Sstevel@tonic-gate free(hmac_ctx);
1270Sstevel@tonic-gate return (CKR_MECHANISM_PARAM_INVALID);
1280Sstevel@tonic-gate }
129676Sizick hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
130676Sizick pMechanism->pParameter);
131676Sizick break;
1320Sstevel@tonic-gate
133676Sizick case CKM_SHA256_HMAC_GENERAL:
134676Sizick if ((pMechanism->ulParameterLen !=
135676Sizick sizeof (CK_MAC_GENERAL_PARAMS)) &&
136676Sizick (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
137676Sizick SHA256_DIGEST_LENGTH)) {
138676Sizick free(hmac_ctx);
139676Sizick return (CKR_MECHANISM_PARAM_INVALID);
140676Sizick }
141676Sizick hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
142676Sizick pMechanism->pParameter);
143676Sizick break;
144676Sizick
145676Sizick case CKM_SHA384_HMAC_GENERAL:
146676Sizick case CKM_SHA512_HMAC_GENERAL:
147676Sizick if ((pMechanism->ulParameterLen !=
148676Sizick sizeof (CK_MAC_GENERAL_PARAMS)) &&
149676Sizick (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
150676Sizick SHA512_DIGEST_LENGTH)) {
151676Sizick free(hmac_ctx);
152676Sizick return (CKR_MECHANISM_PARAM_INVALID);
1530Sstevel@tonic-gate }
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
1560Sstevel@tonic-gate pMechanism->pParameter);
157676Sizick break;
1580Sstevel@tonic-gate
159676Sizick }
160676Sizick
1610Sstevel@tonic-gate
162676Sizick /* Initialize a MAC context. */
163676Sizick rv = mac_init_ctx(session_p, key_p, hmac_ctx, pMechanism->mechanism);
164676Sizick if (rv != CKR_OK)
165676Sizick return (rv);
1660Sstevel@tonic-gate
167676Sizick (void) pthread_mutex_lock(&session_p->session_mutex);
1680Sstevel@tonic-gate
169676Sizick if (sign_op) {
170676Sizick session_p->sign.mech.mechanism = pMechanism->mechanism;
171676Sizick session_p->sign.context = hmac_ctx;
172676Sizick } else {
173676Sizick session_p->verify.mech.mechanism = pMechanism->mechanism;
174676Sizick session_p->verify.context = hmac_ctx;
175676Sizick }
1760Sstevel@tonic-gate
177676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate return (CKR_OK);
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate /*
1840Sstevel@tonic-gate * Initialize a HMAC context.
1850Sstevel@tonic-gate */
1860Sstevel@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)1870Sstevel@tonic-gate mac_init_ctx(soft_session_t *session_p, soft_object_t *key,
1880Sstevel@tonic-gate soft_hmac_ctx_t *ctx, CK_MECHANISM_TYPE mech)
1890Sstevel@tonic-gate {
1900Sstevel@tonic-gate CK_RV rv = CKR_OK;
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate switch (mech) {
1930Sstevel@tonic-gate case CKM_SSL3_MD5_MAC:
1940Sstevel@tonic-gate {
1950Sstevel@tonic-gate CK_BYTE md5_ipad[MD5_SSL_PAD_AND_KEY_SIZE];
1960Sstevel@tonic-gate CK_BYTE md5_opad[MD5_SSL_PAD_AND_KEY_SIZE];
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate if (OBJ_SEC(key)->sk_value_len > MD5_SSL_PAD_AND_KEY_SIZE) {
1990Sstevel@tonic-gate return (CKR_KEY_SIZE_RANGE);
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate bzero(md5_ipad, MD5_SSL_PAD_AND_KEY_SIZE);
2030Sstevel@tonic-gate bzero(md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate /* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
2060Sstevel@tonic-gate (void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
2070Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
2080Sstevel@tonic-gate (void) memcpy(&md5_ipad[OBJ_SEC(key)->sk_value_len],
2090Sstevel@tonic-gate md5_ssl_ipad, MD5_SSL_PAD_SIZE);
2100Sstevel@tonic-gate (void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
2110Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
2120Sstevel@tonic-gate (void) memcpy(&md5_opad[OBJ_SEC(key)->sk_value_len],
2130Sstevel@tonic-gate md5_ssl_opad, MD5_SSL_PAD_SIZE);
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate SOFT_MAC_INIT_CTX(MD5, &(ctx->hc_ctx_u.md5_ctx),
2160Sstevel@tonic-gate md5_ipad, md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate break;
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate case CKM_MD5_HMAC_GENERAL:
2210Sstevel@tonic-gate case CKM_MD5_HMAC:
2220Sstevel@tonic-gate {
2230Sstevel@tonic-gate uint32_t md5_ipad[MD5_HMAC_INTS_PER_BLOCK];
2240Sstevel@tonic-gate uint32_t md5_opad[MD5_HMAC_INTS_PER_BLOCK];
2250Sstevel@tonic-gate CK_MECHANISM digest_mech;
2260Sstevel@tonic-gate CK_ULONG hash_len = MD5_HASH_SIZE;
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate bzero(md5_ipad, MD5_HMAC_BLOCK_SIZE);
2290Sstevel@tonic-gate bzero(md5_opad, MD5_HMAC_BLOCK_SIZE);
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate if (OBJ_SEC(key)->sk_value_len > MD5_HMAC_BLOCK_SIZE) {
2320Sstevel@tonic-gate /*
2330Sstevel@tonic-gate * Hash the key when it is longer than 64 bytes.
2340Sstevel@tonic-gate */
2350Sstevel@tonic-gate digest_mech.mechanism = CKM_MD5;
2360Sstevel@tonic-gate digest_mech.pParameter = NULL_PTR;
2370Sstevel@tonic-gate digest_mech.ulParameterLen = 0;
2380Sstevel@tonic-gate rv = soft_digest_init_internal(session_p, &digest_mech);
2390Sstevel@tonic-gate if (rv != CKR_OK)
2400Sstevel@tonic-gate return (rv);
2410Sstevel@tonic-gate rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
2420Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)md5_ipad,
2430Sstevel@tonic-gate &hash_len);
2440Sstevel@tonic-gate session_p->digest.flags = 0;
2450Sstevel@tonic-gate if (rv != CKR_OK)
2460Sstevel@tonic-gate return (rv);
2470Sstevel@tonic-gate (void) memcpy(md5_opad, md5_ipad, hash_len);
2480Sstevel@tonic-gate } else {
2490Sstevel@tonic-gate (void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
2500Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
2510Sstevel@tonic-gate (void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
2520Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate md5_hmac_ctx_init(&ctx->hc_ctx_u.md5_ctx, md5_ipad, md5_opad);
2560Sstevel@tonic-gate break;
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate case CKM_SSL3_SHA1_MAC:
2600Sstevel@tonic-gate {
2610Sstevel@tonic-gate CK_BYTE sha1_ipad[SHA1_SSL_PAD_AND_KEY_SIZE];
2620Sstevel@tonic-gate CK_BYTE sha1_opad[SHA1_SSL_PAD_AND_KEY_SIZE];
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
2650Sstevel@tonic-gate return (CKR_KEY_SIZE_RANGE);
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate bzero(sha1_ipad, SHA1_SSL_PAD_AND_KEY_SIZE);
2690Sstevel@tonic-gate bzero(sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate /* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
2720Sstevel@tonic-gate (void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
2730Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
2740Sstevel@tonic-gate (void) memcpy(&sha1_ipad[OBJ_SEC(key)->sk_value_len],
2750Sstevel@tonic-gate sha1_ssl_ipad, SHA1_SSL_PAD_SIZE);
2760Sstevel@tonic-gate (void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
2770Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
2780Sstevel@tonic-gate (void) memcpy(&sha1_opad[OBJ_SEC(key)->sk_value_len],
2790Sstevel@tonic-gate sha1_ssl_opad, SHA1_SSL_PAD_SIZE);
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate SOFT_MAC_INIT_CTX(SHA1, &(ctx->hc_ctx_u.sha1_ctx),
2820Sstevel@tonic-gate sha1_ipad, sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate break;
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate case CKM_SHA_1_HMAC_GENERAL:
2870Sstevel@tonic-gate case CKM_SHA_1_HMAC:
2880Sstevel@tonic-gate {
2890Sstevel@tonic-gate uint32_t sha1_ipad[SHA1_HMAC_INTS_PER_BLOCK];
2900Sstevel@tonic-gate uint32_t sha1_opad[SHA1_HMAC_INTS_PER_BLOCK];
2910Sstevel@tonic-gate CK_MECHANISM digest_mech;
2920Sstevel@tonic-gate CK_ULONG hash_len = SHA1_HASH_SIZE;
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
2950Sstevel@tonic-gate bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
2980Sstevel@tonic-gate /*
2990Sstevel@tonic-gate * Hash the key when it is longer than 64 bytes.
3000Sstevel@tonic-gate */
3010Sstevel@tonic-gate digest_mech.mechanism = CKM_SHA_1;
3020Sstevel@tonic-gate digest_mech.pParameter = NULL_PTR;
3030Sstevel@tonic-gate digest_mech.ulParameterLen = 0;
3040Sstevel@tonic-gate rv = soft_digest_init_internal(session_p, &digest_mech);
3050Sstevel@tonic-gate if (rv != CKR_OK)
3060Sstevel@tonic-gate return (rv);
3070Sstevel@tonic-gate rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
3080Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha1_ipad,
3090Sstevel@tonic-gate &hash_len);
3100Sstevel@tonic-gate session_p->digest.flags = 0;
3110Sstevel@tonic-gate if (rv != CKR_OK)
3120Sstevel@tonic-gate return (rv);
3130Sstevel@tonic-gate (void) memcpy(sha1_opad, sha1_ipad, hash_len);
3140Sstevel@tonic-gate } else {
3150Sstevel@tonic-gate (void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
3160Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
3170Sstevel@tonic-gate (void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
3180Sstevel@tonic-gate OBJ_SEC(key)->sk_value_len);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate
3210Sstevel@tonic-gate sha1_hmac_ctx_init(&ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
3220Sstevel@tonic-gate sha1_opad);
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate break;
3250Sstevel@tonic-gate }
326676Sizick case CKM_SHA256_HMAC:
327676Sizick case CKM_SHA256_HMAC_GENERAL:
328676Sizick {
329676Sizick uint64_t sha_ipad[SHA256_HMAC_INTS_PER_BLOCK];
330676Sizick uint64_t sha_opad[SHA256_HMAC_INTS_PER_BLOCK];
331676Sizick CK_MECHANISM digest_mech;
332676Sizick CK_ULONG hash_len = SHA256_DIGEST_LENGTH;
333676Sizick
334676Sizick bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
335676Sizick bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
336676Sizick
337676Sizick if (OBJ_SEC(key)->sk_value_len > SHA256_HMAC_BLOCK_SIZE) {
338676Sizick /*
339676Sizick * Hash the key when it is longer than 64 bytes.
340676Sizick */
341676Sizick digest_mech.mechanism = CKM_SHA256;
342676Sizick digest_mech.pParameter = NULL_PTR;
343676Sizick digest_mech.ulParameterLen = 0;
344676Sizick rv = soft_digest_init_internal(session_p, &digest_mech);
345676Sizick if (rv != CKR_OK)
346676Sizick return (rv);
347676Sizick rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
348676Sizick OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
349676Sizick &hash_len);
350676Sizick session_p->digest.flags = 0;
351676Sizick if (rv != CKR_OK)
352676Sizick return (rv);
353676Sizick (void) memcpy(sha_opad, sha_ipad, hash_len);
354676Sizick } else {
355676Sizick (void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
356676Sizick OBJ_SEC(key)->sk_value_len);
357676Sizick (void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
358676Sizick OBJ_SEC(key)->sk_value_len);
359676Sizick }
360676Sizick
361676Sizick sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
362676Sizick sha_ipad, sha_opad, SHA256_HMAC_INTS_PER_BLOCK,
363676Sizick SHA256_HMAC_BLOCK_SIZE);
364676Sizick
365676Sizick break;
366676Sizick }
367676Sizick case CKM_SHA384_HMAC:
368676Sizick case CKM_SHA384_HMAC_GENERAL:
369676Sizick {
370676Sizick uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
371676Sizick uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
372676Sizick CK_MECHANISM digest_mech;
373676Sizick CK_ULONG hash_len = SHA384_DIGEST_LENGTH;
374676Sizick
375676Sizick bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
376676Sizick bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
377676Sizick
378676Sizick if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
379676Sizick /*
380676Sizick * Hash the key when it is longer than 64 bytes.
381676Sizick */
382676Sizick digest_mech.mechanism = CKM_SHA384;
383676Sizick digest_mech.pParameter = NULL_PTR;
384676Sizick digest_mech.ulParameterLen = 0;
385676Sizick rv = soft_digest_init_internal(session_p, &digest_mech);
386676Sizick if (rv != CKR_OK)
387676Sizick return (rv);
388676Sizick rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
389676Sizick OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
390676Sizick &hash_len);
391676Sizick session_p->digest.flags = 0;
392676Sizick if (rv != CKR_OK)
393676Sizick return (rv);
394676Sizick (void) memcpy(sha_opad, sha_ipad, hash_len);
395676Sizick } else {
396676Sizick (void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
397676Sizick OBJ_SEC(key)->sk_value_len);
398676Sizick (void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
399676Sizick OBJ_SEC(key)->sk_value_len);
400676Sizick }
401676Sizick
402676Sizick sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
403676Sizick sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
404676Sizick SHA512_HMAC_BLOCK_SIZE);
405676Sizick
406676Sizick break;
407676Sizick }
408676Sizick case CKM_SHA512_HMAC:
409676Sizick case CKM_SHA512_HMAC_GENERAL:
410676Sizick {
411676Sizick uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
412676Sizick uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
413676Sizick CK_MECHANISM digest_mech;
414676Sizick CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
415676Sizick
416676Sizick bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
417676Sizick bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
418676Sizick
419676Sizick if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
420676Sizick /*
421676Sizick * Hash the key when it is longer than 64 bytes.
422676Sizick */
423676Sizick digest_mech.mechanism = CKM_SHA512;
424676Sizick digest_mech.pParameter = NULL_PTR;
425676Sizick digest_mech.ulParameterLen = 0;
426676Sizick rv = soft_digest_init_internal(session_p, &digest_mech);
427676Sizick if (rv != CKR_OK)
428676Sizick return (rv);
429676Sizick rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
430676Sizick OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
431676Sizick &hash_len);
432676Sizick session_p->digest.flags = 0;
433676Sizick if (rv != CKR_OK)
434676Sizick return (rv);
435676Sizick (void) memcpy(sha_opad, sha_ipad, hash_len);
436676Sizick } else {
437676Sizick (void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
438676Sizick OBJ_SEC(key)->sk_value_len);
439676Sizick (void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
440676Sizick OBJ_SEC(key)->sk_value_len);
441676Sizick }
442676Sizick
443676Sizick sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
444676Sizick sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
445676Sizick SHA512_HMAC_BLOCK_SIZE);
446676Sizick
447676Sizick break;
448676Sizick }
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate return (rv);
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate
4530Sstevel@tonic-gate
4540Sstevel@tonic-gate /*
4550Sstevel@tonic-gate * Called by soft_sign(), soft_sign_final(), soft_verify() or
4560Sstevel@tonic-gate * soft_verify_final().
4570Sstevel@tonic-gate */
4580Sstevel@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)4590Sstevel@tonic-gate soft_hmac_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
4600Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen,
4610Sstevel@tonic-gate boolean_t sign_op)
4620Sstevel@tonic-gate {
4630Sstevel@tonic-gate
4640Sstevel@tonic-gate soft_hmac_ctx_t *hmac_ctx;
4650Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism;
4660Sstevel@tonic-gate #ifdef __sparcv9
4670Sstevel@tonic-gate /* LINTED */
4680Sstevel@tonic-gate uint_t datalen = (uint_t)ulDataLen;
4690Sstevel@tonic-gate #else /* __sparcv9 */
4700Sstevel@tonic-gate uint_t datalen = ulDataLen;
4710Sstevel@tonic-gate #endif /* __sparcv9 */
4720Sstevel@tonic-gate
4730Sstevel@tonic-gate if (sign_op) {
4740Sstevel@tonic-gate hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
4750Sstevel@tonic-gate mechanism = session_p->sign.mech.mechanism;
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate /*
4780Sstevel@tonic-gate * If application asks for the length of the output buffer
4790Sstevel@tonic-gate * to hold the signature?
4800Sstevel@tonic-gate */
4810Sstevel@tonic-gate if (pSigned == NULL) {
4820Sstevel@tonic-gate *pulSignedLen = hmac_ctx->hmac_len;
4830Sstevel@tonic-gate return (CKR_OK);
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate
4860Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
4870Sstevel@tonic-gate if (*pulSignedLen < hmac_ctx->hmac_len) {
4880Sstevel@tonic-gate *pulSignedLen = hmac_ctx->hmac_len;
4890Sstevel@tonic-gate return (CKR_BUFFER_TOO_SMALL);
4900Sstevel@tonic-gate }
4910Sstevel@tonic-gate } else {
4920Sstevel@tonic-gate hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
4930Sstevel@tonic-gate mechanism = session_p->verify.mech.mechanism;
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate switch (mechanism) {
4970Sstevel@tonic-gate
4980Sstevel@tonic-gate case CKM_SSL3_MD5_MAC:
4990Sstevel@tonic-gate case CKM_MD5_HMAC_GENERAL:
5000Sstevel@tonic-gate case CKM_MD5_HMAC:
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate if (pData != NULL) {
5030Sstevel@tonic-gate /* Called by soft_sign() or soft_verify(). */
5040Sstevel@tonic-gate SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx),
5050Sstevel@tonic-gate pData, datalen);
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate SOFT_MAC_FINAL(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pSigned);
5080Sstevel@tonic-gate break;
5090Sstevel@tonic-gate
5100Sstevel@tonic-gate case CKM_SSL3_SHA1_MAC:
5110Sstevel@tonic-gate case CKM_SHA_1_HMAC_GENERAL:
5120Sstevel@tonic-gate case CKM_SHA_1_HMAC:
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate if (pData != NULL) {
5150Sstevel@tonic-gate /* Called by soft_sign() or soft_verify(). */
5160Sstevel@tonic-gate SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx),
5170Sstevel@tonic-gate pData, datalen);
5180Sstevel@tonic-gate }
5190Sstevel@tonic-gate SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pSigned);
520676Sizick break;
521676Sizick
522676Sizick case CKM_SHA256_HMAC_GENERAL:
523676Sizick case CKM_SHA256_HMAC:
524676Sizick if (pData != NULL)
525676Sizick /* Called by soft_sign() or soft_verify(). */
526676Sizick SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
527676Sizick pData, datalen);
528676Sizick
529676Sizick SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
530676Sizick pSigned);
531676Sizick break;
532676Sizick
533676Sizick case CKM_SHA384_HMAC_GENERAL:
534676Sizick case CKM_SHA384_HMAC:
535676Sizick if (pData != NULL)
536676Sizick /* Called by soft_sign() or soft_verify(). */
537676Sizick SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
538676Sizick pData, datalen);
5390Sstevel@tonic-gate
540676Sizick SOFT_MAC_FINAL_2(SHA384, &(hmac_ctx->hc_ctx_u.sha2_ctx),
541676Sizick pSigned);
542676Sizick hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
5430Sstevel@tonic-gate break;
544676Sizick
545676Sizick case CKM_SHA512_HMAC_GENERAL:
546676Sizick case CKM_SHA512_HMAC:
547676Sizick
548676Sizick if (pData != NULL)
549676Sizick /* Called by soft_sign() or soft_verify(). */
550676Sizick SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
551676Sizick pData, datalen);
552676Sizick
553676Sizick SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
554676Sizick pSigned);
555676Sizick };
556676Sizick
557676Sizick *pulSignedLen = hmac_ctx->hmac_len;
558676Sizick
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate clean_exit:
5610Sstevel@tonic-gate
5620Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate if (sign_op) {
5650Sstevel@tonic-gate bzero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
5660Sstevel@tonic-gate free(session_p->sign.context);
5670Sstevel@tonic-gate session_p->sign.context = NULL;
5680Sstevel@tonic-gate } else {
5690Sstevel@tonic-gate bzero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
5700Sstevel@tonic-gate free(session_p->verify.context);
5710Sstevel@tonic-gate session_p->verify.context = NULL;
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate return (CKR_OK);
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate
5800Sstevel@tonic-gate /*
5810Sstevel@tonic-gate * Called by soft_sign_update() or soft_verify_update().
5820Sstevel@tonic-gate */
5830Sstevel@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)5840Sstevel@tonic-gate soft_hmac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
5850Sstevel@tonic-gate CK_ULONG ulPartLen, boolean_t sign_op)
5860Sstevel@tonic-gate {
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate soft_hmac_ctx_t *hmac_ctx;
5890Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism;
5900Sstevel@tonic-gate #ifdef __sparcv9
5910Sstevel@tonic-gate /* LINTED */
5920Sstevel@tonic-gate uint_t partlen = (uint_t)ulPartLen;
5930Sstevel@tonic-gate #else /* __sparcv9 */
5940Sstevel@tonic-gate uint_t partlen = ulPartLen;
5950Sstevel@tonic-gate #endif /* __sparcv9 */
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate if (sign_op) {
5980Sstevel@tonic-gate hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
5990Sstevel@tonic-gate mechanism = session_p->sign.mech.mechanism;
6000Sstevel@tonic-gate } else {
6010Sstevel@tonic-gate hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
6020Sstevel@tonic-gate mechanism = session_p->verify.mech.mechanism;
6030Sstevel@tonic-gate }
6040Sstevel@tonic-gate
6050Sstevel@tonic-gate switch (mechanism) {
6060Sstevel@tonic-gate
6070Sstevel@tonic-gate case CKM_SSL3_MD5_MAC:
6080Sstevel@tonic-gate case CKM_MD5_HMAC_GENERAL:
6090Sstevel@tonic-gate case CKM_MD5_HMAC:
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pPart,
6120Sstevel@tonic-gate partlen);
6130Sstevel@tonic-gate break;
6140Sstevel@tonic-gate
6150Sstevel@tonic-gate case CKM_SSL3_SHA1_MAC:
6160Sstevel@tonic-gate case CKM_SHA_1_HMAC_GENERAL:
6170Sstevel@tonic-gate case CKM_SHA_1_HMAC:
6180Sstevel@tonic-gate
6190Sstevel@tonic-gate SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pPart,
6200Sstevel@tonic-gate partlen);
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate break;
623676Sizick
624676Sizick case CKM_SHA256_HMAC_GENERAL:
625676Sizick case CKM_SHA256_HMAC:
626676Sizick case CKM_SHA384_HMAC_GENERAL:
627676Sizick case CKM_SHA384_HMAC:
628676Sizick case CKM_SHA512_HMAC_GENERAL:
629676Sizick case CKM_SHA512_HMAC:
630676Sizick
631676Sizick SOFT_MAC_UPDATE(SHA2, &(hmac_ctx->hc_ctx_u.sha2_ctx), pPart,
632676Sizick partlen);
633676Sizick break;
634676Sizick
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate return (CKR_OK);
6370Sstevel@tonic-gate }
6380Sstevel@tonic-gate
6390Sstevel@tonic-gate /*
6400Sstevel@tonic-gate * The following 2 functions expect the MAC key to be alreay copied in
6410Sstevel@tonic-gate * the ipad and opad
6420Sstevel@tonic-gate */
6430Sstevel@tonic-gate void
md5_hmac_ctx_init(md5_hc_ctx_t * md5_hmac_ctx,uint32_t * ipad,uint32_t * opad)6440Sstevel@tonic-gate md5_hmac_ctx_init(md5_hc_ctx_t *md5_hmac_ctx, uint32_t *ipad, uint32_t *opad)
6450Sstevel@tonic-gate {
6460Sstevel@tonic-gate int i;
6470Sstevel@tonic-gate /* XOR key with ipad (0x36) and opad (0x5c) */
6480Sstevel@tonic-gate for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
6490Sstevel@tonic-gate ipad[i] ^= 0x36363636;
6500Sstevel@tonic-gate opad[i] ^= 0x5c5c5c5c;
6510Sstevel@tonic-gate }
6520Sstevel@tonic-gate SOFT_MAC_INIT_CTX(MD5, md5_hmac_ctx, ipad, opad, MD5_HMAC_BLOCK_SIZE);
6530Sstevel@tonic-gate }
6540Sstevel@tonic-gate
6550Sstevel@tonic-gate void
sha1_hmac_ctx_init(sha1_hc_ctx_t * sha1_hmac_ctx,uint32_t * ipad,uint32_t * opad)6560Sstevel@tonic-gate sha1_hmac_ctx_init(sha1_hc_ctx_t *sha1_hmac_ctx, uint32_t *ipad, uint32_t *opad)
6570Sstevel@tonic-gate {
6580Sstevel@tonic-gate int i;
6590Sstevel@tonic-gate /* XOR key with ipad (0x36) and opad (0x5c) */
6600Sstevel@tonic-gate for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
6610Sstevel@tonic-gate ipad[i] ^= 0x36363636;
6620Sstevel@tonic-gate opad[i] ^= 0x5c5c5c5c;
6630Sstevel@tonic-gate }
6640Sstevel@tonic-gate SOFT_MAC_INIT_CTX(SHA1, sha1_hmac_ctx, (const uchar_t *)ipad,
6650Sstevel@tonic-gate (const uchar_t *)opad, SHA1_HMAC_BLOCK_SIZE);
6660Sstevel@tonic-gate }
667676Sizick
668676Sizick
669676Sizick 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)670676Sizick sha2_hmac_ctx_init(uint_t mech, sha2_hc_ctx_t *ctx, uint64_t *ipad,
671676Sizick uint64_t *opad, uint_t blocks_per_int64, uint_t block_size)
672676Sizick {
673676Sizick int i;
674676Sizick
675676Sizick /* XOR key with ipad (0x36) and opad (0x5c) */
676676Sizick for (i = 0; i < blocks_per_int64; i ++) {
677*872Sizick ipad[i] ^= 0x3636363636363636ULL;
678*872Sizick opad[i] ^= 0x5c5c5c5c5c5c5c5cULL;
679676Sizick }
680676Sizick
681676Sizick /* perform SHA2 on ipad */
682676Sizick SHA2Init(mech, &ctx->hc_icontext);
683676Sizick SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
684676Sizick
685676Sizick /* perform SHA2 on opad */
686676Sizick SHA2Init(mech, &ctx->hc_ocontext);
687676Sizick SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
688676Sizick
689676Sizick }
690