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 (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright (c) 2018, Joyent, Inc.
  25  */
  26 
  27 #include <pthread.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <strings.h>
  31 #include <sys/types.h>
  32 #include <security/cryptoki.h>
  33 #include <sys/crypto/common.h>
  34 #include <aes_impl.h>
  35 #include <blowfish_impl.h>
  36 #include <des_impl.h>
  37 #include <arcfour.h>
  38 #include <cryptoutil.h>
  39 #include "softGlobal.h"
  40 #include "softSession.h"
  41 #include "softObject.h"
  42 #include "softDSA.h"
  43 #include "softRSA.h"
  44 #include "softDH.h"
  45 #include "softEC.h"
  46 #include "softMAC.h"
  47 #include "softOps.h"
  48 #include "softKeys.h"
  49 #include "softKeystore.h"
  50 #include "softSSL.h"
  51 #include "softASN1.h"
  52 
  53 
  54 #define local_min(a, b) ((a) < (b) ? (a) : (b))
  55 
  56 static CK_RV
  57 soft_pkcs12_pbe(soft_session_t *, CK_MECHANISM_PTR, soft_object_t *);
  58 
  59 /*
  60  * Create a temporary key object struct by filling up its template attributes.
  61  */
  62 CK_RV
  63 soft_gen_keyobject(CK_ATTRIBUTE_PTR pTemplate,  CK_ULONG ulCount,
  64     CK_ULONG *objecthandle_p, soft_session_t *sp,
  65     CK_OBJECT_CLASS class, CK_KEY_TYPE key_type, CK_ULONG keylen, CK_ULONG mode,
  66     boolean_t internal)
  67 {
  68 
  69         CK_RV rv;
  70         soft_object_t *new_objp = NULL;
  71 
  72         new_objp = calloc(1, sizeof (soft_object_t));
  73         if (new_objp == NULL) {
  74                 return (CKR_HOST_MEMORY);
  75         }
  76 
  77         new_objp->extra_attrlistp = NULL;
  78 
  79         /*
  80          * Validate attribute template and fill in the attributes
  81          * in the soft_object_t.
  82          */
  83         rv = soft_build_key(pTemplate, ulCount, new_objp, class, key_type,
  84             keylen, mode);
  85         if (rv != CKR_OK) {
  86                 goto fail_cleanup1;
  87         }
  88 
  89         /*
  90          * If generating a key is an internal request (i.e. not a C_XXX
  91          * API request), then skip the following checks.
  92          */
  93         if (!internal) {
  94                 rv = soft_pin_expired_check(new_objp);
  95                 if (rv != CKR_OK) {
  96                         goto fail_cleanup2;
  97                 }
  98 
  99                 rv = soft_object_write_access_check(sp, new_objp);
 100                 if (rv != CKR_OK) {
 101                         goto fail_cleanup2;
 102                 }
 103         }
 104 
 105         /* Initialize the rest of stuffs in soft_object_t. */
 106         (void) pthread_mutex_init(&new_objp->object_mutex, NULL);
 107         new_objp->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
 108 
 109         /* Write the new token object to the keystore */
 110         if (IS_TOKEN_OBJECT(new_objp)) {
 111                 new_objp->version = 1;
 112                 new_objp->session_handle = (CK_SESSION_HANDLE)NULL;
 113                 soft_add_token_object_to_slot(new_objp);
 114                 /*
 115                  * Type casting the address of an object struct to
 116                  * an object handle.
 117                  */
 118                 *objecthandle_p = (CK_ULONG)new_objp;
 119 
 120                 return (CKR_OK);
 121         }
 122 
 123         new_objp->session_handle = (CK_SESSION_HANDLE)sp;
 124 
 125         /* Add the new object to the session's object list. */
 126         soft_add_object_to_session(new_objp, sp);
 127 
 128         /* Type casting the address of an object struct to an object handle. */
 129         *objecthandle_p =  (CK_ULONG)new_objp;
 130 
 131         return (CKR_OK);
 132 
 133 fail_cleanup2:
 134         /*
 135          * When any error occurs after soft_build_key(), we will need to
 136          * clean up the memory allocated by the soft_build_key().
 137          */
 138         soft_cleanup_object(new_objp);
 139 
 140 fail_cleanup1:
 141         if (new_objp) {
 142                 /*
 143                  * The storage allocated inside of this object should have
 144                  * been cleaned up by the soft_build_key() if it failed.
 145                  * Therefore, we can safely free the object.
 146                  */
 147                 free(new_objp);
 148         }
 149 
 150         return (rv);
 151 }
 152 
 153 CK_RV
 154 soft_genkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
 155     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
 156 {
 157 
 158         CK_RV rv = CKR_OK;
 159         soft_object_t *secret_key;
 160         CK_KEY_TYPE key_type;
 161         CK_ULONG keylen = 0;
 162         CK_ULONG i;
 163         int des_strength = 0;
 164         int retry = 0;
 165         int keyfound = 0;
 166         boolean_t is_ssl_mech = B_FALSE;
 167 
 168         switch (pMechanism->mechanism) {
 169         case CKM_DES_KEY_GEN:
 170                 key_type = CKK_DES;
 171                 break;
 172 
 173         case CKM_DES2_KEY_GEN:
 174                 key_type = CKK_DES2;
 175                 break;
 176 
 177         case CKM_DES3_KEY_GEN:
 178                 key_type = CKK_DES3;
 179                 break;
 180 
 181         case CKM_AES_KEY_GEN:
 182                 key_type = CKK_AES;
 183                 break;
 184 
 185         case CKM_BLOWFISH_KEY_GEN:
 186                 key_type = CKK_BLOWFISH;
 187                 break;
 188 
 189         case CKM_RC4_KEY_GEN:
 190                 key_type = CKK_RC4;
 191                 break;
 192 
 193         case CKM_SSL3_PRE_MASTER_KEY_GEN:
 194         case CKM_TLS_PRE_MASTER_KEY_GEN:
 195                 if (pMechanism->pParameter == NULL ||
 196                     pMechanism->ulParameterLen != sizeof (CK_VERSION))
 197                         return (CKR_TEMPLATE_INCOMPLETE);
 198                 is_ssl_mech = B_TRUE;
 199                 key_type = CKK_GENERIC_SECRET;
 200                 keylen = 48;
 201                 break;
 202 
 203         case CKM_PKCS5_PBKD2:
 204                 keyfound = 0;
 205                 for (i = 0; i < ulCount && !keyfound; i++) {
 206                         if (pTemplate[i].type == CKA_KEY_TYPE &&
 207                             pTemplate[i].pValue != NULL) {
 208                                 key_type = *((CK_KEY_TYPE*)pTemplate[i].pValue);
 209                                 keyfound = 1;
 210                         }
 211                 }
 212                 if (!keyfound)
 213                         return (CKR_TEMPLATE_INCOMPLETE);
 214                 /*
 215                  * Make sure that parameters were given for this
 216                  * mechanism.
 217                  */
 218                 if (pMechanism->pParameter == NULL ||
 219                     pMechanism->ulParameterLen !=
 220                     sizeof (CK_PKCS5_PBKD2_PARAMS))
 221                         return (CKR_TEMPLATE_INCOMPLETE);
 222                 break;
 223 
 224         case CKM_PBE_SHA1_RC4_128:
 225                 keyfound = 0;
 226                 for (i = 0; i < ulCount; i++) {
 227                         if (pTemplate[i].type == CKA_KEY_TYPE &&
 228                             pTemplate[i].pValue != NULL) {
 229                                 key_type = *((CK_KEY_TYPE*)pTemplate[i].pValue);
 230                                 keyfound = 1;
 231                         }
 232                         if (pTemplate[i].type == CKA_VALUE_LEN &&
 233                             pTemplate[i].pValue != NULL) {
 234                                 keylen = *((CK_ULONG*)pTemplate[i].pValue);
 235                         }
 236                 }
 237                 /* If a keytype was specified, it had better be CKK_RC4 */
 238                 if (keyfound && key_type != CKK_RC4)
 239                         return (CKR_TEMPLATE_INCONSISTENT);
 240                 else if (!keyfound)
 241                         key_type = CKK_RC4;
 242 
 243                 /* If key length was specified, it better be 16 bytes */
 244                 if (keylen != 0 && keylen != 16)
 245                         return (CKR_TEMPLATE_INCONSISTENT);
 246 
 247                 /*
 248                  * Make sure that parameters were given for this
 249                  * mechanism.
 250                  */
 251                 if (pMechanism->pParameter == NULL ||
 252                     pMechanism->ulParameterLen !=
 253                     sizeof (CK_PBE_PARAMS))
 254                         return (CKR_TEMPLATE_INCOMPLETE);
 255                 break;
 256         default:
 257                 return (CKR_MECHANISM_INVALID);
 258         }
 259 
 260         /* Create a new object for secret key. */
 261         rv = soft_gen_keyobject(pTemplate, ulCount, phKey, session_p,
 262             CKO_SECRET_KEY, key_type, keylen, SOFT_GEN_KEY, B_FALSE);
 263 
 264         if (rv != CKR_OK) {
 265                 return (rv);
 266         }
 267 
 268         /* Obtain the secret object pointer. */
 269         secret_key = (soft_object_t *)*phKey;
 270 
 271         switch (pMechanism->mechanism) {
 272         case CKM_DES_KEY_GEN:
 273                 /*
 274                  * Set up key value len since it is not a required
 275                  * attribute for C_GenerateKey.
 276                  */
 277                 keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
 278                 des_strength = DES;
 279                 break;
 280 
 281         case CKM_DES2_KEY_GEN:
 282                 /*
 283                  * Set up key value len since it is not a required
 284                  * attribute for C_GenerateKey.
 285                  */
 286                 keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES2_KEYSIZE;
 287                 des_strength = DES2;
 288                 break;
 289 
 290         case CKM_DES3_KEY_GEN:
 291                 /*
 292                  * Set up key value len since it is not a required
 293                  * attribute for C_GenerateKey.
 294                  */
 295                 keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES3_KEYSIZE;
 296                 des_strength = DES3;
 297                 break;
 298 
 299         case CKM_SSL3_PRE_MASTER_KEY_GEN:
 300         case CKM_TLS_PRE_MASTER_KEY_GEN:
 301                 secret_key->bool_attr_mask |= DERIVE_BOOL_ON;
 302         /* FALLTHRU */
 303 
 304         case CKM_AES_KEY_GEN:
 305         case CKM_BLOWFISH_KEY_GEN:
 306         case CKM_PBE_SHA1_RC4_128:
 307         case CKM_RC4_KEY_GEN:
 308                 keylen = OBJ_SEC_VALUE_LEN(secret_key);
 309                 break;
 310 
 311         case CKM_PKCS5_PBKD2:
 312                 /*
 313                  * PKCS#11 does not allow one to specify key
 314                  * sizes for DES and 3DES, so we must set it here
 315                  * when using PBKD2 algorithms.
 316                  */
 317                 if (key_type == CKK_DES) {
 318                         OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
 319                         des_strength = DES;
 320                 } else if (key_type == CKK_DES3) {
 321                         OBJ_SEC_VALUE_LEN(secret_key) = DES3_KEYSIZE;
 322                         des_strength = DES3;
 323                 }
 324 
 325                 keylen = OBJ_SEC_VALUE_LEN(secret_key);
 326                 break;
 327         }
 328 
 329         if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
 330                 if (IS_TOKEN_OBJECT(secret_key))
 331                         soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
 332                 else
 333                         soft_delete_object(session_p, secret_key,
 334                             B_FALSE, B_FALSE);
 335 
 336                 return (CKR_HOST_MEMORY);
 337         }
 338         switch (pMechanism->mechanism) {
 339         case CKM_PBE_SHA1_RC4_128:
 340                 /*
 341                  * Use the PBE algorithm described in PKCS#11 section
 342                  * 12.33 to derive the key.
 343                  */
 344                 rv = soft_pkcs12_pbe(session_p, pMechanism, secret_key);
 345                 break;
 346         case CKM_PKCS5_PBKD2:
 347                 /* Generate keys using PKCS#5 PBKD2 algorithm */
 348                 rv = soft_generate_pkcs5_pbkdf2_key(session_p, pMechanism,
 349                     secret_key);
 350                 if (rv == CKR_OK && des_strength > 0) {
 351                         /* Perform weak key checking for DES and DES3. */
 352                         if (des_keycheck(OBJ_SEC_VALUE(secret_key),
 353                             des_strength, OBJ_SEC_VALUE(secret_key)) ==
 354                             B_FALSE) {
 355                                 /* We got a weak secret key. */
 356                                 rv = CKR_FUNCTION_FAILED;
 357                         }
 358                 }
 359                 break;
 360         default:
 361                 do {
 362                         /* If this fails, bail out */
 363                         rv = CKR_OK;
 364                         if (pkcs11_get_urandom(
 365                             OBJ_SEC_VALUE(secret_key), keylen) < 0) {
 366                                 rv = CKR_DEVICE_ERROR;
 367                                 break;
 368                         }
 369 
 370                         /* Perform weak key checking for DES and DES3. */
 371                         if (des_strength > 0) {
 372                                 rv = CKR_OK;
 373                                 if (des_keycheck(OBJ_SEC_VALUE(secret_key),
 374                                     des_strength, OBJ_SEC_VALUE(secret_key)) ==
 375                                     B_FALSE) {
 376                                         /* We got a weak key, retry! */
 377                                         retry++;
 378                                         rv = CKR_FUNCTION_FAILED;
 379                                 }
 380                         }
 381                         /*
 382                          * Copy over the SSL client version For SSL mechs
 383                          * The first two bytes of the key is the version
 384                          */
 385                         if (is_ssl_mech)
 386                                 bcopy(pMechanism->pParameter,
 387                                     OBJ_SEC_VALUE(secret_key),
 388                                     sizeof (CK_VERSION));
 389 
 390                 } while (rv != CKR_OK && retry < KEYGEN_RETRY);
 391                 if (retry == KEYGEN_RETRY)
 392                         rv = CKR_FUNCTION_FAILED;
 393                 break;
 394         }
 395 
 396         if (rv != CKR_OK)
 397                 if (IS_TOKEN_OBJECT(secret_key))
 398                         soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
 399                 else
 400                         soft_delete_object(session_p, secret_key,
 401                             B_FALSE, B_FALSE);
 402 
 403         if (IS_TOKEN_OBJECT(secret_key)) {
 404                 /*
 405                  * All the info has been filled, so we can write to
 406                  * keystore now.
 407                  */
 408                 rv = soft_put_object_to_keystore(secret_key);
 409                 if (rv != CKR_OK)
 410                         soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
 411         }
 412 
 413         return (rv);
 414 }
 415 
 416 CK_RV
 417 soft_genkey_pair(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
 418     CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicAttrCount,
 419     CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateAttrCount,
 420     CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
 421 {
 422 
 423         CK_RV rv;
 424         soft_object_t *public_key, *private_key;
 425         CK_KEY_TYPE key_type;
 426 
 427         switch (pMechanism->mechanism) {
 428 
 429         case CKM_RSA_PKCS_KEY_PAIR_GEN:
 430                 key_type = CKK_RSA;
 431                 break;
 432 
 433         case CKM_DSA_KEY_PAIR_GEN:
 434                 key_type = CKK_DSA;
 435                 break;
 436 
 437         case CKM_DH_PKCS_KEY_PAIR_GEN:
 438                 key_type = CKK_DH;
 439                 break;
 440 
 441         case CKM_EC_KEY_PAIR_GEN:
 442                 key_type = CKK_EC;
 443                 break;
 444 
 445         default:
 446                 return (CKR_MECHANISM_INVALID);
 447         }
 448 
 449         /* Create a new object for public key. */
 450         rv = soft_gen_keyobject(pPublicKeyTemplate, ulPublicAttrCount,
 451             phPublicKey, session_p, CKO_PUBLIC_KEY, key_type, 0,
 452             SOFT_GEN_KEY, B_FALSE);
 453 
 454         if (rv != CKR_OK) {
 455                 return (rv);
 456         }
 457 
 458         /* Obtain the public object pointer. */
 459         public_key = (soft_object_t *)*phPublicKey;
 460 
 461         /* Create a new object for private key. */
 462         rv = soft_gen_keyobject(pPrivateKeyTemplate, ulPrivateAttrCount,
 463             phPrivateKey, session_p, CKO_PRIVATE_KEY, key_type, 0,
 464             SOFT_GEN_KEY, B_FALSE);
 465 
 466         if (rv != CKR_OK) {
 467                 /*
 468                  * Both public key and private key must be successful.
 469                  */
 470                 if (IS_TOKEN_OBJECT(public_key))
 471                         soft_delete_token_object(public_key, B_FALSE, B_FALSE);
 472                 else
 473                         soft_delete_object(session_p, public_key,
 474                             B_FALSE, B_FALSE);
 475                 return (rv);
 476         }
 477 
 478         /* Obtain the private object pointer. */
 479         private_key = (soft_object_t *)*phPrivateKey;
 480 
 481         /*
 482          * At this point, both public key and private key objects
 483          * are settled with the application specified attributes.
 484          * We are ready to generate the rest of key attributes based
 485          * on the existing attributes.
 486          */
 487 
 488         switch (key_type) {
 489         case CKK_RSA:
 490                 rv = soft_rsa_genkey_pair(public_key, private_key);
 491                 break;
 492 
 493         case CKK_DSA:
 494                 rv = soft_dsa_genkey_pair(public_key, private_key);
 495                 break;
 496 
 497         case CKK_DH:
 498                 rv = soft_dh_genkey_pair(public_key, private_key);
 499                 private_key->bool_attr_mask |= DERIVE_BOOL_ON;
 500                 break;
 501         case CKK_EC:
 502                 rv = soft_ec_genkey_pair(public_key, private_key);
 503                 private_key->bool_attr_mask |= DERIVE_BOOL_ON;
 504                 break;
 505         }
 506 
 507         if (rv != CKR_OK) {
 508                 if (IS_TOKEN_OBJECT(public_key)) {
 509                         soft_delete_token_object(public_key, B_FALSE, B_FALSE);
 510                         soft_delete_token_object(private_key, B_FALSE, B_FALSE);
 511                 } else {
 512                         soft_delete_object(session_p, public_key,
 513                             B_FALSE, B_FALSE);
 514                         soft_delete_object(session_p, private_key,
 515                             B_FALSE, B_FALSE);
 516                 }
 517                 return (rv);
 518         }
 519 
 520         if (IS_TOKEN_OBJECT(public_key)) {
 521                 /*
 522                  * All the info has been filled, so we can write to
 523                  * keystore now.
 524                  */
 525                 rv = soft_put_object_to_keystore(public_key);
 526                 if (rv != CKR_OK) {
 527                         soft_delete_token_object(public_key, B_FALSE, B_FALSE);
 528                         soft_delete_token_object(private_key, B_FALSE, B_FALSE);
 529                         return (rv);
 530                 }
 531         }
 532 
 533         if (IS_TOKEN_OBJECT(private_key)) {
 534                 rv = soft_put_object_to_keystore(private_key);
 535                 if (rv != CKR_OK) {
 536                         /*
 537                          * We also need to delete the public token object
 538                          * from keystore.
 539                          */
 540                         soft_delete_token_object(public_key, B_TRUE, B_FALSE);
 541                         soft_delete_token_object(private_key, B_FALSE, B_FALSE);
 542                 }
 543         }
 544 
 545         return (rv);
 546 }
 547 
 548 
 549 CK_RV
 550 soft_key_derive_check_length(soft_object_t *secret_key, CK_ULONG max_keylen)
 551 {
 552 
 553         switch (secret_key->key_type) {
 554         case CKK_GENERIC_SECRET:
 555                 if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
 556                         OBJ_SEC_VALUE_LEN(secret_key) = max_keylen;
 557                         return (CKR_OK);
 558                 } else if (OBJ_SEC_VALUE_LEN(secret_key) > max_keylen) {
 559                         return (CKR_ATTRIBUTE_VALUE_INVALID);
 560                 }
 561                 break;
 562         case CKK_RC4:
 563         case CKK_AES:
 564         case CKK_BLOWFISH:
 565                 if ((OBJ_SEC_VALUE_LEN(secret_key) == 0) ||
 566                     (OBJ_SEC_VALUE_LEN(secret_key) > max_keylen)) {
 567                         /* RC4 and AES has variable key length */
 568                         return (CKR_ATTRIBUTE_VALUE_INVALID);
 569                 }
 570                 break;
 571         case CKK_DES:
 572                 if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
 573                         /* DES has a well-defined length */
 574                         OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
 575                         return (CKR_OK);
 576                 } else if (OBJ_SEC_VALUE_LEN(secret_key) != DES_KEYSIZE) {
 577                         return (CKR_ATTRIBUTE_VALUE_INVALID);
 578                 }
 579                 break;
 580         case CKK_DES2:
 581                 if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
 582                         /* DES2 has a well-defined length */
 583                         OBJ_SEC_VALUE_LEN(secret_key) = DES2_KEYSIZE;
 584                         return (CKR_OK);
 585                 } else if (OBJ_SEC_VALUE_LEN(secret_key) != DES2_KEYSIZE) {
 586                         return (CKR_ATTRIBUTE_VALUE_INVALID);
 587                 }
 588                 break;
 589 
 590         default:
 591                 return (CKR_MECHANISM_INVALID);
 592         }
 593 
 594         return (CKR_OK);
 595 }
 596 
 597 /*
 598  * PKCS#11 (12.33) says that v = 512 bits (64 bytes) for SHA1
 599  * PBE methods.
 600  */
 601 #define PKCS12_BUFFER_SIZE 64
 602 /*
 603  * PKCS#12 defines 3 different ID bytes to be used for
 604  * deriving keys for different operations.
 605  */
 606 #define PBE_ID_ENCRYPT  1
 607 #define PBE_ID_IV       2
 608 #define PBE_ID_MAC      3
 609 #define PBE_CEIL(a, b)  (((a)/(b)) + (((a)%(b)) > 0))
 610 
 611 static CK_RV
 612 soft_pkcs12_pbe(soft_session_t *session_p,
 613                 CK_MECHANISM_PTR pMechanism,
 614                 soft_object_t *derived_key)
 615 {
 616         CK_RV rv = CKR_OK;
 617         CK_PBE_PARAMS *params = pMechanism->pParameter;
 618         CK_ULONG c, i, j, k;
 619         CK_ULONG hashSize;
 620         CK_ULONG buffSize;
 621         /*
 622          * Terse variable names are used to make following
 623          * the PKCS#12 spec easier.
 624          */
 625         CK_BYTE *A = NULL;
 626         CK_BYTE *Ai = NULL;
 627         CK_BYTE *B = NULL;
 628         CK_BYTE *D = NULL;
 629         CK_BYTE *I = NULL, *S, *P;
 630         CK_BYTE *keybuf = NULL;
 631         CK_ULONG Alen, Ilen, Slen, Plen, AiLen, Blen, Dlen;
 632         CK_ULONG keysize = OBJ_SEC_VALUE_LEN(derived_key);
 633         CK_MECHANISM digest_mech;
 634 
 635         /* U = hash function output bits */
 636         if (pMechanism->mechanism == CKM_PBE_SHA1_RC4_128) {
 637                 hashSize = SHA1_HASH_SIZE;
 638                 buffSize = PKCS12_BUFFER_SIZE;
 639                 digest_mech.mechanism = CKM_SHA_1;
 640                 digest_mech.pParameter = NULL;
 641                 digest_mech.ulParameterLen = 0;
 642         } else {
 643                 /* we only support 1 PBE mech for now */
 644                 return (CKR_MECHANISM_INVALID);
 645         }
 646         keybuf = OBJ_SEC_VALUE(derived_key);
 647 
 648         Blen = Dlen = buffSize;
 649         D = (CK_BYTE *)malloc(Dlen);
 650         if (D == NULL) {
 651                 rv = CKR_HOST_MEMORY;
 652                 goto cleanup;
 653         }
 654 
 655         B = (CK_BYTE *)malloc(Blen);
 656         if (B == NULL) {
 657                 rv = CKR_HOST_MEMORY;
 658                 goto cleanup;
 659         }
 660 
 661         /*
 662          * Initialize some values and create some buffers
 663          * that we need later.
 664          *
 665          * Slen = buffSize * CEIL(SaltLength/buffSize)
 666          */
 667         Slen = buffSize * PBE_CEIL(params->ulSaltLen, buffSize);
 668 
 669         /*
 670          * Plen = buffSize * CEIL(PasswordLength/buffSize)
 671          */
 672         Plen = buffSize * PBE_CEIL(params->ulPasswordLen, buffSize);
 673 
 674         /*
 675          * From step 4: I = S + P, so: Ilen = Slen + Plen
 676          */
 677         Ilen = Slen + Plen;
 678         I = (CK_BYTE *)malloc(Ilen);
 679         if (I == NULL) {
 680                 rv = CKR_HOST_MEMORY;
 681                 goto cleanup;
 682         }
 683 
 684         S = I;
 685         P = I + Slen;
 686 
 687         /*
 688          * Step 1.
 689          * We are only interested in deriving keys for encrypt/decrypt
 690          * for now, so construct the "D"iversifier accordingly.
 691          */
 692         (void) memset(D, PBE_ID_ENCRYPT, Dlen);
 693 
 694         /*
 695          * Step 2.
 696          * Concatenate copies of the salt together to make S.
 697          */
 698         for (i = 0; i < Slen; i += params->ulSaltLen) {
 699                 (void) memcpy(S+i, params->pSalt,
 700                     ((Slen - i) > params->ulSaltLen ?
 701                     params->ulSaltLen : (Slen - i)));
 702         }
 703 
 704         /*
 705          * Step 3.
 706          * Concatenate copies of the password together to make
 707          * a string P.
 708          */
 709         for (i = 0; i < Plen; i += params->ulPasswordLen) {
 710                 (void) memcpy(P+i, params->pPassword,
 711                     ((Plen - i) > params->ulPasswordLen ?
 712                     params->ulPasswordLen : (Plen - i)));
 713         }
 714 
 715         /*
 716          * Step 4.
 717          * I = S+P - this is now done because S and P are
 718          * pointers into I.
 719          *
 720          * Step 5.
 721          * c= CEIL[n/u]
 722          * where n = pseudorandom bits of output desired.
 723          */
 724         c = PBE_CEIL(keysize, hashSize);
 725 
 726         /*
 727          * Step 6.
 728          */
 729         Alen = c * hashSize;
 730         A = (CK_BYTE *)malloc(Alen);
 731         if (A == NULL) {
 732                 rv = CKR_HOST_MEMORY;
 733                 goto cleanup;
 734         }
 735         AiLen = hashSize;
 736         Ai = (CK_BYTE *)malloc(AiLen);
 737         if (Ai == NULL) {
 738                 rv = CKR_HOST_MEMORY;
 739                 goto cleanup;
 740         }
 741 
 742         /*
 743          * Step 6a.
 744          * Ai = Hr(D+I)
 745          */
 746         for (i = 0; i < c; i++) {
 747                 (void) pthread_mutex_lock(&session_p->session_mutex);
 748 
 749                 if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) {
 750                         (void) pthread_mutex_unlock(&session_p->session_mutex);
 751                         rv = CKR_OPERATION_ACTIVE;
 752                         goto cleanup;
 753                 }
 754                 session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
 755                 (void) pthread_mutex_unlock(&session_p->session_mutex);
 756 
 757                 for (j = 0; j < params->ulIteration; j++) {
 758                         rv = soft_digest_init(session_p, &digest_mech);
 759                         if (rv != CKR_OK)
 760                                 goto digest_done;
 761 
 762                         if (j == 0) {
 763                                 rv = soft_digest_update(session_p, D, Dlen);
 764                                 if (rv != CKR_OK)
 765                                         goto digest_done;
 766 
 767                                 rv = soft_digest_update(session_p, I, Ilen);
 768                         } else {
 769                                 rv = soft_digest_update(session_p, Ai, AiLen);
 770                         }
 771                         if (rv != CKR_OK)
 772                                 goto digest_done;
 773 
 774                         rv = soft_digest_final(session_p, Ai, &AiLen);
 775                         if (rv != CKR_OK)
 776                                 goto digest_done;
 777                 }
 778 digest_done:
 779                 (void) pthread_mutex_lock(&session_p->session_mutex);
 780                 session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE;
 781                 (void) pthread_mutex_unlock(&session_p->session_mutex);
 782 
 783                 if (rv != CKR_OK)
 784                         goto cleanup;
 785                 /*
 786                  * Step 6b.
 787                  * Concatenate Ai to make B
 788                  */
 789                 for (j = 0; j < Blen; j += hashSize) {
 790                         (void) memcpy(B+j, Ai, ((Blen - j > hashSize) ?
 791                             hashSize : Blen - j));
 792                 }
 793 
 794                 /*
 795                  * Step 6c.
 796                  */
 797                 k = Ilen / Blen;
 798                 for (j = 0; j < k; j++) {
 799                         uchar_t idx;
 800                         CK_ULONG m, q = 1, cbit = 0;
 801 
 802                         for (m = Blen - 1; m >= (CK_ULONG)0; m--, q = 0) {
 803                                 idx = m + j*Blen;
 804 
 805                                 q += (CK_ULONG)I[idx] + (CK_ULONG)B[m];
 806                                 q += cbit;
 807                                 I[idx] = (CK_BYTE)(q & 0xff);
 808                                 cbit = (q > 0xff);
 809                         }
 810                 }
 811 
 812                 /*
 813                  * Step 7.
 814                  *  A += Ai
 815                  */
 816                 (void) memcpy(A + i*hashSize, Ai, AiLen);
 817         }
 818 
 819         /*
 820          * Step 8.
 821          * The final output of this process is the A buffer
 822          */
 823         (void) memcpy(keybuf, A, keysize);
 824 
 825 cleanup:
 826         freezero(A, Alen);
 827         freezero(Ai, AiLen);
 828         freezero(B, Blen);
 829         freezero(D, Dlen);
 830         freezero(I, Ilen);
 831         return (rv);
 832 }
 833 
 834 CK_RV
 835 soft_derivekey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
 836     soft_object_t *basekey_p, CK_ATTRIBUTE_PTR pTemplate,
 837     CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
 838 {
 839 
 840         CK_RV rv = CKR_OK;
 841         soft_object_t *secret_key;
 842         CK_MECHANISM digest_mech;
 843         CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
 844         CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
 845         CK_ULONG secret_key_len;
 846         CK_ULONG hash_size;
 847 
 848         switch (pMechanism->mechanism) {
 849         case CKM_DH_PKCS_DERIVE:
 850                 /*
 851                  * Create a new object for secret key. The key type should
 852                  * be provided in the template.
 853                  */
 854                 rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
 855                     phKey, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL, 0,
 856                     SOFT_DERIVE_KEY_DH, B_FALSE);
 857 
 858                 if (rv != CKR_OK) {
 859                         return (rv);
 860                 }
 861 
 862                 /* Obtain the secret object pointer. */
 863                 secret_key = (soft_object_t *)*phKey;
 864 
 865                 rv = soft_dh_key_derive(basekey_p, secret_key,
 866                     (CK_BYTE *)pMechanism->pParameter,
 867                     pMechanism->ulParameterLen);
 868 
 869                 if (rv != CKR_OK) {
 870                         if (IS_TOKEN_OBJECT(secret_key))
 871                                 soft_delete_token_object(secret_key, B_FALSE,
 872                                     B_FALSE);
 873                         else
 874                                 soft_delete_object(session_p, secret_key,
 875                                     B_FALSE, B_FALSE);
 876                         return (rv);
 877                 }
 878 
 879                 break;
 880 
 881         case CKM_ECDH1_DERIVE:
 882                 /*
 883                  * Create a new object for secret key. The key type should
 884                  * be provided in the template.
 885                  */
 886                 rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
 887                     phKey, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL, 0,
 888                     SOFT_DERIVE_KEY_DH, B_FALSE);
 889 
 890                 if (rv != CKR_OK) {
 891                         return (rv);
 892                 }
 893 
 894                 /* Obtain the secret object pointer. */
 895                 secret_key = (soft_object_t *)*phKey;
 896 
 897                 rv = soft_ec_key_derive(basekey_p, secret_key,
 898                     (CK_BYTE *)pMechanism->pParameter,
 899                     pMechanism->ulParameterLen);
 900 
 901                 if (rv != CKR_OK) {
 902                         if (IS_TOKEN_OBJECT(secret_key))
 903                                 soft_delete_token_object(secret_key, B_FALSE,
 904                                     B_FALSE);
 905                         else
 906                                 soft_delete_object(session_p, secret_key,
 907                                     B_FALSE, B_FALSE);
 908                         return (rv);
 909                 }
 910 
 911                 break;
 912 
 913         case CKM_SHA1_KEY_DERIVATION:
 914                 hash_size = SHA1_HASH_SIZE;
 915                 digest_mech.mechanism = CKM_SHA_1;
 916                 goto common;
 917 
 918         case CKM_MD5_KEY_DERIVATION:
 919                 hash_size = MD5_HASH_SIZE;
 920                 digest_mech.mechanism = CKM_MD5;
 921                 goto common;
 922 
 923         case CKM_SHA256_KEY_DERIVATION:
 924                 hash_size = SHA256_DIGEST_LENGTH;
 925                 digest_mech.mechanism = CKM_SHA256;
 926                 goto common;
 927 
 928         case CKM_SHA384_KEY_DERIVATION:
 929                 hash_size = SHA384_DIGEST_LENGTH;
 930                 digest_mech.mechanism = CKM_SHA384;
 931                 goto common;
 932 
 933         case CKM_SHA512_KEY_DERIVATION:
 934                 hash_size = SHA512_DIGEST_LENGTH;
 935                 digest_mech.mechanism = CKM_SHA512;
 936                 goto common;
 937 
 938 common:
 939                 /*
 940                  * Create a new object for secret key. The key type is optional
 941                  * to be provided in the template. If it is not specified in
 942                  * the template, the default is CKK_GENERIC_SECRET.
 943                  */
 944                 rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
 945                     phKey, session_p, CKO_SECRET_KEY,
 946                     (CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
 947                     SOFT_DERIVE_KEY_OTHER, B_FALSE);
 948 
 949                 if (rv != CKR_OK) {
 950                         return (rv);
 951                 }
 952 
 953                 /* Obtain the secret object pointer. */
 954                 secret_key = (soft_object_t *)*phKey;
 955 
 956                 /* Validate the key type and key length */
 957                 rv = soft_key_derive_check_length(secret_key, hash_size);
 958                 if (rv != CKR_OK) {
 959                         if (IS_TOKEN_OBJECT(secret_key))
 960                                 soft_delete_token_object(secret_key, B_FALSE,
 961                                     B_FALSE);
 962                         else
 963                                 soft_delete_object(session_p, secret_key,
 964                                     B_FALSE, B_FALSE);
 965                         return (rv);
 966                 }
 967 
 968                 /*
 969                  * Derive the secret key by digesting the value of another
 970                  * secret key (base key) with SHA-1 or MD5.
 971                  */
 972                 rv = soft_digest_init_internal(session_p, &digest_mech);
 973                 if (rv != CKR_OK) {
 974                         if (IS_TOKEN_OBJECT(secret_key))
 975                                 soft_delete_token_object(secret_key, B_FALSE,
 976                                     B_FALSE);
 977                         else
 978                                 soft_delete_object(session_p, secret_key,
 979                                     B_FALSE, B_FALSE);
 980                         return (rv);
 981                 }
 982 
 983                 rv = soft_digest(session_p, OBJ_SEC_VALUE(basekey_p),
 984                     OBJ_SEC_VALUE_LEN(basekey_p), hash, &hash_len);
 985 
 986                 (void) pthread_mutex_lock(&session_p->session_mutex);
 987                 /* soft_digest_common() has freed the digest context */
 988                 session_p->digest.flags = 0;
 989                 (void) pthread_mutex_unlock(&session_p->session_mutex);
 990 
 991                 if (rv != CKR_OK) {
 992                         if (IS_TOKEN_OBJECT(secret_key))
 993                                 soft_delete_token_object(secret_key, B_FALSE,
 994                                     B_FALSE);
 995                         else
 996                                 soft_delete_object(session_p, secret_key,
 997                                     B_FALSE, B_FALSE);
 998                         return (rv);
 999                 }
