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  * Copyright (c) 2018, Joyent, Inc.
  26  */
  27 
  28 #include <pthread.h>
  29 #include <sys/md5.h>
  30 #include <sys/sha1.h>
  31 #include <sys/sha2.h>
  32 #include <stdlib.h>
  33 #include <string.h>
  34 #include <strings.h>
  35 #include <sys/types.h>
  36 #include <security/cryptoki.h>
  37 #include "softObject.h"
  38 #include "softOps.h"
  39 #include "softSession.h"
  40 #include "softMAC.h"
  41 
  42 /*
  43  * IPAD = 0x36 repeated 48 times for ssl md5, repeated 40 times for ssl sha1
  44  * OPAD = 0x5C repeated 48 times for SSL md5, repeated 40 times for ssl sha1
  45  */
  46 const uint32_t md5_ssl_ipad[] = {
  47         0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
  48         0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
  49         0x36363636, 0x36363636};
  50 const uint32_t sha1_ssl_ipad[] = {
  51         0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636,
  52         0x36363636, 0x36363636, 0x36363636, 0x36363636, 0x36363636};
  53 const uint32_t md5_ssl_opad[] = {
  54         0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
  55         0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
  56         0x5c5c5c5c, 0x5c5c5c5c};
  57 const uint32_t sha1_ssl_opad[] = {
  58         0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c,
  59         0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c};
  60 
  61 /*
  62  * Allocate and initialize a HMAC context, and save the context pointer in
  63  * the session struct. For General-length HMAC, checks the length in the
  64  * parameter to see if it is in the right range.
  65  */
  66 CK_RV
  67 soft_hmac_sign_verify_init_common(soft_session_t *session_p,
  68     CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op)
  69 {
  70 
  71         soft_hmac_ctx_t *hmac_ctx;
  72         CK_RV rv = CKR_OK;
  73 
  74         if ((key_p->class != CKO_SECRET_KEY) ||
  75             (key_p->key_type != CKK_GENERIC_SECRET)) {
  76                 return (CKR_KEY_TYPE_INCONSISTENT);
  77         }
  78 
  79         hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
  80 
  81         if (hmac_ctx == NULL) {
  82                 return (CKR_HOST_MEMORY);
  83         }
  84 
  85         switch (pMechanism->mechanism) {
  86         case CKM_MD5_HMAC:
  87                 hmac_ctx->hmac_len = MD5_HASH_SIZE;
  88                 break;
  89 
  90         case CKM_SHA_1_HMAC:
  91                 hmac_ctx->hmac_len = SHA1_HASH_SIZE;
  92                 break;
  93 
  94         case CKM_SHA256_HMAC:
  95                 hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
  96                 break;
  97 
  98         case CKM_SHA384_HMAC:
  99                 hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
 100                 break;
 101 
 102         case CKM_SHA512_HMAC:
 103                 hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
 104                 break;
 105 
 106         case CKM_MD5_HMAC_GENERAL:
 107         case CKM_SSL3_MD5_MAC:
 108                 if ((pMechanism->ulParameterLen !=
 109                     sizeof (CK_MAC_GENERAL_PARAMS)) &&
 110                     (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
 111                         MD5_HASH_SIZE)) {
 112                                 free(hmac_ctx);
 113                                 return (CKR_MECHANISM_PARAM_INVALID);
 114                         }
 115                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 116                     pMechanism->pParameter);
 117                 break;
 118 
 119         case CKM_SSL3_SHA1_MAC:
 120         case CKM_SHA_1_HMAC_GENERAL:
 121                 if ((pMechanism->ulParameterLen !=
 122                     sizeof (CK_MAC_GENERAL_PARAMS)) &&
 123                     (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
 124                         SHA1_HASH_SIZE)) {
 125                         free(hmac_ctx);
 126                         return (CKR_MECHANISM_PARAM_INVALID);
 127                 }
 128                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 129                     pMechanism->pParameter);
 130                 break;
 131 
 132         case CKM_SHA256_HMAC_GENERAL:
 133                 if ((pMechanism->ulParameterLen !=
 134                     sizeof (CK_MAC_GENERAL_PARAMS)) &&
 135                     (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
 136                         SHA256_DIGEST_LENGTH)) {
 137                         free(hmac_ctx);
 138                         return (CKR_MECHANISM_PARAM_INVALID);
 139                 }
 140                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 141                     pMechanism->pParameter);
 142                 break;
 143 
 144         case CKM_SHA384_HMAC_GENERAL:
 145         case CKM_SHA512_HMAC_GENERAL:
 146                 if ((pMechanism->ulParameterLen !=
 147                     sizeof (CK_MAC_GENERAL_PARAMS)) &&
 148                     (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
 149                         SHA512_DIGEST_LENGTH)) {
 150                         free(hmac_ctx);
 151                         return (CKR_MECHANISM_PARAM_INVALID);
 152                 }
 153 
 154                 hmac_ctx->hmac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 155                     pMechanism->pParameter);
 156                 break;
 157 
 158         }
 159 
 160 
 161         /* Initialize a MAC context. */
 162         rv = mac_init_ctx(session_p, key_p, hmac_ctx, pMechanism->mechanism);
 163         if (rv != CKR_OK)
 164                 return (rv);
 165 
 166         (void) pthread_mutex_lock(&session_p->session_mutex);
 167 
 168         if (sign_op) {
 169                 session_p->sign.mech.mechanism = pMechanism->mechanism;
 170                 session_p->sign.context = hmac_ctx;
 171         } else {
 172                 session_p->verify.mech.mechanism = pMechanism->mechanism;
 173                 session_p->verify.context = hmac_ctx;
 174         }
 175 
 176         (void) pthread_mutex_unlock(&session_p->session_mutex);
 177 
 178         return (CKR_OK);
 179 }
 180 
 181 
 182 /*
 183  * Initialize a HMAC context.
 184  */
 185 CK_RV
 186 mac_init_ctx(soft_session_t *session_p, soft_object_t *key,
 187     soft_hmac_ctx_t *ctx, CK_MECHANISM_TYPE mech)
 188 {
 189         CK_RV rv = CKR_OK;
 190 
 191         switch (mech) {
 192         case CKM_SSL3_MD5_MAC:
 193         {
 194                 CK_BYTE md5_ipad[MD5_SSL_PAD_AND_KEY_SIZE];
 195                 CK_BYTE md5_opad[MD5_SSL_PAD_AND_KEY_SIZE];
 196 
 197                 if (OBJ_SEC(key)->sk_value_len > MD5_SSL_PAD_AND_KEY_SIZE) {
 198                         return (CKR_KEY_SIZE_RANGE);
 199                 }
 200 
 201                 bzero(md5_ipad, MD5_SSL_PAD_AND_KEY_SIZE);
 202                 bzero(md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
 203 
 204                 /* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
 205                 (void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
 206                     OBJ_SEC(key)->sk_value_len);
 207                 (void) memcpy(&md5_ipad[OBJ_SEC(key)->sk_value_len],
 208                     md5_ssl_ipad, MD5_SSL_PAD_SIZE);
 209                 (void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
 210                     OBJ_SEC(key)->sk_value_len);
 211                 (void) memcpy(&md5_opad[OBJ_SEC(key)->sk_value_len],
 212                     md5_ssl_opad, MD5_SSL_PAD_SIZE);
 213 
 214                 SOFT_MAC_INIT_CTX(MD5, &(ctx->hc_ctx_u.md5_ctx),
 215                     md5_ipad, md5_opad, MD5_SSL_PAD_AND_KEY_SIZE);
 216 
 217                 break;
 218         }
 219         case CKM_MD5_HMAC_GENERAL:
 220         case CKM_MD5_HMAC:
 221         {
 222                 uint32_t md5_ipad[MD5_HMAC_INTS_PER_BLOCK];
 223                 uint32_t md5_opad[MD5_HMAC_INTS_PER_BLOCK];
 224                 CK_MECHANISM digest_mech;
 225                 CK_ULONG hash_len = MD5_HASH_SIZE;
 226 
 227                 bzero(md5_ipad, MD5_HMAC_BLOCK_SIZE);
 228                 bzero(md5_opad, MD5_HMAC_BLOCK_SIZE);
 229 
 230                 if (OBJ_SEC(key)->sk_value_len > MD5_HMAC_BLOCK_SIZE) {
 231                         /*
 232                          * Hash the key when it is longer than 64 bytes.
 233                          */
 234                         digest_mech.mechanism = CKM_MD5;
 235                         digest_mech.pParameter = NULL_PTR;
 236                         digest_mech.ulParameterLen = 0;
 237                         rv = soft_digest_init_internal(session_p, &digest_mech);
 238                         if (rv != CKR_OK)
 239                                 return (rv);
 240                         rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
 241                             OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)md5_ipad,
 242                             &hash_len);
 243                         session_p->digest.flags = 0;
 244                         if (rv != CKR_OK)
 245                                 return (rv);
 246                         (void) memcpy(md5_opad, md5_ipad, hash_len);
 247                 } else {
 248                         (void) memcpy(md5_ipad, OBJ_SEC(key)->sk_value,
 249                             OBJ_SEC(key)->sk_value_len);
 250                         (void) memcpy(md5_opad, OBJ_SEC(key)->sk_value,
 251                             OBJ_SEC(key)->sk_value_len);
 252                 }
 253 
 254                 md5_hmac_ctx_init(&ctx->hc_ctx_u.md5_ctx, md5_ipad, md5_opad);
 255                 break;
 256         }
 257 
 258         case CKM_SSL3_SHA1_MAC:
 259         {
 260                 CK_BYTE sha1_ipad[SHA1_SSL_PAD_AND_KEY_SIZE];
 261                 CK_BYTE sha1_opad[SHA1_SSL_PAD_AND_KEY_SIZE];
 262 
 263                 if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
 264                         return (CKR_KEY_SIZE_RANGE);
 265                 }
 266 
 267                 bzero(sha1_ipad, SHA1_SSL_PAD_AND_KEY_SIZE);
 268                 bzero(sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
 269 
 270                 /* SSL MAC is HASH(key + opad + HASH(key + ipad + data)) */
 271                 (void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
 272                     OBJ_SEC(key)->sk_value_len);
 273                 (void) memcpy(&sha1_ipad[OBJ_SEC(key)->sk_value_len],
 274                     sha1_ssl_ipad, SHA1_SSL_PAD_SIZE);
 275                 (void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
 276                     OBJ_SEC(key)->sk_value_len);
 277                 (void) memcpy(&sha1_opad[OBJ_SEC(key)->sk_value_len],
 278                     sha1_ssl_opad, SHA1_SSL_PAD_SIZE);
 279 
 280                 SOFT_MAC_INIT_CTX(SHA1, &(ctx->hc_ctx_u.sha1_ctx),
 281                     sha1_ipad, sha1_opad, SHA1_SSL_PAD_AND_KEY_SIZE);
 282 
 283                 break;
 284         }
 285         case CKM_SHA_1_HMAC_GENERAL:
 286         case CKM_SHA_1_HMAC:
 287         {
 288                 uint32_t sha1_ipad[SHA1_HMAC_INTS_PER_BLOCK];
 289                 uint32_t sha1_opad[SHA1_HMAC_INTS_PER_BLOCK];
 290                 CK_MECHANISM digest_mech;
 291                 CK_ULONG hash_len = SHA1_HASH_SIZE;
 292 
 293                 bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
 294                 bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
 295 
 296                 if (OBJ_SEC(key)->sk_value_len > SHA1_HMAC_BLOCK_SIZE) {
 297                         /*
 298                          * Hash the key when it is longer than 64 bytes.
 299                          */
 300                         digest_mech.mechanism = CKM_SHA_1;
 301                         digest_mech.pParameter = NULL_PTR;
 302                         digest_mech.ulParameterLen = 0;
 303                         rv = soft_digest_init_internal(session_p, &digest_mech);
 304                         if (rv != CKR_OK)
 305                                 return (rv);
 306                         rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
 307                             OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha1_ipad,
 308                             &hash_len);
 309                         session_p->digest.flags = 0;
 310                         if (rv != CKR_OK)
 311                                 return (rv);
 312                         (void) memcpy(sha1_opad, sha1_ipad, hash_len);
 313                 } else {
 314                         (void) memcpy(sha1_ipad, OBJ_SEC(key)->sk_value,
 315                             OBJ_SEC(key)->sk_value_len);
 316                         (void) memcpy(sha1_opad, OBJ_SEC(key)->sk_value,
 317                             OBJ_SEC(key)->sk_value_len);
 318                 }
 319 
 320                 sha1_hmac_ctx_init(&ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
 321                     sha1_opad);
 322 
 323                 break;
 324         }
 325         case CKM_SHA256_HMAC:
 326         case CKM_SHA256_HMAC_GENERAL:
 327         {
 328                 uint64_t sha_ipad[SHA256_HMAC_INTS_PER_BLOCK];
 329                 uint64_t sha_opad[SHA256_HMAC_INTS_PER_BLOCK];
 330                 CK_MECHANISM digest_mech;
 331                 CK_ULONG hash_len = SHA256_DIGEST_LENGTH;
 332 
 333                 bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
 334                 bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
 335 
 336                 if (OBJ_SEC(key)->sk_value_len > SHA256_HMAC_BLOCK_SIZE) {
 337                         /*
 338                          * Hash the key when it is longer than 64 bytes.
 339                          */
 340                         digest_mech.mechanism = CKM_SHA256;
 341                         digest_mech.pParameter = NULL_PTR;
 342                         digest_mech.ulParameterLen = 0;
 343                         rv = soft_digest_init_internal(session_p, &digest_mech);
 344                         if (rv != CKR_OK)
 345                                 return (rv);
 346                         rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
 347                             OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
 348                             &hash_len);
 349                         session_p->digest.flags = 0;
 350                         if (rv != CKR_OK)
 351                                 return (rv);
 352                         (void) memcpy(sha_opad, sha_ipad, hash_len);
 353                 } else {
 354                         (void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
 355                             OBJ_SEC(key)->sk_value_len);
 356                         (void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
 357                             OBJ_SEC(key)->sk_value_len);
 358                 }
 359 
 360                 sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
 361                     sha_ipad, sha_opad, SHA256_HMAC_INTS_PER_BLOCK,
 362                     SHA256_HMAC_BLOCK_SIZE);
 363 
 364                 break;
 365         }
 366         case CKM_SHA384_HMAC:
 367         case CKM_SHA384_HMAC_GENERAL:
 368         {
 369                 uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
 370                 uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
 371                 CK_MECHANISM digest_mech;
 372                 CK_ULONG hash_len = SHA384_DIGEST_LENGTH;
 373 
 374                 bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
 375                 bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
 376 
 377                 if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
 378                         /*
 379                          * Hash the key when it is longer than 64 bytes.
 380                          */
 381                         digest_mech.mechanism = CKM_SHA384;
 382                         digest_mech.pParameter = NULL_PTR;
 383                         digest_mech.ulParameterLen = 0;
 384                         rv = soft_digest_init_internal(session_p, &digest_mech);
 385                         if (rv != CKR_OK)
 386                                 return (rv);
 387                         rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
 388                             OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
 389                             &hash_len);
 390                         session_p->digest.flags = 0;
 391                         if (rv != CKR_OK)
 392                                 return (rv);
 393                         (void) memcpy(sha_opad, sha_ipad, hash_len);
 394                 } else {
 395                         (void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
 396                             OBJ_SEC(key)->sk_value_len);
 397                         (void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
 398                             OBJ_SEC(key)->sk_value_len);
 399                 }
 400 
 401                 sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
 402                     sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
 403                     SHA512_HMAC_BLOCK_SIZE);
 404 
 405                 break;
 406         }
 407         case CKM_SHA512_HMAC:
 408         case CKM_SHA512_HMAC_GENERAL:
 409         {
 410                 uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
 411                 uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
 412                 CK_MECHANISM digest_mech;
 413                 CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
 414 
 415                 bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
 416                 bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
 417 
 418                 if (OBJ_SEC(key)->sk_value_len > SHA512_HMAC_BLOCK_SIZE) {
 419                         /*
 420                          * Hash the key when it is longer than 64 bytes.
 421                          */
 422                         digest_mech.mechanism = CKM_SHA512;
 423                         digest_mech.pParameter = NULL_PTR;
 424                         digest_mech.ulParameterLen = 0;
 425                         rv = soft_digest_init_internal(session_p, &digest_mech);
 426                         if (rv != CKR_OK)
 427                                 return (rv);
 428                         rv = soft_digest(session_p, OBJ_SEC(key)->sk_value,
 429                             OBJ_SEC(key)->sk_value_len, (CK_BYTE_PTR)sha_ipad,
 430                             &hash_len);
 431                         session_p->digest.flags = 0;
 432                         if (rv != CKR_OK)
 433                                 return (rv);
 434                         (void) memcpy(sha_opad, sha_ipad, hash_len);
 435                 } else {
 436                         (void) memcpy(sha_ipad, OBJ_SEC(key)->sk_value,
 437                             OBJ_SEC(key)->sk_value_len);
 438                         (void) memcpy(sha_opad, OBJ_SEC(key)->sk_value,
 439                             OBJ_SEC(key)->sk_value_len);
 440                 }
 441 
 442                 sha2_hmac_ctx_init(CKM_TO_SHA2(mech), &ctx->hc_ctx_u.sha2_ctx,
 443                     sha_ipad, sha_opad, SHA512_HMAC_INTS_PER_BLOCK,
 444                     SHA512_HMAC_BLOCK_SIZE);
 445 
 446                 break;
 447         }
 448         }
 449         return (rv);
 450 }
 451 
 452 
 453 /*
 454  * Called by soft_sign(), soft_sign_final(), soft_verify() or
 455  * soft_verify_final().
 456  */
 457 CK_RV
 458 soft_hmac_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
 459     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen,
 460     boolean_t sign_op)
 461 {
 462 
 463         soft_hmac_ctx_t *hmac_ctx;
 464         CK_MECHANISM_TYPE       mechanism;
 465 #ifdef  __sparcv9
 466         /* LINTED */
 467         uint_t datalen = (uint_t)ulDataLen;
 468 #else   /* __sparcv9 */
 469         uint_t datalen = ulDataLen;
 470 #endif  /* __sparcv9 */
 471 
 472         if (sign_op) {
 473                 hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
 474                 mechanism = session_p->sign.mech.mechanism;
 475 
 476                 /*
 477                  * If application asks for the length of the output buffer
 478                  * to hold the signature?
 479                  */
 480                 if (pSigned == NULL) {
 481                         *pulSignedLen = hmac_ctx->hmac_len;
 482                         return (CKR_OK);
 483                 }
 484 
 485                 /* Is the application-supplied buffer large enough? */
 486                 if (*pulSignedLen < hmac_ctx->hmac_len) {
 487                         *pulSignedLen = hmac_ctx->hmac_len;
 488                         return (CKR_BUFFER_TOO_SMALL);
 489                 }
 490         } else {
 491                 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
 492                 mechanism = session_p->verify.mech.mechanism;
 493         }
 494 
 495         switch (mechanism) {
 496 
 497         case CKM_SSL3_MD5_MAC:
 498         case CKM_MD5_HMAC_GENERAL:
 499         case CKM_MD5_HMAC:
 500 
 501                 if (pData != NULL) {
 502                         /* Called by soft_sign() or soft_verify(). */
 503                         SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx),
 504                             pData, datalen);
 505                 }
 506                 SOFT_MAC_FINAL(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pSigned);
 507                 break;
 508 
 509         case CKM_SSL3_SHA1_MAC:
 510         case CKM_SHA_1_HMAC_GENERAL:
 511         case CKM_SHA_1_HMAC:
 512 
 513                 if (pData != NULL) {
 514                         /* Called by soft_sign() or soft_verify(). */
 515                         SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx),
 516                             pData, datalen);
 517                 }
 518                 SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pSigned);
 519                 break;
 520 
 521         case CKM_SHA256_HMAC_GENERAL:
 522         case CKM_SHA256_HMAC:
 523                 if (pData != NULL)
 524                         /* Called by soft_sign() or soft_verify(). */
 525                         SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
 526                             pData, datalen);
 527 
 528                 SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
 529                     pSigned);
 530                 break;
 531 
 532         case CKM_SHA384_HMAC_GENERAL:
 533         case CKM_SHA384_HMAC:
 534                 if (pData != NULL)
 535                         /* Called by soft_sign() or soft_verify(). */
 536                         SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
 537                             pData, datalen);
 538 
 539                 SOFT_MAC_FINAL_2(SHA384, &(hmac_ctx->hc_ctx_u.sha2_ctx),
 540                     pSigned);
 541                 hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
 542                 break;
 543 
 544         case CKM_SHA512_HMAC_GENERAL:
 545         case CKM_SHA512_HMAC:
 546 
 547                 if (pData != NULL)
 548                         /* Called by soft_sign() or soft_verify(). */
 549                         SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
 550                             pData, datalen);
 551 
 552                 SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
 553                     pSigned);
 554         };
 555 
 556         *pulSignedLen = hmac_ctx->hmac_len;
 557 
 558 
 559 clean_exit:
 560 
 561         (void) pthread_mutex_lock(&session_p->session_mutex);
 562 
 563         if (sign_op) {
 564                 freezero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
 565                 session_p->sign.context = NULL;
 566         } else {
 567                 freezero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
 568                 session_p->verify.context = NULL;
 569         }
 570 
 571         (void) pthread_mutex_unlock(&session_p->session_mutex);
 572 
 573         return (CKR_OK);
 574 }
 575 
 576 
 577 /*
 578  * Called by soft_sign_update() or soft_verify_update().
 579  */
 580 CK_RV
 581 soft_hmac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
 582         CK_ULONG ulPartLen, boolean_t sign_op)
 583 {
 584 
 585         soft_hmac_ctx_t *hmac_ctx;
 586         CK_MECHANISM_TYPE       mechanism;
 587 #ifdef  __sparcv9
 588         /* LINTED */
 589         uint_t partlen = (uint_t)ulPartLen;
 590 #else   /* __sparcv9 */
 591         uint_t partlen = ulPartLen;
 592 #endif  /* __sparcv9 */
 593 
 594         if (sign_op) {
 595                 hmac_ctx = (soft_hmac_ctx_t *)session_p->sign.context;
 596                 mechanism = session_p->sign.mech.mechanism;
 597         } else {
 598                 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
 599                 mechanism = session_p->verify.mech.mechanism;
 600         }
 601 
 602         switch (mechanism) {
 603 
 604         case CKM_SSL3_MD5_MAC:
 605         case CKM_MD5_HMAC_GENERAL:
 606         case CKM_MD5_HMAC:
 607 
 608                 SOFT_MAC_UPDATE(MD5, &(hmac_ctx->hc_ctx_u.md5_ctx), pPart,
 609                     partlen);
 610                 break;
 611 
 612         case CKM_SSL3_SHA1_MAC:
 613         case CKM_SHA_1_HMAC_GENERAL:
 614         case CKM_SHA_1_HMAC:
 615 
 616                 SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), pPart,
 617                     partlen);
 618 
 619                 break;
 620 
 621         case CKM_SHA256_HMAC_GENERAL:
 622         case CKM_SHA256_HMAC:
 623         case CKM_SHA384_HMAC_GENERAL:
 624         case CKM_SHA384_HMAC:
 625         case CKM_SHA512_HMAC_GENERAL:
 626         case CKM_SHA512_HMAC:
 627 
 628                 SOFT_MAC_UPDATE(SHA2, &(hmac_ctx->hc_ctx_u.sha2_ctx), pPart,
 629                     partlen);
 630                 break;
 631 
 632         }
 633         return (CKR_OK);
 634 }
 635 
 636 /*
 637  * The following 2 functions expect the MAC key to be alreay copied in
 638  * the ipad and opad
 639  */
 640 void
 641 md5_hmac_ctx_init(md5_hc_ctx_t *md5_hmac_ctx, uint32_t *ipad, uint32_t *opad)
 642 {
 643         int i;
 644         /* XOR key with ipad (0x36) and opad (0x5c) */
 645         for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
 646                 ipad[i] ^= 0x36363636;
 647                 opad[i] ^= 0x5c5c5c5c;
 648         }
 649         SOFT_MAC_INIT_CTX(MD5, md5_hmac_ctx, ipad, opad, MD5_HMAC_BLOCK_SIZE);
 650 }
 651 
 652 void
 653 sha1_hmac_ctx_init(sha1_hc_ctx_t *sha1_hmac_ctx, uint32_t *ipad, uint32_t *opad)
 654 {
 655         int i;
 656         /* XOR key with ipad (0x36) and opad (0x5c) */
 657         for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
 658                 ipad[i] ^= 0x36363636;
 659                 opad[i] ^= 0x5c5c5c5c;
 660         }
 661         SOFT_MAC_INIT_CTX(SHA1, sha1_hmac_ctx, (const uchar_t *)ipad,
 662             (const uchar_t *)opad, SHA1_HMAC_BLOCK_SIZE);
 663 }
 664 
 665 
 666 void
 667 sha2_hmac_ctx_init(uint_t mech, sha2_hc_ctx_t *ctx, uint64_t *ipad,
 668     uint64_t *opad, uint_t blocks_per_int64, uint_t block_size)
 669 {
 670         int i;
 671 
 672         /* XOR key with ipad (0x36) and opad (0x5c) */
 673         for (i = 0; i < blocks_per_int64; i ++) {
 674                 ipad[i] ^= 0x3636363636363636ULL;
 675                 opad[i] ^= 0x5c5c5c5c5c5c5c5cULL;
 676         }
 677 
 678         /* perform SHA2 on ipad */
 679         SHA2Init(mech, &ctx->hc_icontext);
 680         SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
 681 
 682         /* perform SHA2 on opad */
 683         SHA2Init(mech, &ctx->hc_ocontext);
 684         SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
 685 
 686 }