1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  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"
  42 
  43 /*
  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
  46  */
  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};
  61 
  62 /*
  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.
  66  */
  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)
  70 {
  71 
  72         soft_hmac_ctx_t *hmac_ctx;
  73         CK_RV rv = CKR_OK;
  74 
  75         if ((key_p->class != CKO_SECRET_KEY) ||
  76             (key_p->key_type != CKK_GENERIC_SECRET)) {
  77                 return (CKR_KEY_TYPE_INCONSISTENT);
  78         }
  79 
  80         hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
  81 
  82         if (hmac_ctx == NULL) {
  83                 return (CKR_HOST_MEMORY);
  84         }
  85 
  86         switch (pMechanism->mechanism) {
  87         case CKM_MD5_HMAC:
  88                 hmac_ctx->hmac_len = MD5_HASH_SIZE;
  89                 break;
  90 
  91         case CKM_SHA_1_HMAC:
  92                 hmac_ctx->hmac_len = SHA1_HASH_SIZE;
  93                 break;
  94 
  95         case CKM_SHA256_HMAC:
  96                 hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
  97                 break;
  98 
  99         case CKM_SHA384_HMAC:
 100                 hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
 101                 break;
 102 
 103         case CKM_SHA512_HMAC:
 104                 hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
 105                 break;
 106 
 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);
 115                         }
 116                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 117                     pMechanism->pParameter);
 118                 break;
 119 
 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);
 128                 }
 129                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 130                     pMechanism->pParameter);
 131                 break;
 132 
 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);
 140                 }
 141                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 142                     pMechanism->pParameter);
 143                 break;
 144 
 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);
 153                 }
 154 
 155                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 156                     pMechanism->pParameter);
 157                 break;
 158 
 159         }
 160 
 161 
 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);
 166 
 167         (void) pthread_mutex_lock(&session_p->session_mutex);
 168 
 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;
 175         }
 176 
 177         (void) pthread_mutex_unlock(&session_p->session_mutex);
 178 
 179         return (CKR_OK);
 180 }
 181 
 182 
 183 /*
 184  * Initialize a HMAC context.
 185  */
 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)
 189 {
 190         CK_RV rv = CKR_OK;
 191 
 192         switch (mech) {
 193         case CKM_SSL3_MD5_MAC:
 194         {
 195                 CK_BYTE md5_ipad[MD5_SSL_PAD_AND_KEY_SIZE];
 196                 CK_BYTE md5_opad[MD5_SSL_PAD_AND_KEY_SIZE];
 197 
 198                 if (OBJ_SEC(key)->sk_value_len > MD5_SSL_PAD_AND_KEY_SIZE) {
 199                         return (CKR_KEY_SIZE_RANGE);
 200                 }
 201 
 202                 bzero(md5_ipad, MD5_SSL_PAD_AND_KEY_SIZE);
 203                 bzero(md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
 204 
 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);
 214 
 215                 SOFT_MAC_INIT_CTX(MD5, &(ctx->hc_ctx_u.md5_ctx),
 216                     md5_ipad, md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
 217 
 218                 break;
 219         }
 220         case CKM_MD5_HMAC_GENERAL:
 221         case CKM_MD5_HMAC:
 222         {
 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;
 227 
 228                 bzero(md5_ipad, MD5_HMAC_BLOCK_SIZE);
 229                 bzero(md5_opad, MD5_HMAC_BLOCK_SIZE);
 230 
 231                 if (OBJ_SEC(key)->sk_value_len > MD5_HMAC_BLOCK_SIZE) {
 232                         /*
 233                          * Hash the key when it is longer than 64 bytes.
 234                          */
 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);
 253                 }
 254 
 255                 md5_hmac_ctx_init(&ctx->hc_ctx_u.md5_ctx, md5_ipad, md5_opad);
 256                 break;
 257         }
 258 
 259         case CKM_SSL3_SHA1_MAC:
 260         {
 261                 CK_BYTE sha1_ipad[SHA1_SSL_PAD_AND_KEY_SIZE];
 262                 CK_BYTE sha1_opad[SHA1_SSL_PAD_AND_KEY_SIZE];
 263 
 264                 if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
 265                         return (CKR_KEY_SIZE_RANGE);
 266                 }
 267 
 268                 bzero(sha1_ipad, SHA1_SSL_PAD_AND_KEY_SIZE);
 269                 bzero(sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
 270 
 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);
 280 
 281                 SOFT_MAC_INIT_CTX(SHA1, &(ctx->hc_ctx_u.sha1_ctx),
 282                     sha1_ipad, sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
 283 
 284                 break;
 285         }
 286         case CKM_SHA_1_HMAC_GENERAL:
 287         case CKM_SHA_1_HMAC:
 288         {
 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;
 293 
 294                 bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
 295                 bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
 296 
 297                 if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
 298                         /*
 299                          * Hash the key when it is longer than 64 bytes.
 300                          */
 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);
 319                 }
 320 
 321                 sha1_hmac_ctx_init(&ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
 322                     sha1_opad);
 323 
 324                 break;
 325         }
 326         case CKM_SHA256_HMAC:
 327         case CKM_SHA256_HMAC_GENERAL:
 328         {
 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;
 333 
 334                 bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
 335                 bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
 336 
 337                 if (OBJ_SEC(key)->sk_value_len > SHA256_HMAC_BLOCK_SIZE) {
 338                         /*
 339                          * Hash the key when it is longer than 64 bytes.
 340                          */
 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);
 359                 }
 360 
 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);
 364 
 365                 break;
 366         }
 367         case CKM_SHA384_HMAC:
 368         case CKM_SHA384_HMAC_GENERAL:
 369         {
 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;
 374 
 375                 bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
 376                 bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
 377 
 378                 if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
 379                         /*
 380                          * Hash the key when it is longer than 64 bytes.
 381                          */
 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);
 400                 }
 401 
 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);
 405 
 406                 break;
 407         }
 408         case CKM_SHA512_HMAC:
 409         case CKM_SHA512_HMAC_GENERAL:
 410         {
 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;
 415 
 416                 bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
 417                 bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
 418 
 419                 if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
 420                         /*
 421                          * Hash the key when it is longer than 64 bytes.
 422                          */
 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);
 441                 }
 442 
 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);
 446 
 447                 break;
 448         }
 449         }
 450         return (rv);
 451 }
 452 
 453 
 454 /*
 455  * Called by soft_sign(), soft_sign_final(), soft_verify() or
 456  * soft_verify_final().
 457  */
 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)
 462 {
 463 
 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 */
 472 
 473         if (sign_op) {
 474                 hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
 475                 mechanism = session_p->sign.mech.mechanism;
 476 
 477                 /*
 478                  * If application asks for the length of the output buffer
 479                  * to hold the signature?
 480                  */
 481                 if (pSigned == NULL) {
 482                         *pulSignedLen = hmac_ctx->hmac_len;
 483                         return (CKR_OK);
 484                 }
 485 
 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);
 490                 }
 491         } else {
 492                 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
 493                 mechanism = session_p->verify.mech.mechanism;
 494         }
 495 
 496         switch (mechanism) {
 497 
 498         case CKM_SSL3_MD5_MAC:
 499         case CKM_MD5_HMAC_GENERAL:
 500         case CKM_MD5_HMAC:
 501 
 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);
 506                 }
 507                 SOFT_MAC_FINAL(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pSigned);
 508                 break;
 509 
 510         case CKM_SSL3_SHA1_MAC:
 511         case CKM_SHA_1_HMAC_GENERAL:
 512         case CKM_SHA_1_HMAC:
 513 
 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);
 518                 }
 519                 SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pSigned);
 520                 break;
 521 
 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);
 528 
 529                 SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
 530                     pSigned);
 531                 break;
 532 
 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);
 539 
 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;
 544 
 545         case CKM_SHA512_HMAC_GENERAL:
 546         case CKM_SHA512_HMAC:
 547 
 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);
 552 
 553                 SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
 554                     pSigned);
 555         };
 556 
 557         *pulSignedLen = hmac_ctx->hmac_len;
 558 
 559 
 560 clean_exit:
 561 
 562         (void) pthread_mutex_lock(&session_p->session_mutex);
 563 
 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;
 572         }
 573 
 574         (void) pthread_mutex_unlock(&session_p->session_mutex);
 575 
 576         return (CKR_OK);
 577 }
 578 
 579 
 580 /*
 581  * Called by soft_sign_update() or soft_verify_update().
 582  */
 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)
 586 {
 587 
 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 */
 596 
 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;
 603         }
 604 
 605         switch (mechanism) {
 606 
 607         case CKM_SSL3_MD5_MAC:
 608         case CKM_MD5_HMAC_GENERAL:
 609         case CKM_MD5_HMAC:
 610 
 611                 SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pPart,
 612                     partlen);
 613                 break;
 614 
 615         case CKM_SSL3_SHA1_MAC:
 616         case CKM_SHA_1_HMAC_GENERAL:
 617         case CKM_SHA_1_HMAC:
 618 
 619                 SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pPart,
 620                     partlen);
 621 
 622                 break;
 623 
 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:
 630 
 631                 SOFT_MAC_UPDATE(SHA2, &(hmac_ctx->hc_ctx_u.sha2_ctx), pPart,
 632                     partlen);
 633                 break;
 634 
 635         }
 636         return (CKR_OK);
 637 }
 638 
 639 /*
 640  * The following 2 functions expect the MAC key to be alreay copied in
 641  * the ipad and opad
 642  */
 643 void
 644 md5_hmac_ctx_init(md5_hc_ctx_t *md5_hmac_ctx, uint32_t *ipad, uint32_t *opad)
 645 {
 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;
 651         }
 652         SOFT_MAC_INIT_CTX(MD5, md5_hmac_ctx, ipad, opad, MD5_HMAC_BLOCK_SIZE);
 653 }
 654 
 655 void
 656 sha1_hmac_ctx_init(sha1_hc_ctx_t *sha1_hmac_ctx, uint32_t *ipad, uint32_t *opad)
 657 {
 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;
 663         }
 664         SOFT_MAC_INIT_CTX(SHA1, sha1_hmac_ctx, (const uchar_t *)ipad,
 665             (const uchar_t *)opad, SHA1_HMAC_BLOCK_SIZE);
 666 }
 667 
 668 
 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)
 672 {
 673         int i;
 674 
 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;
 679         }
 680 
 681         /* perform SHA2 on ipad */
 682         SHA2Init(mech, &ctx->hc_icontext);
 683         SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
 684 
 685         /* perform SHA2 on opad */
 686         SHA2Init(mech, &ctx->hc_ocontext);
 687         SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
 688 
 689 }