1000 
1001                 secret_key_len = OBJ_SEC_VALUE_LEN(secret_key);
1002 
1003                 if ((OBJ_SEC_VALUE(secret_key) = malloc(secret_key_len)) ==
1004                     NULL) {
1005                         if (IS_TOKEN_OBJECT(secret_key))
1006                                 soft_delete_token_object(secret_key, B_FALSE,
1007                                     B_FALSE);
1008                         else
1009                                 soft_delete_object(session_p, secret_key,
1010                                     B_FALSE, B_FALSE);
1011                         return (CKR_HOST_MEMORY);
1012                 }
1013 
1014                 /*
1015                  * The key produced by this mechanism will be of the
1016                  * specified type and length.
1017                  * The truncation removes extra bytes from the leading
1018                  * of the digested key value.
1019                  */
1020                 (void) memcpy(OBJ_SEC_VALUE(secret_key),
1021                     (hash + hash_len - secret_key_len),
1022                     secret_key_len);
1023 
1024                 break;
1025 
1026         /*
1027          * The key sensitivity and extractability rules for the generated
1028          * keys will be enforced inside soft_ssl_master_key_derive() and
1029          * soft_ssl_key_and_mac_derive()
1030          */
1031         case CKM_SSL3_MASTER_KEY_DERIVE:
1032         case CKM_SSL3_MASTER_KEY_DERIVE_DH:
1033         case CKM_TLS_MASTER_KEY_DERIVE:
1034         case CKM_TLS_MASTER_KEY_DERIVE_DH:
1035                 if (phKey == NULL_PTR)
1036                         return (CKR_ARGUMENTS_BAD);
1037                 return (soft_ssl_master_key_derive(session_p, pMechanism,
1038                     basekey_p, pTemplate, ulAttributeCount, phKey));
1039 
1040         case CKM_SSL3_KEY_AND_MAC_DERIVE:
1041         case CKM_TLS_KEY_AND_MAC_DERIVE:
1042                 return (soft_ssl_key_and_mac_derive(session_p, pMechanism,
1043                     basekey_p, pTemplate, ulAttributeCount));
1044 
1045         case CKM_TLS_PRF:
1046                 if (pMechanism->pParameter == NULL ||
1047                     pMechanism->ulParameterLen != sizeof (CK_TLS_PRF_PARAMS) ||
1048                     phKey != NULL)
1049                         return (CKR_ARGUMENTS_BAD);
1050 
1051                 if (pTemplate != NULL)
1052                         return (CKR_TEMPLATE_INCONSISTENT);
1053 
1054                 return (derive_tls_prf(
1055                     (CK_TLS_PRF_PARAMS_PTR)pMechanism->pParameter, basekey_p));
1056 
1057         default:
1058                 return (CKR_MECHANISM_INVALID);
1059         }
1060 
1061         soft_derive_enforce_flags(basekey_p, secret_key);
1062 
1063         if (IS_TOKEN_OBJECT(secret_key)) {
1064                 /*
1065                  * All the info has been filled, so we can write to
1066                  * keystore now.
1067                  */
1068                 rv = soft_put_object_to_keystore(secret_key);
1069                 if (rv != CKR_OK)
1070                         soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
1071         }
1072 
1073         return (rv);
1074 }
1075 
1076 
1077 /*
1078  * Perform key derivation rules on key's sensitivity and extractability.
1079  */
1080 void
1081 soft_derive_enforce_flags(soft_object_t *basekey, soft_object_t *newkey)
1082 {
1083 
1084         boolean_t new_sensitive = B_FALSE;
1085         boolean_t new_extractable = B_FALSE;
1086 
1087         /*
1088          * The sensitive and extractable bits have been set when
1089          * the newkey was built.
1090          */
1091         if (newkey->bool_attr_mask & SENSITIVE_BOOL_ON) {
1092                 new_sensitive = B_TRUE;
1093         }
1094 
1095         if (newkey->bool_attr_mask & EXTRACTABLE_BOOL_ON) {
1096                 new_extractable = B_TRUE;
1097         }
1098 
1099         /* Derive the CKA_ALWAYS_SENSITIVE flag */
1100         if (!basekey->bool_attr_mask & ALWAYS_SENSITIVE_BOOL_ON) {
1101                 /*
1102                  * If the base key has its CKA_ALWAYS_SENSITIVE set to
1103                  * FALSE, then the derived key will as well.
1104                  */
1105                 newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1106         } else {
1107                 /*
1108                  * If the base key has its CKA_ALWAYS_SENSITIVE set to TRUE,
1109                  * then the derived key has the CKA_ALWAYS_SENSITIVE set to
1110                  * the same value as its CKA_SENSITIVE;
1111                  */
1112                 if (new_sensitive) {
1113                         newkey->bool_attr_mask |= ALWAYS_SENSITIVE_BOOL_ON;
1114                 } else {
1115                         newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1116                 }
1117         }
1118 
1119         /* Derive the CKA_NEVER_EXTRACTABLE flag */
1120         if (!basekey->bool_attr_mask & NEVER_EXTRACTABLE_BOOL_ON) {
1121                 /*
1122                  * If the base key has its CKA_NEVER_EXTRACTABLE set to
1123                  * FALSE, then the derived key will as well.
1124                  */
1125                 newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1126         } else {
1127                 /*
1128                  * If the base key has its CKA_NEVER_EXTRACTABLE set to TRUE,
1129                  * then the derived key has the CKA_NEVER_EXTRACTABLE set to
1130                  * the opposite value from its CKA_EXTRACTABLE;
1131                  */
1132                 if (new_extractable) {
1133                         newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1134                 } else {
1135                         newkey->bool_attr_mask |= NEVER_EXTRACTABLE_BOOL_ON;
1136                 }
1137         }
1138 
1139         /* Set the CKA_LOCAL flag to false */
1140         newkey->bool_attr_mask &= ~LOCAL_BOOL_ON;
1141 }
1142 
1143 
1144 /*
1145  * do_prf
1146  *
1147  * This routine implements Step 3. of the PBKDF2 function
1148  * defined in PKCS#5 for generating derived keys from a
1149  * password.
1150  *
1151  * Currently, PRF is always SHA_1_HMAC.
1152  */
1153 static CK_RV
1154 do_prf(soft_session_t *session_p,
1155         CK_PKCS5_PBKD2_PARAMS_PTR params,
1156         soft_object_t *hmac_key,
1157         CK_BYTE *newsalt, CK_ULONG saltlen,
1158         CK_BYTE *blockdata, CK_ULONG blocklen)
1159 {
1160         CK_RV rv = CKR_OK;
1161         CK_MECHANISM digest_mech = {CKM_SHA_1_HMAC, NULL, 0};
1162         CK_BYTE buffer[2][SHA1_HASH_SIZE];
1163         CK_ULONG hmac_outlen = SHA1_HASH_SIZE;
1164         CK_ULONG inlen;
1165         CK_BYTE *input, *output;
1166         CK_ULONG i, j;
1167 
1168         input = newsalt;
1169         inlen = saltlen;
1170 
1171         output = buffer[1];
1172         (void) pthread_mutex_lock(&session_p->session_mutex);
1173 
1174         if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) {
1175                 (void) pthread_mutex_unlock(&session_p->session_mutex);
1176                 return (CKR_OPERATION_ACTIVE);
1177         }
1178         session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
1179         (void) pthread_mutex_unlock(&session_p->session_mutex);
1180 
1181         for (i = 0; i < params->iterations; i++) {
1182                 /*
1183                  * The key doesn't change, its always the
1184                  * password iniitally given.
1185                  */
1186                 rv = soft_sign_init(session_p, &digest_mech, hmac_key);
1187 
1188                 if (rv != CKR_OK) {
1189                         goto cleanup;
1190                 }
1191 
1192                 /* Call PRF function (SHA1_HMAC for now). */
1193                 rv = soft_sign(session_p, input, inlen, output, &hmac_outlen);
1194 
1195                 if (rv != CKR_OK) {
1196                         goto cleanup;
1197                 }
1198                 /*
1199                  * The first time, initialize the output buffer
1200                  * with the HMAC signature.
1201                  */
1202                 if (i == 0) {
1203                         (void) memcpy(blockdata, output,
1204                             local_min(blocklen, hmac_outlen));
1205                 } else {
1206                         /*
1207                          * XOR the existing data with output from PRF.
1208                          *
1209                          * Only XOR up to the length of the blockdata,
1210                          * it may be less than a full hmac buffer when
1211                          * the final block is being computed.
1212                          */
1213                         for (j = 0; j < hmac_outlen && j < blocklen; j++)
1214                                 blockdata[j] ^= output[j];
1215                 }
1216                 /* Output from previous PRF is input for next round */
1217                 input = output;
1218                 inlen = hmac_outlen;
1219 
1220                 /*
1221                  * Switch buffers to avoid overuse of memcpy.
1222                  * Initially we used buffer[1], so after the end of
1223                  * the first iteration (i==0), we switch to buffer[0]
1224                  * and continue swapping with each iteration.
1225                  */
1226                 output = buffer[i%2];
1227         }
1228 cleanup:
1229         (void) pthread_mutex_lock(&session_p->session_mutex);
1230         session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE;
1231         (void) pthread_mutex_unlock(&session_p->session_mutex);
1232 
1233         return (rv);
1234 }
1235 
1236 static CK_RV
1237 soft_create_hmac_key(soft_session_t *session_p,  CK_BYTE *passwd,
1238                 CK_ULONG passwd_len, CK_OBJECT_HANDLE_PTR phKey)
1239 {
1240         CK_RV rv = CKR_OK;
1241         CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
1242         CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
1243         CK_BBOOL True = TRUE;
1244         CK_ATTRIBUTE keytemplate[4];
1245         /*
1246          * We must initialize each template member individually
1247          * because at the time of initial coding for ON10, the
1248          * compiler was using the "-xc99=%none" option
1249          * which prevents us from being able to declare the whole
1250          * template in place as usual.
1251          */
1252         keytemplate[0].type = CKA_CLASS;
1253         keytemplate[0].pValue = &keyclass;
1254         keytemplate[0].ulValueLen =  sizeof (keyclass);
1255 
1256         keytemplate[1].type = CKA_KEY_TYPE;
1257         keytemplate[1].pValue = &keytype;
1258         keytemplate[1].ulValueLen =  sizeof (keytype);
1259 
1260         keytemplate[2].type = CKA_SIGN;
1261         keytemplate[2].pValue = &True;
1262         keytemplate[2].ulValueLen =  sizeof (True);
1263 
1264         keytemplate[3].type = CKA_VALUE;
1265         keytemplate[3].pValue = passwd;
1266         keytemplate[3].ulValueLen = passwd_len;
1267         /*
1268          * Create a generic key object to be used for HMAC operations.
1269          * The "value" for this key is the password from the
1270          * mechanism parameter structure.
1271          */
1272         rv = soft_gen_keyobject(keytemplate,
1273             sizeof (keytemplate)/sizeof (CK_ATTRIBUTE), phKey, session_p,
1274             CKO_SECRET_KEY, (CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
1275             SOFT_CREATE_OBJ, B_TRUE);
1276 
1277         return (rv);
1278 }
1279 
1280 CK_RV
1281 soft_generate_pkcs5_pbkdf2_key(soft_session_t *session_p,
1282                 CK_MECHANISM_PTR pMechanism,
1283                 soft_object_t *secret_key)
1284 {
1285         CK_RV rv = CKR_OK;
1286         CK_PKCS5_PBKD2_PARAMS   *params =
1287             (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
1288         CK_ULONG hLen = SHA1_HASH_SIZE;
1289         CK_ULONG dkLen, i;
1290         CK_ULONG blocks, remainder;
1291         CK_OBJECT_HANDLE phKey = 0;
1292         soft_object_t *hmac_key = NULL;
1293         CK_BYTE *salt = NULL;
1294         CK_BYTE *keydata = NULL;
1295 
1296         params = (CK_PKCS5_PBKD2_PARAMS_PTR) pMechanism->pParameter;
1297 
1298         if (params->prf != CKP_PKCS5_PBKD2_HMAC_SHA1)
1299                 return (CKR_MECHANISM_PARAM_INVALID);
1300 
1301         if (params->pPrfData != NULL || params->ulPrfDataLen != 0)
1302                 return (CKR_DATA_INVALID);
1303 
1304         if (params->saltSource != CKZ_SALT_SPECIFIED ||
1305             params->iterations == 0)
1306                 return (CKR_MECHANISM_PARAM_INVALID);
1307 
1308         /*
1309          * Create a key object to use for HMAC operations.
1310          */
1311         rv = soft_create_hmac_key(session_p, params->pPassword,
1312             *params->ulPasswordLen, &phKey);
1313 
1314         if (rv != CKR_OK)
1315                 return (rv);
1316 
1317         hmac_key = (soft_object_t *)phKey;
1318 
1319         /* Step 1. */
1320         dkLen = OBJ_SEC_VALUE_LEN(secret_key);  /* length of desired key */
1321 
1322         if (dkLen > ((((u_longlong_t)1)<<32)-1)*hLen) {
1323                 (void) soft_delete_object(session_p, hmac_key, B_FALSE,
1324                     B_FALSE);
1325                 return (CKR_KEY_SIZE_RANGE);
1326         }
1327 
1328         /* Step 2. */
1329         blocks = dkLen / hLen;
1330 
1331         /* crude "Ceiling" function to adjust the number of blocks to use */
1332         if (blocks * hLen != dkLen)
1333                 blocks++;
1334 
1335         remainder = dkLen - ((blocks - 1) * hLen);
1336 
1337         /* Step 3 */
1338         salt = (CK_BYTE *)malloc(params->ulSaltSourceDataLen + 4);
1339         if (salt == NULL) {
1340                 (void) soft_delete_object(session_p, hmac_key, B_FALSE,
1341                     B_FALSE);
1342                 return (CKR_HOST_MEMORY);
1343         }
1344         /*
1345          * Nothing in PKCS#5 says you cannot pass an empty
1346          * salt, so we will allow for this and not return error
1347          * if the salt is not specified.
1348          */
1349         if (params->pSaltSourceData != NULL && params->ulSaltSourceDataLen > 0)
1350                 (void) memcpy(salt, params->pSaltSourceData,
1351                     params->ulSaltSourceDataLen);
1352 
1353         /*
1354          * Get pointer to the data section of the key,
1355          * this will be used below as output from the
1356          * PRF iteration/concatenations so that when the
1357          * blocks are all iterated, the secret_key will
1358          * have the resulting derived key value.
1359          */
1360         keydata = (CK_BYTE *)OBJ_SEC_VALUE(secret_key);
1361 
1362         /* Step 4. */
1363         for (i = 0; i < blocks && (rv == CKR_OK); i++) {
1364                 CK_BYTE *s;
1365 
1366                 s = salt + params->ulSaltSourceDataLen;
1367 
1368                 /*
1369                  * Append the block index to the salt as input
1370                  * to the PRF.  Block index should start at 1
1371                  * not 0.
1372                  */
1373                 *s++ = ((i+1) >> 24) & 0xff;
1374                 *s++ = ((i+1) >> 16) & 0xff;
1375                 *s++ = ((i+1) >> 8) & 0xff;
1376                 *s   = ((i+1)) & 0xff;
1377 
1378                 /*
1379                  * Adjust the key pointer so we always append the
1380                  * PRF output to the current key.
1381                  */
1382                 rv = do_prf(session_p, params, hmac_key,
1383                     salt, params->ulSaltSourceDataLen + 4, keydata,
1384                     ((i + 1) == blocks ? remainder : hLen));
1385 
1386                 keydata += hLen;
1387         }
1388         (void) soft_delete_object(session_p, hmac_key, B_FALSE, B_FALSE);
1389         freezero(salt, params->ulSaltSourceDataLen);
1390 
1391         return (rv);
1392 }
1393 
1394 CK_RV
1395 soft_wrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1396                 soft_object_t *wrappingKey_p, soft_object_t *hkey_p,
1397                 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
1398 {
1399         CK_RV           rv = CKR_OK;
1400         CK_ULONG        plain_len = 0;
1401         CK_BYTE_PTR     plain_data = NULL;
1402         CK_ULONG        padded_len = 0;
1403         CK_BYTE_PTR     padded_data = NULL;
1404         CK_ULONG        wkey_blksz = 1;         /* so modulo will work right */
1405 
1406         /* Check if the mechanism is supported. */
1407         switch (pMechanism->mechanism) {
1408         case CKM_DES_CBC_PAD:
1409         case CKM_DES3_CBC_PAD:
1410         case CKM_AES_CBC_PAD:
1411                 /*
1412                  * Secret key mechs with padding can be used to wrap secret
1413                  * keys and private keys only.  See PKCS#11, * sec 11.14,
1414                  * C_WrapKey and secs 12.* for each mechanism's wrapping/
1415                  * unwrapping constraints.
1416                  */
1417                 if (hkey_p->class != CKO_SECRET_KEY && hkey_p->class !=
1418                     CKO_PRIVATE_KEY)
1419                         return (CKR_MECHANISM_INVALID);
1420                 break;
1421         case CKM_RSA_PKCS:
1422         case CKM_RSA_X_509:
1423         case CKM_DES_ECB:
1424         case CKM_DES3_ECB:
1425         case CKM_AES_ECB:
1426         case CKM_DES_CBC:
1427         case CKM_DES3_CBC:
1428         case CKM_AES_CBC:
1429         case CKM_AES_CTR:
1430         case CKM_BLOWFISH_CBC:
1431                 /*
1432                  * Unpadded secret key mechs and private key mechs are only
1433                  * defined for wrapping secret keys.  See PKCS#11 refs above.
1434                  */
1435                 if (hkey_p->class != CKO_SECRET_KEY)
1436                         return (CKR_MECHANISM_INVALID);
1437                 break;
1438         default:
1439                 return (CKR_MECHANISM_INVALID);
1440         }
1441 
1442         if (hkey_p->class == CKO_SECRET_KEY) {
1443                 plain_data = OBJ_SEC_VALUE(hkey_p);
1444                 plain_len = OBJ_SEC_VALUE_LEN(hkey_p);
1445         } else {
1446                 /*
1447                  * BER-encode the object to be wrapped:  call first with
1448                  * plain_data = NULL to get the size needed, allocate that
1449                  * much space, call again to fill space with actual data.
1450                  */
1451                 rv = soft_object_to_asn1(hkey_p, NULL, &plain_len);
1452                 if (rv != CKR_OK)
1453                         return (rv);
1454                 if ((plain_data = malloc(plain_len)) == NULL)
1455                         return (CKR_HOST_MEMORY);
1456                 (void) memset(plain_data, 0x0, plain_len);
1457                 rv = soft_object_to_asn1(hkey_p, plain_data, &plain_len);
1458                 if (rv != CKR_OK)
1459                         goto cleanup_wrap;
1460         }
1461 
1462         /*
1463          * For unpadded ECB and CBC mechanisms, the object needs to be
1464          * padded to the wrapping key's blocksize prior to the encryption.
1465          */
1466         padded_len = plain_len;
1467         padded_data = plain_data;
1468 
1469         switch (pMechanism->mechanism) {
1470         case CKM_DES_ECB:
1471         case CKM_DES3_ECB:
1472         case CKM_AES_ECB:
1473         case CKM_DES_CBC:
1474         case CKM_DES3_CBC:
1475         case CKM_AES_CBC:
1476         case CKM_BLOWFISH_CBC:
1477                 /* Find the block size of the wrapping key. */
1478                 if (wrappingKey_p->class == CKO_SECRET_KEY) {
1479                         switch (wrappingKey_p->key_type) {
1480                         case CKK_DES:
1481                         case CKK_DES2:
1482                         case CKK_DES3:
1483                                 wkey_blksz = DES_BLOCK_LEN;
1484                                 break;
1485                         case CKK_AES:
1486                                 wkey_blksz = AES_BLOCK_LEN;
1487                                 break;
1488                         case CKK_BLOWFISH:
1489                                 wkey_blksz = BLOWFISH_BLOCK_LEN;
1490                                 break;
1491                         default:
1492                                 break;
1493                         }
1494                 } else {
1495                         rv = CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
1496                         goto cleanup_wrap;
1497                 }
1498 
1499                 /* Extend the plain text data to block size boundary.  */
1500                 if ((padded_len % wkey_blksz) != 0) {
1501                         padded_len += (wkey_blksz - (plain_len % wkey_blksz));
1502                         if ((padded_data = malloc(padded_len)) == NULL) {
1503                                 rv = CKR_HOST_MEMORY;
1504                                 goto cleanup_wrap;
1505                         }
1506                         (void) memset(padded_data, 0x0, padded_len);
1507                         (void) memcpy(padded_data, plain_data, plain_len);
1508                 }
1509                 break;
1510         default:
1511                 break;
1512         }
1513 
1514         rv = soft_encrypt_init(session_p, pMechanism, wrappingKey_p);
1515         if (rv != CKR_OK)
1516                 goto cleanup_wrap;
1517 
1518         rv = soft_encrypt(session_p, padded_data, padded_len,
1519             pWrappedKey, pulWrappedKeyLen);
1520 
1521 cleanup_wrap:
1522         if (padded_data != NULL && padded_len != plain_len) {
1523                 /* Clear buffer before returning to memory pool. */
1524                 freezero(padded_data, padded_len);
1525         }
1526 
1527         if ((hkey_p->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1528                 /* Clear buffer before returning to memory pool. */
1529                 freezero(plain_data, plain_len);
1530         }
1531 
1532         return (rv);
1533 }
1534 
1535 /*
1536  * Quick check for whether unwrapped key length is appropriate for key type
1537  * and whether it needs to be truncated (in case the wrapping function had
1538  * to pad the key prior to wrapping).
1539  */
1540 static CK_RV
1541 soft_unwrap_secret_len_check(CK_KEY_TYPE keytype, CK_MECHANISM_TYPE mechtype,
1542         CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
1543 {
1544         CK_ULONG        i;
1545         boolean_t       isValueLen = B_FALSE;
1546 
1547         /*
1548          * Based on the key type and the mech used to unwrap, need to
1549          * determine if CKA_VALUE_LEN should or should not be specified.
1550          * PKCS#11 v2.11 restricts CKA_VALUE_LEN from being specified
1551          * for C_UnwrapKey for all mechs and key types, but v2.20 loosens
1552          * that restriction, perhaps because it makes it impossible to
1553          * determine the original length of unwrapped variable-length secret
1554          * keys, such as RC4, AES, and GENERIC_SECRET.  These variable-length
1555          * secret keys would have been padded with trailing null-bytes so
1556          * that they could be successfully wrapped with *_ECB and *_CBC
1557          * mechanisms.  Hence for unwrapping with these mechs, CKA_VALUE_LEN
1558          * must be specified.  For unwrapping with other mechs, such as
1559          * *_CBC_PAD, the CKA_VALUE_LEN is not needed.
1560          */
1561 
1562         /* Find out if template has CKA_VALUE_LEN. */
1563         for (i = 0; i < ulAttributeCount; i++) {
1564                 if (pTemplate[i].type == CKA_VALUE_LEN &&
1565                     pTemplate[i].pValue != NULL) {
1566                         isValueLen = B_TRUE;
1567                         break;
1568                 }
1569         }
1570 
1571         /* Does its presence  conflict with the mech type and key type? */
1572         switch (mechtype) {
1573         case CKM_DES_ECB:
1574         case CKM_DES3_ECB:
1575         case CKM_AES_ECB:
1576         case CKM_DES_CBC:
1577         case CKM_DES3_CBC:
1578         case CKM_AES_CBC:
1579         case CKM_BLOWFISH_CBC:
1580                 /*
1581                  * CKA_VALUE_LEN must be specified
1582                  * if keytype is CKK_RC4, CKK_AES and CKK_GENERIC_SECRET
1583                  * and must not be specified otherwise
1584                  */
1585                 switch (keytype) {
1586                 case CKK_DES:
1587                 case CKK_DES2:
1588                 case CKK_DES3:
1589                         if (isValueLen)
1590                                 return (CKR_TEMPLATE_INCONSISTENT);
1591                         break;
1592                 case CKK_GENERIC_SECRET:
1593                 case CKK_RC4:
1594                 case CKK_AES:
1595                 case CKK_BLOWFISH:
1596                         if (!isValueLen)
1597                                 return (CKR_TEMPLATE_INCOMPLETE);
1598                         break;
1599                 default:
1600                         return (CKR_FUNCTION_NOT_SUPPORTED);
1601                 }
1602                 break;
1603         default:
1604                 /* CKA_VALUE_LEN must not be specified */
1605                 if (isValueLen)
1606                         return (CKR_TEMPLATE_INCONSISTENT);
1607                 break;
1608         }
1609 
1610         return (CKR_OK);
1611 }
1612 
1613 CK_RV
1614 soft_unwrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1615                 soft_object_t *unwrappingkey_p,
1616                 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
1617                 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
1618                 CK_OBJECT_HANDLE_PTR phKey)
1619 {
1620         CK_RV                   rv = CKR_OK;
1621         CK_OBJECT_CLASS         new_obj_class = ~0UL;
1622         int                     i = 0;
1623         soft_object_t           *new_objp = NULL;
1624         boolean_t               persistent = B_FALSE;
1625         CK_BYTE_PTR             plain_data = NULL;
1626         CK_ULONG                plain_len = 0;
1627         secret_key_obj_t        *sck = NULL;
1628 
1629         /* Scan the attribute template for the object class. */
1630         if (pTemplate != NULL && ulAttributeCount != 0) {
1631                 for (i = 0; i < ulAttributeCount; i++) {
1632                         if (pTemplate[i].type == CKA_CLASS) {
1633                                 new_obj_class =
1634                                     *((CK_OBJECT_CLASS *)pTemplate[i].pValue);
1635                                 break;
1636                         }
1637                 }
1638                 if (new_obj_class == ~0UL)
1639                         return (CKR_TEMPLATE_INCOMPLETE);
1640         }
1641 
1642         /*
1643          * Check if the mechanism is supported, and now that the new
1644          * object's class is known, the mechanism selected should be
1645          * capable of doing the unwrap.
1646          */
1647         switch (pMechanism->mechanism) {
1648         case CKM_RSA_PKCS:
1649         case CKM_RSA_X_509:
1650         case CKM_DES_ECB:
1651         case CKM_DES3_ECB:
1652         case CKM_AES_ECB:
1653         case CKM_DES_CBC:
1654         case CKM_DES3_CBC:
1655         case CKM_AES_CBC:
1656         case CKM_BLOWFISH_CBC:
1657                 if (new_obj_class != CKO_SECRET_KEY)
1658                         return (CKR_MECHANISM_INVALID);
1659                 break;
1660         case CKM_DES_CBC_PAD:
1661         case CKM_DES3_CBC_PAD:
1662         case CKM_AES_CBC_PAD:
1663                 if (new_obj_class != CKO_SECRET_KEY && new_obj_class !=
1664                     CKO_PRIVATE_KEY)
1665                         return (CKR_MECHANISM_INVALID);
1666                 break;
1667         default:
1668                 return (CKR_MECHANISM_INVALID);
1669         }
1670 
1671         /* Create a new object based on the attribute template. */
1672         rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
1673             (CK_ULONG *)&new_objp, session_p, (CK_OBJECT_CLASS)~0UL,
1674             (CK_KEY_TYPE)~0UL, 0, SOFT_UNWRAP_KEY, B_FALSE);
1675         if (rv != CKR_OK)
1676                 return (rv);
1677 
1678         /*
1679          * New key will have CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE
1680          * both set to FALSE.  CKA_EXTRACTABLE will be set _by_default_ to
1681          * true -- leaving the possibility that it may be set FALSE by the
1682          * supplied attribute template.  If the precise template cannot be
1683          * supported, unwrap fails.  PKCS#11 spec, Sec. 11.14, C_UnwrapKey.
1684          *
1685          * Therefore, check the new object's NEVER_EXTRACTABLE_BOOL_ON and
1686          * ALWAYS_SENSITVE_BOOL_ON; if they are TRUE, the template must
1687          * have supplied them and therefore we cannot honor the unwrap.
1688          */
1689         if ((new_objp->bool_attr_mask & NEVER_EXTRACTABLE_BOOL_ON) ||
1690             (new_objp->bool_attr_mask & ALWAYS_SENSITIVE_BOOL_ON)) {
1691                 rv = CKR_TEMPLATE_INCONSISTENT;
1692                 goto cleanup_unwrap;
1693         }
1694 
1695         rv = soft_decrypt_init(session_p, pMechanism, unwrappingkey_p);
1696         if (rv != CKR_OK)
1697                 goto cleanup_unwrap;
1698 
1699         /* First get the length of the plain data */
1700         rv = soft_decrypt(session_p, pWrappedKey, ulWrappedKeyLen, NULL,
1701             &plain_len);
1702         if (rv != CKR_OK)
1703                 goto cleanup_unwrap;
1704 
1705         /* Allocate space for the unwrapped data */
1706         if ((plain_data = malloc(plain_len)) == NULL) {
1707                 rv = CKR_HOST_MEMORY;
1708                 goto cleanup_unwrap;
1709         }
1710         (void) memset(plain_data, 0x0, plain_len);
1711 
1712         /* Perform actual decryption into the allocated space. */
1713         rv = soft_decrypt(session_p, pWrappedKey, ulWrappedKeyLen, plain_data,
1714             &plain_len);
1715         if (rv != CKR_OK)
1716                 goto cleanup_unwrap;
1717 
1718         if (new_objp->class == CKO_SECRET_KEY) {
1719                 /*
1720                  * Since no ASN.1 encoding is done for secret keys, check for
1721                  * appropriateness and copy decrypted buffer to the key object.
1722                  */
1723 
1724                 /* Check keytype and mechtype don't conflict with valuelen */
1725                 rv = soft_unwrap_secret_len_check(new_objp->key_type,
1726                     pMechanism->mechanism, pTemplate, ulAttributeCount);
1727                 if (rv != CKR_OK)
1728                         goto cleanup_unwrap;
1729 
1730                 /*
1731                  * Allocate the secret key structure if not already there;
1732                  * it will exist for variable length keys since CKA_VALUE_LEN
1733                  * is specified and saved, but not for fixed length keys.
1734                  */
1735                 if (OBJ_SEC(new_objp) == NULL) {
1736                         if ((sck = calloc(1, sizeof (secret_key_obj_t))) ==
1737                             NULL) {
1738                                 rv = CKR_HOST_MEMORY;
1739                                 goto cleanup_unwrap;
1740                         }
1741                         OBJ_SEC(new_objp) = sck;
1742                 }
1743 
1744                 switch (new_objp->key_type) {
1745                 /* Fixed length secret keys don't have CKA_VALUE_LEN */
1746                 case CKK_DES:
1747                         OBJ_SEC_VALUE_LEN(new_objp) = DES_KEYSIZE;
1748                         break;
1749                 case CKK_DES2:
1750                         OBJ_SEC_VALUE_LEN(new_objp) = DES2_KEYSIZE;
1751                         break;
1752                 case CKK_DES3:
1753                         OBJ_SEC_VALUE_LEN(new_objp) = DES3_KEYSIZE;
1754                         break;
1755 
1756                 /*
1757                  * Variable length secret keys.  CKA_VALUE_LEN must be
1758                  * provided by the template when mech is *_ECB or *_CBC, and
1759                  * should already have been set during soft_gen_keyobject().
1760                  * Otherwise we don't need CKA_VALUE_LEN.
1761                  */
1762                 case CKK_GENERIC_SECRET:
1763                 case CKK_RC4:
1764                 case CKK_AES:
1765                 case CKK_BLOWFISH:
1766                         break;
1767                 default:
1768                         rv = CKR_WRAPPED_KEY_INVALID;
1769                         goto cleanup_unwrap;
1770                 };
1771 
1772                 if (OBJ_SEC_VALUE_LEN(new_objp) == 0) {
1773                         /* No CKA_VALUE_LEN set so set it now and save data */
1774                         OBJ_SEC_VALUE_LEN(new_objp) = plain_len;
1775                         OBJ_SEC_VALUE(new_objp) = plain_data;
1776                 } else if (OBJ_SEC_VALUE_LEN(new_objp) == plain_len) {
1777                         /* No need to truncate, just save the data */
1778                         OBJ_SEC_VALUE(new_objp) = plain_data;
1779                 } else if (OBJ_SEC_VALUE_LEN(new_objp) > plain_len) {
1780                         /* Length can't be bigger than what was decrypted */
1781                         rv = CKR_WRAPPED_KEY_LEN_RANGE;
1782                         goto cleanup_unwrap;
1783                 } else {        /* betw 0 and plain_len, hence padded */
1784                         /* Truncate the data before saving. */
1785                         OBJ_SEC_VALUE(new_objp) = realloc(plain_data,
1786                             OBJ_SEC_VALUE_LEN(new_objp));
1787                         if (OBJ_SEC_VALUE(new_objp) == NULL) {
1788                                 rv = CKR_HOST_MEMORY;
1789                                 goto cleanup_unwrap;
1790                         }
1791                 }
1792         } else {
1793                 /* BER-decode the object to be unwrapped. */
1794                 rv = soft_asn1_to_object(new_objp, plain_data, plain_len);
1795                 if (rv != CKR_OK)
1796                         goto cleanup_unwrap;
1797         }
1798 
1799         /* If it needs to be persistent, write it to the keystore */
1800         if (IS_TOKEN_OBJECT(new_objp)) {
1801                 persistent = B_TRUE;
1802                 rv = soft_put_object_to_keystore(new_objp);
1803                 if (rv != CKR_OK)
1804                         goto cleanup_unwrap;
1805         }
1806 
1807         if (new_objp->class != CKO_SECRET_KEY) {
1808                 /* Clear buffer before returning to memory pool. */
1809                 freezero(plain_data, plain_len);
1810         }
1811 
1812         *phKey = (CK_OBJECT_HANDLE)new_objp;
1813 
1814         return (CKR_OK);
1815 
1816 cleanup_unwrap:
1817         /* The decrypted private key buffer must be freed explicitly. */
1818         if ((new_objp->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1819                 /* Clear buffer before returning to memory pool. */
1820                 freezero(plain_data, plain_len);
1821         }
1822 
1823         /* sck and new_objp are indirectly free()d inside these functions */
1824         if (IS_TOKEN_OBJECT(new_objp))
1825                 soft_delete_token_object(new_objp, persistent, B_FALSE);
1826         else
1827                 soft_delete_object(session_p, new_objp, B_FALSE, B_FALSE);
1828 
1829         return (rv);
1830 }