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