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 (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 #include <crypt.h>
  26 #include <cryptoutil.h>
  27 #include <pwd.h>
  28 #include <pthread.h>
  29 #include <stdlib.h>
  30 #include <string.h>
  31 #include <strings.h>
  32 #include <sys/types.h>
  33 #include <sys/sysmacros.h>
  34 #include <security/cryptoki.h>
  35 #include "softGlobal.h"
  36 #include "softCrypt.h"
  37 #include "softSession.h"
  38 #include "softObject.h"
  39 #include "softKeys.h"
  40 #include "softKeystore.h"
  41 #include "softKeystoreUtil.h"
  42 #include "softMAC.h"
  43 #include "softOps.h"
  44 
  45 soft_session_t token_session;
  46 
  47 /*
  48  * soft_gen_hashed_pin()
  49  *
  50  * Arguments:
  51  *
  52  *      pPin:   pointer to caller provided Pin
  53  *      result: output argument which contains the address of the
  54  *              pointer to the hashed pin
  55  *      salt:   input argument (if non-NULL), or
  56  *              output argument (if NULL):
  57  *              address of pointer to the "salt" of the hashed pin
  58  *
  59  * Description:
  60  *
  61  *      Generate a hashed pin using system provided crypt(3C) function.
  62  *
  63  * Returns:
  64  *
  65  *      0: no error
  66  *      -1: some error occurred while generating the hashed pin
  67  *
  68  */
  69 int
  70 soft_gen_hashed_pin(CK_UTF8CHAR_PTR pPin, char **result, char **salt)
  71 {
  72 
  73         uid_t uid;
  74         struct passwd pwd, *pw;
  75         char pwdbuf[PWD_BUFFER_SIZE];
  76         boolean_t new_salt = B_FALSE;
  77 
  78         /*
  79          * We need to get the passwd entry of the application, which is required
  80          * by the crypt_gensalt() below.
  81          */
  82         uid = geteuid();
  83         if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
  84                 return (-1);
  85         }
  86 
  87         if (*salt == NULL) {
  88                 new_salt = B_TRUE;
  89                 /*
  90                  * crypt_gensalt() will allocate memory to store the new salt.
  91                  * on return.  Pass "$5" here to default to crypt_sha256 since
  92                  * SHA256 is a FIPS 140-2 certified algorithm and we shouldn't
  93                  * assume the system default is that strong.
  94                  */
  95                 if ((*salt = crypt_gensalt("$5", pw)) == NULL) {
  96                         return (-1);
  97                 }
  98         }
  99 
 100         if ((*result = crypt((char *)pPin, *salt)) == NULL) {
 101                 if (new_salt)
 102                         free(*salt);
 103                 return (-1);
 104         }
 105 
 106         return (0);
 107 }
 108 
 109 /*
 110  * Authenticate user's PIN for C_Login.
 111  */
 112 CK_RV
 113 soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
 114 {
 115 
 116         char    *user_cryptpin = NULL;
 117         char    *ks_cryptpin = NULL;
 118         char    *salt = NULL;
 119         uchar_t *tmp_pin = NULL;
 120         boolean_t pin_initialized = B_FALSE;
 121         CK_RV   rv = CKR_OK;
 122 
 123         /*
 124          * Check to see if keystore is initialized.
 125          */
 126         rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
 127             B_FALSE);
 128         if (rv != CKR_OK)
 129                 return (rv);
 130 
 131         /*
 132          * Authenticate user's PIN for C_Login.
 133          */
 134         if (pin_initialized) {
 135 
 136                 if (soft_keystore_get_pin_salt(&salt) < 0) {
 137                         rv = CKR_FUNCTION_FAILED;
 138                         goto cleanup;
 139                 }
 140 
 141                 /*
 142                  * Generate the hashed value based on the user's supplied pin.
 143                  */
 144                 tmp_pin = malloc(ulPinLen + 1);
 145                 if (tmp_pin == NULL) {
 146                         rv = CKR_HOST_MEMORY;
 147                         goto cleanup;
 148                 }
 149 
 150                 (void) memcpy(tmp_pin, pPin, ulPinLen);
 151                 tmp_pin[ulPinLen] = '\0';
 152 
 153                 if (soft_gen_hashed_pin(tmp_pin, &user_cryptpin, &salt) < 0) {
 154                         rv = CKR_FUNCTION_FAILED;
 155                         goto cleanup;
 156                 }
 157 
 158                 /*
 159                  * Compare hash value of the user supplied PIN with
 160                  * hash value of the keystore PIN.
 161                  */
 162                 if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
 163                         rv = CKR_PIN_INCORRECT;
 164                         goto cleanup;
 165                 }
 166 
 167                 /*
 168                  * Provide the user's PIN to low-level keystore so that
 169                  * it can use it to generate encryption key as needed for
 170                  * encryption/decryption of the private objects in
 171                  * keystore.
 172                  */
 173                 if (soft_keystore_authpin(tmp_pin) != 0) {
 174                         rv = CKR_FUNCTION_FAILED;
 175                 } else {
 176                         rv = CKR_OK;
 177                 }
 178                 goto cleanup;
 179         } else {
 180                 /*
 181                  * The PIN is not initialized in the keystore
 182                  * We will let it pass the authentication anyway but set the
 183                  * "userpin_change_needed" flag so that the application
 184                  * will get CKR_PIN_EXPIRED by other C_functions such as
 185                  * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
 186                  */
 187                 soft_slot.userpin_change_needed = 1;
 188                 rv = CKR_OK;
 189         }
 190 
 191 cleanup:
 192         if (salt)
 193                 free(salt);
 194         if (tmp_pin)
 195                 free(tmp_pin);
 196         if (ks_cryptpin)
 197                 free(ks_cryptpin);
 198 
 199         return (rv);
 200 }
 201 
 202 /*
 203  * The second level C_SetPIN function.
 204  */
 205 CK_RV
 206 soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
 207     CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
 208 {
 209 
 210         char    *user_cryptpin = NULL;
 211         char    *ks_cryptpin = NULL;
 212         char    *salt = NULL;
 213         boolean_t pin_initialized = B_FALSE;
 214         uchar_t *tmp_old_pin = NULL, *tmp_new_pin = NULL;
 215         CK_RV   rv = CKR_OK;
 216 
 217         /*
 218          * Check to see if keystore is initialized.
 219          */
 220         rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
 221             B_FALSE);
 222         if (rv != CKR_OK)
 223                 return (rv);
 224 
 225         /*
 226          * Authenticate user's PIN for C_SetPIN.
 227          */
 228         if (pin_initialized) {
 229                 /*
 230                  * Generate the hashed value based on the user supplied PIN.
 231                  */
 232                 if (soft_keystore_get_pin_salt(&salt) < 0) {
 233                         rv = CKR_FUNCTION_FAILED;
 234                         goto cleanup;
 235                 }
 236 
 237                 tmp_old_pin = malloc(ulOldPinLen + 1);
 238                 if (tmp_old_pin == NULL) {
 239                         rv = CKR_HOST_MEMORY;
 240                         goto cleanup;
 241                 }
 242                 (void) memcpy(tmp_old_pin, pOldPin, ulOldPinLen);
 243                 tmp_old_pin[ulOldPinLen] = '\0';
 244 
 245                 if (soft_gen_hashed_pin(tmp_old_pin, &user_cryptpin,
 246                     &salt) < 0) {
 247                         rv = CKR_FUNCTION_FAILED;
 248                         goto cleanup;
 249                 }
 250 
 251                 /*
 252                  * Compare hashed value of the user supplied PIN with the
 253                  * hashed value of the keystore PIN.
 254                  */
 255                 if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
 256                         rv = CKR_PIN_INCORRECT;
 257                         goto cleanup;
 258                 }
 259         } else {
 260                 /*
 261                  * This is the first time to setpin, the oldpin must be
 262                  * "changeme".
 263                  */
 264                 if (strncmp("changeme", (const char *)pOldPin,
 265                     ulOldPinLen) != 0) {
 266                         rv = CKR_PIN_INCORRECT;
 267                         goto cleanup;
 268                 }
 269         }
 270 
 271         tmp_new_pin = malloc(ulNewPinLen + 1);
 272         if (tmp_new_pin == NULL) {
 273                 rv = CKR_HOST_MEMORY;
 274                 goto cleanup;
 275         }
 276         (void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
 277         tmp_new_pin[ulNewPinLen] = '\0';
 278 
 279         /*
 280          * Set the new pin after the old pin is authenticated.
 281          */
 282         if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
 283                 rv = CKR_FUNCTION_FAILED;
 284                 goto cleanup;
 285         } else {
 286                 (void) pthread_mutex_lock(&soft_giant_mutex);
 287                 soft_slot.userpin_change_needed = 0;
 288                 (void) pthread_mutex_unlock(&soft_giant_mutex);
 289                 rv = CKR_OK;
 290         }
 291 
 292 cleanup:
 293         if (salt)
 294                 free(salt);
 295         if (ks_cryptpin)
 296                 free(ks_cryptpin);
 297         if (tmp_old_pin)
 298                 free(tmp_old_pin);
 299         if (tmp_new_pin)
 300                 free(tmp_new_pin);
 301 
 302         return (rv);
 303 }
 304 
 305 /*
 306  * soft_keystore_pack_obj()
 307  *
 308  * Arguments:
 309  *
 310  *      obj:    pointer to the soft_object_t of the token object to
 311  *              be packed
 312  *      ks_buf: output argument which contains the address of the
 313  *              pointer to the buf of the packed token object
 314  *              soft_keystore_pack_obj() will allocate memory for the buf,
 315  *              it is caller's responsibility to free it.
 316  *      len:    output argument which contains the address of the
 317  *              buffer length of the packed token object
 318  *
 319  * Description:
 320  *
 321  *      Pack the in-core token object into the keystore format.
 322  *
 323  * Returns:
 324  *
 325  *      CKR_OK: no error
 326  *      Other: some error occurred while packing the object
 327  *
 328  */
 329 CK_RV
 330 soft_keystore_pack_obj(soft_object_t *obj, uchar_t **ks_buf, size_t *len)
 331 {
 332         ks_obj_hdr_t hdr;
 333         ks_attr_hdr_t attr_hdr;
 334         CK_ATTRIBUTE_INFO_PTR extra_attr;
 335         int num_attrs = 0;
 336         ulong_t len_attrs = 0;
 337         size_t ks_len;
 338         uchar_t *buf, *buf1;
 339         CK_RV rv;
 340         int i;
 341 
 342         (void) memset(&hdr, 0, sizeof (ks_obj_hdr_t));
 343 
 344         /*
 345          * The first part of the packed format contains
 346          * the ks_obj_hdr_t struct.
 347          */
 348         hdr.class = SWAP64((uint64_t)obj->class);
 349         hdr.key_type = SWAP64((uint64_t)obj->key_type);
 350         hdr.cert_type = SWAP64((uint64_t)obj->cert_type);
 351         hdr.bool_attr_mask = SWAP64(obj->bool_attr_mask);
 352         hdr.mechanism = SWAP64((uint64_t)obj->mechanism);
 353         hdr.object_type = obj->object_type;
 354 
 355         /*
 356          * The second part of the packed format contains
 357          * the attributes from the extra atrribute list.
 358          */
 359         extra_attr = obj->extra_attrlistp;
 360 
 361         while (extra_attr) {
 362                 num_attrs++;
 363                 len_attrs += ROUNDUP(extra_attr->attr.ulValueLen, 8);
 364                 extra_attr = extra_attr->next;
 365         }
 366         hdr.num_attrs = SWAP32(num_attrs);
 367         ks_len = soft_pack_object_size(obj);
 368         ks_len += sizeof (ks_obj_hdr_t) + len_attrs +
 369             2 * num_attrs * sizeof (uint64_t);
 370         buf = calloc(1, ks_len);
 371         if (buf == NULL) {
 372                 return (CKR_HOST_MEMORY);
 373         }
 374         (void) memcpy(buf, &hdr, sizeof (ks_obj_hdr_t));
 375         buf1 = buf + sizeof (ks_obj_hdr_t);
 376         extra_attr = obj->extra_attrlistp;
 377         for (i = 0; i < num_attrs; i++) {
 378                 attr_hdr.type = SWAP64((uint64_t)extra_attr->attr.type);
 379                 attr_hdr.ulValueLen =
 380                     SWAP64((uint64_t)extra_attr->attr.ulValueLen);
 381                 (void) memcpy(buf1, &attr_hdr, sizeof (ks_attr_hdr_t));
 382                 buf1 = buf1 + sizeof (ks_attr_hdr_t);
 383                 (void) memcpy(buf1, extra_attr->attr.pValue,
 384                     extra_attr->attr.ulValueLen);
 385                 buf1 = buf1 + ROUNDUP(extra_attr->attr.ulValueLen, 8);
 386                 extra_attr = extra_attr->next;
 387         }
 388 
 389         /*
 390          * The third part of the packed format contains
 391          * the key itself.
 392          */
 393         rv = soft_pack_object(obj, buf1);
 394         *len = ks_len;
 395         *ks_buf = buf;
 396 
 397         return (rv);
 398 
 399 }
 400 
 401 /*
 402  * soft_keystore_unpack_obj()
 403  *
 404  * Arguments:
 405  *
 406  *      obj:    pointer to the soft_object_t to store the unpacked
 407  *              token object
 408  *      ks_obj: input argument which contains the pointer to the
 409  *              ks_obj_t struct of packed token object to be unpacked
 410  *
 411  * Description:
 412  *
 413  *      Unpack the token object in keystore format to in-core soft_object_t.
 414  *
 415  * Returns:
 416  *
 417  *      CKR_OK: no error
 418  *      Other: some error occurred while unpacking the object
 419  *
 420  */
 421 CK_RV
 422 soft_keystore_unpack_obj(soft_object_t *obj, ks_obj_t *ks_obj)
 423 {
 424 
 425         CK_RV rv;
 426         ks_obj_hdr_t *hdr;
 427         ks_attr_hdr_t *attr_hdr;
 428         CK_ATTRIBUTE template;
 429         int i;
 430         uchar_t *buf;
 431 
 432         /*
 433          * Unpack the common area.
 434          */
 435         (void) strcpy((char *)obj->ks_handle.name,
 436             (char *)ks_obj->ks_handle.name);
 437         obj->ks_handle.public = ks_obj->ks_handle.public;
 438         /* LINTED: pointer alignment */
 439         hdr = (ks_obj_hdr_t *)ks_obj->buf;
 440         obj->version = ks_obj->obj_version;
 441         obj->class = (CK_OBJECT_CLASS)(SWAP64(hdr->class));
 442         obj->key_type = (CK_KEY_TYPE)(SWAP64(hdr->key_type));
 443         obj->cert_type = (CK_CERTIFICATE_TYPE)(SWAP64(hdr->cert_type));
 444         obj->bool_attr_mask = SWAP64(hdr->bool_attr_mask);
 445         obj->mechanism = (CK_MECHANISM_TYPE)(SWAP64(hdr->mechanism));
 446         obj->object_type = hdr->object_type;
 447 
 448         /*
 449          * Initialize other stuffs which were not from keystore.
 450          */
 451         (void) pthread_mutex_init(&obj->object_mutex, NULL);
 452         obj->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
 453         obj->session_handle = (CK_SESSION_HANDLE)NULL;
 454 
 455         buf = ks_obj->buf + sizeof (ks_obj_hdr_t);
 456 
 457         /*
 458          * Unpack extra attribute list.
 459          */
 460         for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
 461                 /* LINTED: pointer alignment */
 462                 attr_hdr = (ks_attr_hdr_t *)buf;
 463                 (void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
 464                 template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
 465                 template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
 466                 buf = buf + sizeof (ks_attr_hdr_t);
 467                 /* Allocate storage for the value of the attribute. */
 468                 if (template.ulValueLen > 0) {
 469                         template.pValue = malloc(template.ulValueLen);
 470                         if (template.pValue == NULL) {
 471                                 return (CKR_HOST_MEMORY);
 472                         }
 473                         (void) memcpy(template.pValue, buf,
 474                             template.ulValueLen);
 475                 }
 476 
 477                 rv = soft_add_extra_attr(&template, obj);
 478                 if (template.pValue) {
 479                         free(template.pValue);
 480                 }
 481 
 482                 if (rv != CKR_OK) {
 483                         return (rv);
 484                 }
 485 
 486                 buf = buf + ROUNDUP(template.ulValueLen, 8);
 487         }
 488 
 489         /*
 490          * Unpack the key itself.
 491          */
 492         rv = soft_unpack_object(obj, buf);
 493         return (rv);
 494 
 495 }
 496 
 497 
 498 /*
 499  * soft_unpack_obj_attribute()
 500  *
 501  * Arguments:
 502  *
 503  *      buf:    contains the packed data (attributes) from keystore
 504  *      key_dest: the key attribute will be unpacked and save in key_dest
 505  *      cert_dest: the certificate attribute will be unpacked an
 506  *                 in cert_dest
 507  *      offset: length of the current attribute occupies.
 508  *              The caller should use this returned "offset" to
 509  *              advance the buffer pointer to next attribute.
 510  *      cert:   TRUE for certificate (use cert_dest)
 511  *              FALSE for key (use key_dest)
 512  *
 513  * Description:
 514  *
 515  *      Unpack the attribute from keystore format to the big integer format.
 516  *
 517  * Returns:
 518  *
 519  *      CKR_OK: no error
 520  *      Other: some error occurred while unpacking the object attribute
 521  *
 522  */
 523 CK_RV
 524 soft_unpack_obj_attribute(uchar_t *buf, biginteger_t *key_dest,
 525     cert_attr_t **cert_dest, ulong_t *offset, boolean_t cert)
 526 {
 527 
 528         CK_RV rv;
 529         CK_ATTRIBUTE template;
 530 
 531         /* LINTED: pointer alignment */
 532         template.ulValueLen = SWAP64(*(uint64_t *)buf);
 533         buf = buf + sizeof (uint64_t);
 534         template.pValue = malloc(template.ulValueLen);
 535         if (template.pValue == NULL) {
 536                 return (CKR_HOST_MEMORY);
 537         }
 538 
 539         (void) memcpy(template.pValue, buf, template.ulValueLen);
 540         if (cert) {
 541                 rv = get_cert_attr_from_template(cert_dest, &template);
 542         } else {
 543                 rv = get_bigint_attr_from_template(key_dest, &template);
 544         }
 545 
 546         free(template.pValue);
 547         if (rv != CKR_OK) {
 548                 return (rv);
 549         }
 550 
 551         *offset = sizeof (uint64_t) + template.ulValueLen;
 552         return (CKR_OK);
 553 }
 554 
 555 
 556 /*
 557  * Calculate the total buffer length required to store the
 558  * object key (the third part) in a keystore format.
 559  */
 560 ulong_t
 561 soft_pack_object_size(soft_object_t *objp)
 562 {
 563 
 564         CK_OBJECT_CLASS class = objp->class;
 565         CK_KEY_TYPE     keytype = objp->key_type;
 566         CK_CERTIFICATE_TYPE certtype = objp->cert_type;
 567 
 568         switch (class) {
 569         case CKO_PUBLIC_KEY:
 570                 switch (keytype) {
 571                 case CKK_RSA:
 572                         /*
 573                          * modulus_bits + modulus_len + modulus +
 574                          * pubexpo_len + pubexpo
 575                          */
 576                         return (ROUNDUP(((biginteger_t *)
 577                             OBJ_PUB_RSA_MOD(objp))->big_value_len, 8) +
 578                             ROUNDUP(((biginteger_t *)
 579                             OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len, 8) +
 580                             3 * sizeof (uint64_t));
 581 
 582                 case CKK_DSA:
 583                         /*
 584                          * prime_len + prime + subprime_len + subprime +
 585                          * base_len + base + value_len + value
 586                          */
 587                         return (ROUNDUP(((biginteger_t *)
 588                             OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8) +
 589                             ROUNDUP(((biginteger_t *)
 590                             OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8) +
 591                             ROUNDUP(((biginteger_t *)
 592                             OBJ_PUB_DSA_BASE(objp))->big_value_len, 8) +
 593                             ROUNDUP(((biginteger_t *)
 594                             OBJ_PUB_DSA_VALUE(objp))->big_value_len, 8) +
 595                             4 * sizeof (uint64_t));
 596                 case CKK_EC:
 597                         /*
 598                          * ec_point_len + ec_point
 599                          */
 600                         return (ROUNDUP(((biginteger_t *)
 601                             OBJ_PUB_EC_POINT(objp))->big_value_len, 8) +
 602                             sizeof (uint64_t));
 603                 case CKK_DH:
 604                         /*
 605                          * prime_len + prime + base_len + base +
 606                          * value_len + value
 607                          */
 608                         return (ROUNDUP(((biginteger_t *)
 609                             OBJ_PUB_DH_PRIME(objp))->big_value_len, 8) +
 610                             ROUNDUP(((biginteger_t *)
 611                             OBJ_PUB_DH_BASE(objp))->big_value_len, 8) +
 612                             ROUNDUP(((biginteger_t *)
 613                             OBJ_PUB_DH_VALUE(objp))->big_value_len, 8) +
 614                             3 * sizeof (uint64_t));
 615 
 616                 case CKK_X9_42_DH:
 617                         /*
 618                          * prime_len + prime + base_len + base +
 619                          * subprime_len + subprime + value_len + value
 620                          */
 621                         return (ROUNDUP(((biginteger_t *)
 622                             OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8) +
 623                             ROUNDUP(((biginteger_t *)
 624                             OBJ_PUB_DH942_BASE(objp))->big_value_len, 8) +
 625                             ROUNDUP(((biginteger_t *)
 626                             OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8) +
 627                             ROUNDUP(((biginteger_t *)
 628                             OBJ_PUB_DH942_VALUE(objp))->big_value_len, 8) +
 629                             4 * sizeof (uint64_t));
 630                 } /* keytype */
 631 
 632                 break;
 633 
 634         case CKO_PRIVATE_KEY:
 635                 switch (keytype) {
 636                 case CKK_RSA:
 637                         /*
 638                          * modulus_len + modulus + pubexpo_len + pubexpo +
 639                          * priexpo_len + priexpo + prime1_len + prime1 +
 640                          * prime2_len + prime2 + expo1_len + expo1 +
 641                          * expo2_len + expo2 + coef_len + coef
 642                          */
 643                         return (ROUNDUP(((biginteger_t *)
 644                             OBJ_PRI_RSA_MOD(objp))->big_value_len, 8) +
 645                             ROUNDUP(((biginteger_t *)
 646                             OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8) +
 647                             ROUNDUP(((biginteger_t *)
 648                             OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8) +
 649                             ROUNDUP(((biginteger_t *)
 650                             OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8) +
 651                             ROUNDUP(((biginteger_t *)
 652                             OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8) +
 653                             ROUNDUP(((biginteger_t *)
 654                             OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8) +
 655                             ROUNDUP(((biginteger_t *)
 656                             OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8) +
 657                             ROUNDUP(((biginteger_t *)
 658                             OBJ_PRI_RSA_COEF(objp))->big_value_len, 8) +
 659                             8 * sizeof (uint64_t));
 660 
 661                 case CKK_DSA:
 662                         /*
 663                          * prime_len + prime + subprime_len + subprime +
 664                          * base_len + base + value_len + value
 665                          */
 666                         return (ROUNDUP(((biginteger_t *)
 667                             OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8) +
 668                             ROUNDUP(((biginteger_t *)
 669                             OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8) +
 670                             ROUNDUP(((biginteger_t *)
 671                             OBJ_PRI_DSA_BASE(objp))->big_value_len, 8) +
 672                             ROUNDUP(((biginteger_t *)
 673                             OBJ_PRI_DSA_VALUE(objp))->big_value_len, 8) +
 674                             4 * sizeof (uint64_t));
 675 
 676                 case CKK_DH:
 677                         /*
 678                          * value_bits + prime_len + prime + base_len + base +
 679                          * value_len + value
 680                          */
 681                         return (ROUNDUP(((biginteger_t *)
 682                             OBJ_PRI_DH_PRIME(objp))->big_value_len, 8) +
 683                             ROUNDUP(((biginteger_t *)
 684                             OBJ_PRI_DH_BASE(objp))->big_value_len, 8) +
 685                             ROUNDUP(((biginteger_t *)
 686                             OBJ_PRI_DH_VALUE(objp))->big_value_len, 8) +
 687                             4 * sizeof (uint64_t));
 688 
 689                 case CKK_EC:
 690                         /*
 691                          * value_len + value
 692                          */
 693                         return (ROUNDUP(((biginteger_t *)
 694                             OBJ_PRI_EC_VALUE(objp))->big_value_len, 8) +
 695                             sizeof (uint64_t));
 696 
 697                 case CKK_X9_42_DH:
 698                         /*
 699                          * prime_len + prime + base_len + base +
 700                          * subprime_len + subprime + value_len + value
 701                          */
 702                         return (ROUNDUP(((biginteger_t *)
 703                             OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8) +
 704                             ROUNDUP(((biginteger_t *)
 705                             OBJ_PRI_DH942_BASE(objp))->big_value_len, 8) +
 706                             ROUNDUP(((biginteger_t *)
 707                             OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8) +
 708                             ROUNDUP(((biginteger_t *)
 709                             OBJ_PRI_DH942_VALUE(objp))->big_value_len, 8) +
 710                             4 * sizeof (uint64_t));
 711 
 712                 } /* keytype */
 713 
 714                 break;
 715 
 716         case CKO_SECRET_KEY:
 717                 /*
 718                  * value_len + value
 719                  */
 720                 return (ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8) +
 721                     sizeof (uint64_t));
 722 
 723         case CKO_CERTIFICATE:
 724                 switch (certtype) {
 725                 case CKC_X_509:
 726                         /*
 727                          * subject_len + subject + value_len + value
 728                          */
 729                         return (ROUNDUP(((cert_attr_t *)
 730                             X509_CERT_SUBJECT(objp))->length, 8) +
 731                             ROUNDUP(((cert_attr_t *)
 732                             X509_CERT_VALUE(objp))->length, 8) +
 733                             2 * sizeof (uint64_t));
 734 
 735                 case CKC_X_509_ATTR_CERT:
 736                         /*
 737                          * owner_len + owner + value_len + value
 738                          */
 739                         return (ROUNDUP(((cert_attr_t *)
 740                             X509_ATTR_CERT_OWNER(objp))->length, 8) +
 741                             ROUNDUP(((cert_attr_t *)
 742                             X509_ATTR_CERT_VALUE(objp))->length, 8) +
 743                             2 * sizeof (uint64_t));
 744                 }
 745                 return (0);
 746 
 747         case CKO_DOMAIN_PARAMETERS:
 748 
 749                 return (0);
 750         }
 751         return (0);
 752 }
 753 
 754 /*
 755  * Pack the object key (the third part) from the soft_object_t
 756  * into the keystore format.
 757  */
 758 CK_RV
 759 soft_pack_object(soft_object_t *objp, uchar_t *buf)
 760 {
 761 
 762         CK_OBJECT_CLASS class = objp->class;
 763         CK_KEY_TYPE     keytype = objp->key_type;
 764         CK_CERTIFICATE_TYPE certtype = objp->cert_type;
 765         uint64_t tmp_val;
 766 
 767         switch (class) {
 768         case CKO_PUBLIC_KEY:
 769                 switch (keytype) {
 770                 case CKK_RSA:
 771                         /* modulus_bits */
 772                         tmp_val = SWAP64((uint64_t)OBJ_PUB_RSA_MOD_BITS(objp));
 773                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 774                         buf = buf + sizeof (uint64_t);
 775 
 776                         /* modulus_len + modulus */
 777                         tmp_val = SWAP64((uint64_t)(((biginteger_t *)
 778                             OBJ_PUB_RSA_MOD(objp))->big_value_len));
 779                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 780                         buf = buf + sizeof (uint64_t);
 781 
 782                         (void) memcpy(buf, (char *)(((biginteger_t *)
 783                             OBJ_PUB_RSA_MOD(objp))->big_value),
 784                             ((biginteger_t *)
 785                             OBJ_PUB_RSA_MOD(objp))->big_value_len);
 786                         buf = buf + ROUNDUP(((biginteger_t *)
 787                             OBJ_PUB_RSA_MOD(objp))->big_value_len, 8);
 788 
 789                         /* pubexpo_len + pubexpo */
 790                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 791                             OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
 792                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 793                         buf = buf + sizeof (uint64_t);
 794 
 795                         (void) memcpy(buf, (char *)(((biginteger_t *)
 796                             OBJ_PUB_RSA_PUBEXPO(objp))->big_value),
 797                             ((biginteger_t *)
 798                             OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
 799                         break;
 800 
 801                 case CKK_DSA:
 802                         /* prime_len + prime */
 803                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 804                             OBJ_PUB_DSA_PRIME(objp))->big_value_len);
 805                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 806                         buf = buf + sizeof (uint64_t);
 807 
 808                         (void) memcpy(buf, (char *)((biginteger_t *)
 809                             OBJ_PUB_DSA_PRIME(objp))->big_value,
 810                             ((biginteger_t *)
 811                             OBJ_PUB_DSA_PRIME(objp))->big_value_len);
 812                         buf = buf + ROUNDUP(((biginteger_t *)
 813                             OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8);
 814 
 815                         /* subprime_len + subprime */
 816                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 817                             OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
 818                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 819                         buf = buf + sizeof (uint64_t);
 820 
 821                         (void) memcpy(buf, (char *)((biginteger_t *)
 822                             OBJ_PUB_DSA_SUBPRIME(objp))->big_value,
 823                             ((biginteger_t *)
 824                             OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
 825                         buf = buf + ROUNDUP(((biginteger_t *)
 826                             OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8);
 827 
 828                         /* base_len + base */
 829                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 830                             OBJ_PUB_DSA_BASE(objp))->big_value_len);
 831                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 832                         buf = buf + sizeof (uint64_t);
 833 
 834                         (void) memcpy(buf, (char *)((biginteger_t *)
 835                             OBJ_PUB_DSA_BASE(objp))->big_value,
 836                             ((biginteger_t *)
 837                             OBJ_PUB_DSA_BASE(objp))->big_value_len);
 838                         buf = buf + ROUNDUP(((biginteger_t *)
 839                             OBJ_PUB_DSA_BASE(objp))->big_value_len, 8);
 840 
 841                         /* value_len + value */
 842                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 843                             OBJ_PUB_DSA_VALUE(objp))->big_value_len);
 844                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 845                         buf = buf + sizeof (uint64_t);
 846 
 847                         (void) memcpy(buf, (char *)((biginteger_t *)
 848                             OBJ_PUB_DSA_VALUE(objp))->big_value,
 849                             ((biginteger_t *)
 850                             OBJ_PUB_DSA_VALUE(objp))->big_value_len);
 851 
 852                         break;
 853                 case CKK_EC:
 854                         /* point_len + point */
 855                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 856                             OBJ_PUB_EC_POINT(objp))->big_value_len);
 857                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 858                         buf = buf + sizeof (uint64_t);
 859 
 860                         (void) memcpy(buf, (char *)((biginteger_t *)
 861                             OBJ_PUB_EC_POINT(objp))->big_value,
 862                             ((biginteger_t *)
 863                             OBJ_PUB_EC_POINT(objp))->big_value_len);
 864                         break;
 865 
 866                 case CKK_DH:
 867                         /* prime_len + prime */
 868                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 869                             OBJ_PUB_DH_PRIME(objp))->big_value_len);
 870                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 871                         buf = buf + sizeof (uint64_t);
 872 
 873                         (void) memcpy(buf, (char *)((biginteger_t *)
 874                             OBJ_PUB_DH_PRIME(objp))->big_value,
 875                             ((biginteger_t *)
 876                             OBJ_PUB_DH_PRIME(objp))->big_value_len);
 877                         buf = buf + ROUNDUP(((biginteger_t *)
 878                             OBJ_PUB_DH_PRIME(objp))->big_value_len, 8);
 879 
 880                         /* base_len + base */
 881                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 882                             OBJ_PUB_DH_BASE(objp))->big_value_len);
 883                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 884                         buf = buf + sizeof (uint64_t);
 885 
 886                         (void) memcpy(buf, (char *)((biginteger_t *)
 887                             OBJ_PUB_DH_BASE(objp))->big_value,
 888                             ((biginteger_t *)
 889                             OBJ_PUB_DH_BASE(objp))->big_value_len);
 890                         buf = buf + ROUNDUP(((biginteger_t *)
 891                             OBJ_PUB_DH_BASE(objp))->big_value_len, 8);
 892 
 893                         /* value_len + value */
 894                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 895                             OBJ_PUB_DH_VALUE(objp))->big_value_len);
 896                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 897                         buf = buf + sizeof (uint64_t);
 898 
 899                         (void) memcpy(buf, (char *)((biginteger_t *)
 900                             OBJ_PUB_DH_VALUE(objp))->big_value,
 901                             ((biginteger_t *)
 902                             OBJ_PUB_DH_VALUE(objp))->big_value_len);
 903 
 904                         break;
 905 
 906                 case CKK_X9_42_DH:
 907                         /* prime_len +  prime */
 908                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 909                             OBJ_PUB_DH942_PRIME(objp))->big_value_len);
 910                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 911                         buf = buf + sizeof (uint64_t);
 912 
 913                         (void) memcpy(buf, (char *)((biginteger_t *)
 914                             OBJ_PUB_DH942_PRIME(objp))->big_value,
 915                             ((biginteger_t *)
 916                             OBJ_PUB_DH942_PRIME(objp))->big_value_len);
 917                         buf = buf + ROUNDUP(((biginteger_t *)
 918                             OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8);
 919 
 920                         /* base_len + base */
 921                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 922                             OBJ_PUB_DH942_BASE(objp))->big_value_len);
 923                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 924                         buf = buf + sizeof (uint64_t);
 925 
 926                         (void) memcpy(buf, (char *)((biginteger_t *)
 927                             OBJ_PUB_DH942_BASE(objp))->big_value,
 928                             ((biginteger_t *)
 929                             OBJ_PUB_DH942_BASE(objp))->big_value_len);
 930                         buf = buf + ROUNDUP(((biginteger_t *)
 931                             OBJ_PUB_DH942_BASE(objp))->big_value_len, 8);
 932 
 933                         /* subprime_len + subprime */
 934                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 935                             OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
 936                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 937                         buf = buf + sizeof (uint64_t);
 938 
 939                         (void) memcpy(buf, (char *)((biginteger_t *)
 940                             OBJ_PUB_DH942_SUBPRIME(objp))->big_value,
 941                             ((biginteger_t *)
 942                             OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
 943                         buf = buf + ROUNDUP(((biginteger_t *)
 944                             OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8);
 945 
 946                         /* value_len + value */
 947                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 948                             OBJ_PUB_DH942_VALUE(objp))->big_value_len);
 949                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 950                         buf = buf + sizeof (uint64_t);
 951 
 952                         (void) memcpy(buf, (char *)((biginteger_t *)
 953                             OBJ_PUB_DH942_VALUE(objp))->big_value,
 954                             ((biginteger_t *)
 955                             OBJ_PUB_DH942_VALUE(objp))->big_value_len);
 956 
 957                         break;
 958                 } /* keytype */
 959 
 960                 break;
 961 
 962         case CKO_PRIVATE_KEY:
 963                 switch (keytype) {
 964                 case CKK_RSA:
 965                         /* modulus_len + modulus */
 966                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 967                             OBJ_PRI_RSA_MOD(objp))->big_value_len);
 968                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 969                         buf = buf + sizeof (uint64_t);
 970 
 971                         (void) memcpy(buf, (char *)((biginteger_t *)
 972                             OBJ_PRI_RSA_MOD(objp))->big_value,
 973                             ((biginteger_t *)
 974                             OBJ_PRI_RSA_MOD(objp))->big_value_len);
 975                         buf = buf + ROUNDUP(((biginteger_t *)
 976                             OBJ_PRI_RSA_MOD(objp))->big_value_len, 8);
 977 
 978                         /* pubexpo_len + pubexpo */
 979                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 980                             OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
 981                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 982                         buf = buf + sizeof (uint64_t);
 983 
 984                         (void) memcpy(buf, (char *)((biginteger_t *)
 985                             OBJ_PRI_RSA_PUBEXPO(objp))->big_value,
 986                             ((biginteger_t *)
 987                             OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
 988                         buf = buf + ROUNDUP(((biginteger_t *)
 989                             OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8);
 990 
 991                         /* priexpo_len + priexpo */
 992                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
 993                             OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
 994                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
 995                         buf = buf + sizeof (uint64_t);
 996 
 997                         (void) memcpy(buf, (char *)((biginteger_t *)
 998                             OBJ_PRI_RSA_PRIEXPO(objp))->big_value,
 999                             ((biginteger_t *)
1000                             OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
1001                         buf = buf + ROUNDUP(((biginteger_t *)
1002                             OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8);
1003 
1004                         /* prime1_len + prime1 */
1005                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1006                             OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
1007                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1008                         buf = buf + sizeof (uint64_t);
1009 
1010                         (void) memcpy(buf, (char *)((biginteger_t *)
1011                             OBJ_PRI_RSA_PRIME1(objp))->big_value,
1012                             ((biginteger_t *)
1013                             OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
1014                         buf = buf + ROUNDUP(((biginteger_t *)
1015                             OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8);
1016 
1017                         /* prime2_len + prime2 */
1018                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1019                             OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
1020                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1021                         buf = buf + sizeof (uint64_t);
1022 
1023                         (void) memcpy(buf, (char *)((biginteger_t *)
1024                             OBJ_PRI_RSA_PRIME2(objp))->big_value,
1025                             ((biginteger_t *)
1026                             OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
1027                         buf = buf + ROUNDUP(((biginteger_t *)
1028                             OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8);
1029 
1030                         /* expo1_len + expo1 */
1031                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1032                             OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
1033                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1034                         buf = buf + sizeof (uint64_t);
1035 
1036                         (void) memcpy(buf, (char *)((biginteger_t *)
1037                             OBJ_PRI_RSA_EXPO1(objp))->big_value,
1038                             ((biginteger_t *)
1039                             OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
1040                         buf = buf + ROUNDUP(((biginteger_t *)
1041                             OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8);
1042 
1043                         /* expo2_len + expo2 */
1044                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1045                             OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
1046                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1047                         buf = buf + sizeof (uint64_t);
1048 
1049                         (void) memcpy(buf, (char *)((biginteger_t *)
1050                             OBJ_PRI_RSA_EXPO2(objp))->big_value,
1051                             ((biginteger_t *)
1052                             OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
1053                         buf = buf + ROUNDUP(((biginteger_t *)
1054                             OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8);
1055 
1056                         /* coef_len + coef */
1057                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1058                             OBJ_PRI_RSA_COEF(objp))->big_value_len);
1059                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1060                         buf = buf + sizeof (uint64_t);
1061 
1062                         (void) memcpy(buf, (char *)((biginteger_t *)
1063                             OBJ_PRI_RSA_COEF(objp))->big_value,
1064                             ((biginteger_t *)
1065                             OBJ_PRI_RSA_COEF(objp))->big_value_len);
1066                         buf = buf + ROUNDUP(((biginteger_t *)
1067                             OBJ_PRI_RSA_COEF(objp))->big_value_len, 8);
1068 
1069                         break;
1070 
1071                 case CKK_DSA:
1072                         /* prime_len + prime */
1073                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1074                             OBJ_PRI_DSA_PRIME(objp))->big_value_len);
1075                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1076                         buf = buf + sizeof (uint64_t);
1077 
1078                         (void) memcpy(buf, (char *)((biginteger_t *)
1079                             OBJ_PRI_DSA_PRIME(objp))->big_value,
1080                             ((biginteger_t *)
1081                             OBJ_PRI_DSA_PRIME(objp))->big_value_len);
1082                         buf = buf + ROUNDUP(((biginteger_t *)
1083                             OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8);
1084 
1085                         /* subprime_len + subprime */
1086                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1087                             OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
1088                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1089                         buf = buf + sizeof (uint64_t);
1090 
1091                         (void) memcpy(buf, (char *)((biginteger_t *)
1092                             OBJ_PRI_DSA_SUBPRIME(objp))->big_value,
1093                             ((biginteger_t *)
1094                             OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
1095                         buf = buf + ROUNDUP(((biginteger_t *)
1096                             OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8);
1097 
1098                         /* base_len + base */
1099                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1100                             OBJ_PRI_DSA_BASE(objp))->big_value_len);
1101                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1102                         buf = buf + sizeof (uint64_t);
1103 
1104                         (void) memcpy(buf, (char *)((biginteger_t *)
1105                             OBJ_PRI_DSA_BASE(objp))->big_value,
1106                             ((biginteger_t *)
1107                             OBJ_PRI_DSA_BASE(objp))->big_value_len);
1108                         buf = buf + ROUNDUP(((biginteger_t *)
1109                             OBJ_PRI_DSA_BASE(objp))->big_value_len, 8);
1110 
1111                         /* value_len + value */
1112                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1113                             OBJ_PRI_DSA_VALUE(objp))->big_value_len);
1114                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1115                         buf = buf + sizeof (uint64_t);
1116 
1117                         (void) memcpy(buf, (char *)((biginteger_t *)
1118                             OBJ_PRI_DSA_VALUE(objp))->big_value,
1119                             ((biginteger_t *)
1120                             OBJ_PRI_DSA_VALUE(objp))->big_value_len);
1121 
1122                         break;
1123                 case CKK_EC:
1124                         /* value_len + value */
1125                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1126                             OBJ_PRI_EC_VALUE(objp))->big_value_len);
1127                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1128                         buf = buf + sizeof (uint64_t);
1129 
1130                         (void) memcpy(buf, (char *)((biginteger_t *)
1131                             OBJ_PRI_EC_VALUE(objp))->big_value,
1132                             ((biginteger_t *)
1133                             OBJ_PRI_EC_VALUE(objp))->big_value_len);
1134                         break;
1135 
1136                 case CKK_DH:
1137                         /* value_bits */
1138                         tmp_val = SWAP64((uint64_t)OBJ_PRI_DH_VAL_BITS(objp));
1139                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1140                         buf = buf + sizeof (uint64_t);
1141 
1142                         /* prime_len + prime */
1143                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1144                             OBJ_PRI_DH_PRIME(objp))->big_value_len);
1145                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1146                         buf = buf + sizeof (uint64_t);
1147 
1148                         (void) memcpy(buf, (char *)((biginteger_t *)
1149                             OBJ_PRI_DH_PRIME(objp))->big_value,
1150                             ((biginteger_t *)
1151                             OBJ_PRI_DH_PRIME(objp))->big_value_len);
1152                         buf = buf + ROUNDUP(((biginteger_t *)
1153                             OBJ_PRI_DH_PRIME(objp))->big_value_len, 8);
1154 
1155                         /* base_len + base */
1156                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1157                             OBJ_PRI_DH_BASE(objp))->big_value_len);
1158                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1159                         buf = buf + sizeof (uint64_t);
1160 
1161                         (void) memcpy(buf, (char *)((biginteger_t *)
1162                             OBJ_PRI_DH_BASE(objp))->big_value,
1163                             ((biginteger_t *)
1164                             OBJ_PRI_DH_BASE(objp))->big_value_len);
1165                         buf = buf + ROUNDUP(((biginteger_t *)
1166                             OBJ_PRI_DH_BASE(objp))->big_value_len, 8);
1167 
1168                         /* value_len + value */
1169                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1170                             OBJ_PRI_DH_VALUE(objp))->big_value_len);
1171                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1172                         buf = buf + sizeof (uint64_t);
1173 
1174                         (void) memcpy(buf, (char *)((biginteger_t *)
1175                             OBJ_PRI_DH_VALUE(objp))->big_value,
1176                             ((biginteger_t *)
1177                             OBJ_PRI_DH_VALUE(objp))->big_value_len);
1178 
1179                         break;
1180 
1181                 case CKK_X9_42_DH:
1182                         /* prime_len + prime */
1183                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1184                             OBJ_PRI_DH942_PRIME(objp))->big_value_len);
1185                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1186                         buf = buf + sizeof (uint64_t);
1187 
1188                         (void) memcpy(buf, (char *)((biginteger_t *)
1189                             OBJ_PRI_DH942_PRIME(objp))->big_value,
1190                             ((biginteger_t *)
1191                             OBJ_PRI_DH942_PRIME(objp))->big_value_len);
1192                         buf = buf + ROUNDUP(((biginteger_t *)
1193                             OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8);
1194 
1195                         /* base_len + base */
1196                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1197                             OBJ_PRI_DH942_BASE(objp))->big_value_len);
1198                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1199                         buf = buf + sizeof (uint64_t);
1200 
1201                         (void) memcpy(buf, (char *)((biginteger_t *)
1202                             OBJ_PRI_DH942_BASE(objp))->big_value,
1203                             ((biginteger_t *)
1204                             OBJ_PRI_DH942_BASE(objp))->big_value_len);
1205                         buf = buf + ROUNDUP(((biginteger_t *)
1206                             OBJ_PRI_DH942_BASE(objp))->big_value_len, 8);
1207 
1208                         /* subprime_len + subprime */
1209                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1210                             OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
1211                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1212                         buf = buf + sizeof (uint64_t);
1213 
1214                         (void) memcpy(buf, (char *)((biginteger_t *)
1215                             OBJ_PRI_DH942_SUBPRIME(objp))->big_value,
1216                             ((biginteger_t *)
1217                             OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
1218                         buf = buf + ROUNDUP(((biginteger_t *)
1219                             OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8);
1220 
1221                         /* value_len + value */
1222                         tmp_val = SWAP64((uint64_t)((biginteger_t *)
1223                             OBJ_PRI_DH942_VALUE(objp))->big_value_len);
1224                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1225                         buf = buf + sizeof (uint64_t);
1226 
1227                         (void) memcpy(buf, (char *)((biginteger_t *)
1228                             OBJ_PRI_DH942_VALUE(objp))->big_value,
1229                             ((biginteger_t *)
1230                             OBJ_PRI_DH942_VALUE(objp))->big_value_len);
1231 
1232                         break;
1233 
1234                 } /* keytype */
1235 
1236                 break;
1237 
1238         case CKO_SECRET_KEY:
1239                 /* value_len  + value */
1240                 tmp_val = SWAP64((uint64_t)OBJ_SEC_VALUE_LEN(objp));
1241                 (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1242                 buf = buf + sizeof (uint64_t);
1243 
1244                 if (OBJ_SEC_VALUE_LEN(objp) > 0) {
1245                         (void) memcpy(buf, (char *)OBJ_SEC_VALUE(objp),
1246                             OBJ_SEC_VALUE_LEN(objp));
1247                         buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
1248                 }
1249 
1250                 break;
1251 
1252         case CKO_CERTIFICATE:
1253 
1254                 switch (certtype) {
1255                 case CKC_X_509:
1256                         /* subject_len + subject */
1257                         tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1258                             X509_CERT_SUBJECT(objp))->length));
1259                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1260                         buf = buf + sizeof (uint64_t);
1261 
1262                         (void) memcpy(buf, (char *)((cert_attr_t *)
1263                             X509_CERT_SUBJECT(objp))->value,
1264                             ((cert_attr_t *)
1265                             X509_CERT_SUBJECT(objp))->length);
1266                         buf = buf + ROUNDUP(((cert_attr_t *)
1267                             X509_CERT_SUBJECT(objp))->length, 8);
1268 
1269                         /* value_len + value */
1270                         tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1271                             X509_CERT_VALUE(objp))->length));
1272                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1273                         buf = buf + sizeof (uint64_t);
1274 
1275                         (void) memcpy(buf, (char *)((cert_attr_t *)
1276                             X509_CERT_VALUE(objp))->value,
1277                             ((cert_attr_t *)
1278                             X509_CERT_VALUE(objp))->length);
1279                         break;
1280 
1281                 case CKC_X_509_ATTR_CERT:
1282                         /* owner_len + owner */
1283                         tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1284                             X509_ATTR_CERT_OWNER(objp))->length));
1285                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1286                         buf = buf + sizeof (uint64_t);
1287 
1288                         (void) memcpy(buf, (char *)((cert_attr_t *)
1289                             X509_ATTR_CERT_OWNER(objp))->value,
1290                             ((cert_attr_t *)
1291                             X509_ATTR_CERT_OWNER(objp))->length);
1292                         buf = buf + ROUNDUP(((cert_attr_t *)
1293                             X509_ATTR_CERT_OWNER(objp))->length, 8);
1294 
1295                         /* value_len + value */
1296                         tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1297                             X509_ATTR_CERT_VALUE(objp))->length));
1298                         (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1299                         buf = buf + sizeof (uint64_t);
1300 
1301                         (void) memcpy(buf, (char *)((cert_attr_t *)
1302                             X509_ATTR_CERT_VALUE(objp))->value,
1303                             ((cert_attr_t *)
1304                             X509_ATTR_CERT_VALUE(objp))->length);
1305                         break;
1306                 }
1307                 break;
1308 
1309         case CKO_DOMAIN_PARAMETERS:
1310 
1311                 return (0);
1312         }
1313         return (CKR_OK);
1314 }
1315 
1316 /*
1317  * Unpack the object key in keystore format (the third part)
1318  * into soft_object_t.
1319  */
1320 CK_RV
1321 soft_unpack_object(soft_object_t *objp, uchar_t *buf)
1322 {
1323 
1324         public_key_obj_t  *pbk;
1325         private_key_obj_t *pvk;
1326         secret_key_obj_t  *sck;
1327         certificate_obj_t *cert;
1328         CK_OBJECT_CLASS class = objp->class;
1329         CK_KEY_TYPE     keytype = objp->key_type;
1330         CK_CERTIFICATE_TYPE certtype = objp->cert_type;
1331 
1332         biginteger_t    modulus;
1333         biginteger_t    pubexpo;
1334         biginteger_t    prime;
1335         biginteger_t    subprime;
1336         biginteger_t    base;
1337         biginteger_t    value;
1338 
1339         biginteger_t    priexpo;
1340         biginteger_t    prime1;
1341         biginteger_t    prime2;
1342         biginteger_t    expo1;
1343         biginteger_t    expo2;
1344         biginteger_t    coef;
1345         CK_RV           rv = CKR_OK;
1346         ulong_t offset = 0;
1347         uint64_t tmp_val;
1348 
1349         /* prevent bigint_attr_cleanup from freeing invalid attr value */
1350         (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1351         (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1352         (void) memset(&prime, 0x0, sizeof (biginteger_t));
1353         (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1354         (void) memset(&base, 0x0, sizeof (biginteger_t));
1355         (void) memset(&value, 0x0, sizeof (biginteger_t));
1356 
1357         (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1358         (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1359         (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1360         (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1361         (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1362         (void) memset(&coef, 0x0, sizeof (biginteger_t));
1363 
1364         switch (class) {
1365 
1366         case CKO_PUBLIC_KEY:
1367                 /* Allocate storage for Public Key Object. */
1368                 pbk = calloc(1, sizeof (public_key_obj_t));
1369                 if (pbk == NULL) {
1370                         rv =  CKR_HOST_MEMORY;
1371                         return (rv);
1372                 }
1373 
1374                 objp->object_class_u.public_key = pbk;
1375 
1376                 switch (keytype) {
1377                 case CKK_RSA:                   /* modulus_bits */
1378                         (void) memcpy(&tmp_val, buf, sizeof (uint64_t));
1379                         KEY_PUB_RSA_MOD_BITS(pbk) = (CK_ULONG)(SWAP64(tmp_val));
1380                         buf = buf + sizeof (uint64_t);
1381 
1382                         /* modulus */
1383                         if ((rv = soft_unpack_obj_attribute(buf, &modulus,
1384                             NULL, &offset, B_FALSE)) != CKR_OK)
1385                                 goto pub_cleanup;
1386 
1387                         copy_bigint_attr(&modulus, KEY_PUB_RSA_MOD(pbk));
1388 
1389                         buf += ROUNDUP(offset, 8);
1390 
1391                         /* pubexpo */
1392                         if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
1393                             NULL, &offset, B_FALSE)) != CKR_OK)
1394                                 goto pub_cleanup;
1395 
1396                         copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1397 
1398                         break;
1399 
1400                 case CKK_DSA:
1401                         /* prime */
1402                         if ((rv = soft_unpack_obj_attribute(buf, &prime,
1403                             NULL, &offset, B_FALSE)) != CKR_OK)
1404                                 goto pub_cleanup;
1405 
1406                         copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1407 
1408                         buf += ROUNDUP(offset, 8);
1409 
1410                         /* subprime */
1411                         if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1412                             NULL, &offset, B_FALSE)) != CKR_OK)
1413                                 goto pub_cleanup;
1414 
1415                         copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1416 
1417                         buf += ROUNDUP(offset, 8);
1418 
1419                         /* base */
1420                         if ((rv = soft_unpack_obj_attribute(buf, &base,
1421                             NULL, &offset, B_FALSE)) != CKR_OK)
1422                                 goto pub_cleanup;
1423 
1424                         copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1425 
1426                         buf += ROUNDUP(offset, 8);
1427 
1428                         /* value */
1429                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1430                             NULL, &offset, B_FALSE)) != CKR_OK)
1431                                 goto pub_cleanup;
1432 
1433                         copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
1434 
1435                         break;
1436 
1437                 case CKK_DH:
1438                         /* prime */
1439                         if ((rv = soft_unpack_obj_attribute(buf, &prime,
1440                             NULL, &offset, B_FALSE)) != CKR_OK)
1441                                 goto pub_cleanup;
1442 
1443                         copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1444 
1445                         buf += ROUNDUP(offset, 8);
1446 
1447                         /* base */
1448                         if ((rv = soft_unpack_obj_attribute(buf, &base,
1449                             NULL, &offset, B_FALSE)) != CKR_OK)
1450                                 goto pub_cleanup;
1451 
1452                         copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1453 
1454                         buf += ROUNDUP(offset, 8);
1455 
1456                         /* value */
1457                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1458                             NULL, &offset, B_FALSE)) != CKR_OK)
1459                                 goto pub_cleanup;
1460 
1461                         copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
1462 
1463                         break;
1464 
1465                 case CKK_EC:
1466                         /* ec_point */
1467                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1468                             NULL, &offset, B_FALSE)) != CKR_OK)
1469                                 goto pri_cleanup;
1470 
1471                         copy_bigint_attr(&value, KEY_PUB_EC_POINT(pbk));
1472                         break;
1473 
1474                 case CKK_X9_42_DH:
1475                         /* prime */
1476                         if ((rv = soft_unpack_obj_attribute(buf, &prime,
1477                             NULL, &offset, B_FALSE)) != CKR_OK)
1478                                 goto pub_cleanup;
1479 
1480                         copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1481 
1482                         buf += ROUNDUP(offset, 8);
1483 
1484                         /* base */
1485                         if ((rv = soft_unpack_obj_attribute(buf, &base,
1486                             NULL, &offset, B_FALSE)) != CKR_OK)
1487                                 goto pub_cleanup;
1488 
1489                         copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1490 
1491                         buf += ROUNDUP(offset, 8);
1492 
1493                         /* subprime */
1494                         if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1495                             NULL, &offset, B_FALSE)) != CKR_OK)
1496                                 goto pub_cleanup;
1497 
1498                         copy_bigint_attr(&subprime,
1499                             KEY_PUB_DH942_SUBPRIME(pbk));
1500 
1501                         buf += ROUNDUP(offset, 8);
1502 
1503                         /* value */
1504                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1505                             NULL, &offset, B_FALSE)) != CKR_OK)
1506                                 goto pub_cleanup;
1507 
1508                         copy_bigint_attr(&value, KEY_PUB_DH942_VALUE(pbk));
1509 
1510                         break;
1511                 } /* keytype */
1512 
1513                 break;
1514 
1515         case CKO_PRIVATE_KEY:
1516                 /* Allocate storage for Private Key Object. */
1517                 pvk = calloc(1, sizeof (private_key_obj_t));
1518                 if (pvk == NULL) {
1519                         rv = CKR_HOST_MEMORY;
1520                         return (rv);
1521                 }
1522 
1523                 objp->object_class_u.private_key = pvk;
1524 
1525                 switch (keytype) {
1526                 case CKK_RSA:
1527                         /* modulus */
1528                         if ((rv = soft_unpack_obj_attribute(buf, &modulus,
1529                             NULL, &offset, B_FALSE)) != CKR_OK)
1530                                 goto pri_cleanup;
1531 
1532                         copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
1533 
1534                         buf += ROUNDUP(offset, 8);
1535 
1536                         /* pubexpo */
1537                         if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
1538                             NULL, &offset, B_FALSE)) != CKR_OK)
1539                                 goto pri_cleanup;
1540 
1541                         copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
1542 
1543                         buf += ROUNDUP(offset, 8);
1544 
1545                         /* priexpo */
1546                         if ((rv = soft_unpack_obj_attribute(buf, &priexpo,
1547                             NULL, &offset, B_FALSE)) != CKR_OK)
1548                                 goto pri_cleanup;
1549 
1550                         copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
1551 
1552                         buf += ROUNDUP(offset, 8);
1553 
1554                         /* prime1 */
1555                         if ((rv = soft_unpack_obj_attribute(buf, &prime1,
1556                             NULL, &offset, B_FALSE)) != CKR_OK)
1557                                 goto pri_cleanup;
1558 
1559                         copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
1560 
1561                         buf += ROUNDUP(offset, 8);
1562 
1563                         /* prime2 */
1564                         if ((rv = soft_unpack_obj_attribute(buf, &prime2,
1565                             NULL, &offset, B_FALSE)) != CKR_OK)
1566                                 goto pri_cleanup;
1567 
1568                         copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
1569 
1570                         buf += ROUNDUP(offset, 8);
1571 
1572                         /* expo1 */
1573                         if ((rv = soft_unpack_obj_attribute(buf, &expo1,
1574                             NULL, &offset, B_FALSE)) != CKR_OK)
1575                                 goto pri_cleanup;
1576 
1577                         copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
1578 
1579                         buf += ROUNDUP(offset, 8);
1580 
1581                         /* expo2 */
1582                         if ((rv = soft_unpack_obj_attribute(buf, &expo2,
1583                             NULL, &offset, B_FALSE)) != CKR_OK)
1584                                 goto pri_cleanup;
1585 
1586                         copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
1587 
1588                         buf += ROUNDUP(offset, 8);
1589 
1590                         /* coef */
1591                         if ((rv = soft_unpack_obj_attribute(buf, &coef,
1592                             NULL, &offset, B_FALSE)) != CKR_OK)
1593                                 goto pri_cleanup;
1594 
1595                         copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
1596 
1597                         break;
1598 
1599                 case CKK_DSA:
1600                         /* prime */
1601                         if ((rv = soft_unpack_obj_attribute(buf, &prime,
1602                             NULL, &offset, B_FALSE)) != CKR_OK)
1603                                 goto pri_cleanup;
1604 
1605                         copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
1606 
1607                         buf += ROUNDUP(offset, 8);
1608 
1609                         /* subprime */
1610                         if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1611                             NULL, &offset, B_FALSE)) != CKR_OK)
1612                                 goto pri_cleanup;
1613 
1614                         copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
1615 
1616                         buf += ROUNDUP(offset, 8);
1617 
1618                         /* base */
1619                         if ((rv = soft_unpack_obj_attribute(buf, &base,
1620                             NULL, &offset, B_FALSE)) != CKR_OK)
1621                                 goto pri_cleanup;
1622 
1623                         copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
1624 
1625                         buf += ROUNDUP(offset, 8);
1626 
1627                         /* value */
1628                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1629                             NULL, &offset, B_FALSE)) != CKR_OK)
1630                                 goto pri_cleanup;
1631 
1632                         copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
1633 
1634                         break;
1635 
1636                 case CKK_DH:
1637                         /* value_bits */
1638                         (void) memcpy(&tmp_val, buf, sizeof (uint64_t));
1639                         KEY_PRI_DH_VAL_BITS(pvk) = (CK_ULONG)(SWAP64(tmp_val));
1640                         buf = buf + sizeof (uint64_t);
1641 
1642                         /* prime */
1643                         if ((rv = soft_unpack_obj_attribute(buf, &prime,
1644                             NULL, &offset, B_FALSE)) != CKR_OK)
1645                                 goto pri_cleanup;
1646 
1647                         copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
1648 
1649                         buf += ROUNDUP(offset, 8);
1650 
1651                         /* base */
1652                         if ((rv = soft_unpack_obj_attribute(buf, &base,
1653                             NULL, &offset, B_FALSE)) != CKR_OK)
1654                                 goto pri_cleanup;
1655 
1656                         copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
1657 
1658                         buf += ROUNDUP(offset, 8);
1659 
1660                         /* value */
1661                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1662                             NULL, &offset, B_FALSE)) != CKR_OK)
1663                                 goto pri_cleanup;
1664 
1665                         copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
1666 
1667                         break;
1668 
1669                 case CKK_EC:
1670                         /* value */
1671                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1672                             NULL, &offset, B_FALSE)) != CKR_OK)
1673                                 goto pri_cleanup;
1674 
1675                         copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
1676                         break;
1677 
1678                 case CKK_X9_42_DH:
1679                         /* prime */
1680                         if ((rv = soft_unpack_obj_attribute(buf, &prime,
1681                             NULL, &offset, B_FALSE)) != CKR_OK)
1682                                 goto pri_cleanup;
1683 
1684                         copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
1685 
1686                         buf += ROUNDUP(offset, 8);
1687 
1688                         /* base */
1689                         if ((rv = soft_unpack_obj_attribute(buf, &base,
1690                             NULL, &offset, B_FALSE)) != CKR_OK)
1691                                 goto pri_cleanup;
1692 
1693                         copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
1694 
1695                         buf += ROUNDUP(offset, 8);
1696 
1697                         /* subprime */
1698                         if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1699                             NULL, &offset, B_FALSE)) != CKR_OK)
1700                                 goto pri_cleanup;
1701 
1702                         copy_bigint_attr(&subprime, KEY_PRI_DH942_BASE(pvk));
1703 
1704                         buf += ROUNDUP(offset, 8);
1705 
1706                         /* value */
1707                         if ((rv = soft_unpack_obj_attribute(buf, &value,
1708                             NULL, &offset, B_FALSE)) != CKR_OK)
1709                                 goto pri_cleanup;
1710 
1711                         copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
1712 
1713                         break;
1714                 } /* keytype */
1715 
1716                 break;
1717 
1718         case CKO_SECRET_KEY:
1719                 /* Allocate storage for Secret Key Object. */
1720                 sck = calloc(1, sizeof (secret_key_obj_t));
1721                 if (sck == NULL) {
1722                         return (CKR_HOST_MEMORY);
1723                 }
1724 
1725                 objp->object_class_u.secret_key = sck;
1726 
1727                 /* value */
1728                 (void) memcpy((void *)&tmp_val, buf, sizeof (uint64_t));
1729                 OBJ_SEC_VALUE_LEN(objp) = (CK_ULONG)(SWAP64(tmp_val));
1730                 buf = buf + sizeof (uint64_t);
1731 
1732                 if (OBJ_SEC_VALUE_LEN(objp) > 0) {
1733                         OBJ_SEC_VALUE(objp) = malloc(OBJ_SEC_VALUE_LEN(objp));
1734                         if (OBJ_SEC_VALUE(objp) == NULL) {
1735                                 free(sck);
1736                                 return (CKR_HOST_MEMORY);
1737                         }
1738                         (void) memcpy(OBJ_SEC_VALUE(objp), buf,
1739                             OBJ_SEC_VALUE_LEN(objp));
1740 
1741                         buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
1742                 }
1743 
1744                 return (rv);
1745 
1746         case CKO_CERTIFICATE:
1747                 /* Allocate storage for Certificate Object. */
1748                 cert = calloc(1, sizeof (certificate_obj_t));
1749                 if (cert == NULL) {
1750                         return (CKR_HOST_MEMORY);
1751                 }
1752                 (void) memset((void *)cert, 0, sizeof (certificate_obj_t));
1753 
1754                 cert->certificate_type = certtype;
1755                 objp->object_class_u.certificate = cert;
1756 
1757                 switch (certtype) {
1758                 case CKC_X_509:
1759                         /* subject */
1760                         if ((rv = soft_unpack_obj_attribute(buf, NULL,
1761                             &cert->cert_type_u.x509.subject,
1762                             &offset, B_TRUE)) != CKR_OK) {
1763                                 free(cert);
1764                                 return (rv);
1765                         }
1766 
1767                         buf += ROUNDUP(offset, 8);
1768 
1769                         /* value */
1770                         if ((rv = soft_unpack_obj_attribute(buf, NULL,
1771                             &cert->cert_type_u.x509.value,
1772                             &offset, B_TRUE)) != CKR_OK) {
1773                                 free(cert);
1774                                 return (rv);
1775                         }
1776 
1777                         break;
1778 
1779                 case CKC_X_509_ATTR_CERT:
1780                         /* owner */
1781                         if ((rv = soft_unpack_obj_attribute(buf, NULL,
1782                             &cert->cert_type_u.x509_attr.owner,
1783                             &offset, B_TRUE)) != CKR_OK) {
1784                                 free(cert);
1785                                 return (rv);
1786                         }
1787 
1788                         buf += ROUNDUP(offset, 8);
1789 
1790                         /* value */
1791                         if ((rv = soft_unpack_obj_attribute(buf, NULL,
1792                             &cert->cert_type_u.x509_attr.value,
1793                             &offset, B_TRUE)) != CKR_OK) {
1794                                 free(cert);
1795                                 return (rv);
1796                         }
1797 
1798                         break;
1799                 }
1800 
1801                 return (rv);
1802 
1803         case CKO_DOMAIN_PARAMETERS:
1804 
1805                 break;
1806         }
1807 
1808 pub_cleanup:
1809         /*
1810          * cleanup the storage allocated to the local variables.
1811          */
1812         if (rv != CKR_OK)
1813                 free(pbk);
1814         bigint_attr_cleanup(&modulus);
1815         bigint_attr_cleanup(&pubexpo);
1816         bigint_attr_cleanup(&prime);
1817         bigint_attr_cleanup(&subprime);
1818         bigint_attr_cleanup(&base);
1819         bigint_attr_cleanup(&value);
1820         return (rv);
1821 
1822 pri_cleanup:
1823         /*
1824          * cleanup the storage allocated to the local variables.
1825          */
1826         if (rv != CKR_OK)
1827                 free(pvk);
1828         bigint_attr_cleanup(&modulus);
1829         bigint_attr_cleanup(&priexpo);
1830         bigint_attr_cleanup(&prime);
1831         bigint_attr_cleanup(&subprime);
1832         bigint_attr_cleanup(&base);
1833         bigint_attr_cleanup(&value);
1834         bigint_attr_cleanup(&pubexpo);
1835         bigint_attr_cleanup(&prime1);
1836         bigint_attr_cleanup(&prime2);
1837         bigint_attr_cleanup(&expo1);
1838         bigint_attr_cleanup(&expo2);
1839         bigint_attr_cleanup(&coef);
1840         return (rv);
1841 }
1842 
1843 
1844 /*
1845  * Store the token object to a keystore file.
1846  */
1847 CK_RV
1848 soft_put_object_to_keystore(soft_object_t *objp)
1849 {
1850 
1851         uchar_t *buf;
1852         size_t len;
1853         CK_RV rv;
1854 
1855         rv = soft_keystore_pack_obj(objp, &buf, &len);
1856         if (rv != CKR_OK)
1857                 return (rv);
1858 
1859         (void) pthread_mutex_lock(&soft_slot.slot_mutex);
1860         if (objp->object_type == TOKEN_PUBLIC) {
1861                 if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
1862                     B_FALSE, &objp->ks_handle)) == -1) {
1863                         (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1864                         free(buf);
1865                         return (CKR_FUNCTION_FAILED);
1866                 }
1867         } else {
1868                 if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
1869                     B_FALSE, &objp->ks_handle)) == -1) {
1870                         (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1871                         free(buf);
1872                         return (CKR_FUNCTION_FAILED);
1873                 }
1874         }
1875         (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1876         free(buf);
1877         return (CKR_OK);
1878 
1879 }
1880 
1881 /*
1882  * Modify the in-core token object and then write it to
1883  * a keystore file.
1884  */
1885 CK_RV
1886 soft_modify_object_to_keystore(soft_object_t *objp)
1887 {
1888 
1889         uchar_t *buf;
1890         size_t len;
1891         CK_RV rv;
1892 
1893         rv = soft_keystore_pack_obj(objp, &buf, &len);
1894         if (rv != CKR_OK)
1895                 return (rv);
1896 
1897         /* B_TRUE: caller has held a writelock on the keystore */
1898         if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
1899             B_TRUE) < 0) {
1900                 return (CKR_FUNCTION_FAILED);
1901         }
1902 
1903         free(buf);
1904         return (CKR_OK);
1905 
1906 }
1907 
1908 /*
1909  * Read the token object from the keystore file.
1910  */
1911 CK_RV
1912 soft_get_token_objects_from_keystore(ks_search_type_t type)
1913 {
1914         CK_RV rv;
1915         ks_obj_t        *ks_obj = NULL, *ks_obj_next;
1916         soft_object_t *new_objp = NULL;
1917 
1918         /* Load the token object from keystore based on the object type */
1919         rv = soft_keystore_get_objs(type, &ks_obj, B_FALSE);
1920         if (rv != CKR_OK) {
1921                 return (rv);
1922         }
1923 
1924         while (ks_obj) {
1925 
1926                 new_objp = calloc(1, sizeof (soft_object_t));
1927                 if (new_objp == NULL) {
1928                         rv = CKR_HOST_MEMORY;
1929                         goto cleanup;
1930                 }
1931                 /* Convert the keystore format to memory format */
1932                 rv = soft_keystore_unpack_obj(new_objp, ks_obj);
1933                 if (rv != CKR_OK) {
1934                         if (new_objp->class == CKO_CERTIFICATE)
1935                                 soft_cleanup_cert_object(new_objp);
1936                         else
1937                                 soft_cleanup_object(new_objp);
1938                         goto cleanup;
1939                 }
1940 
1941                 soft_add_token_object_to_slot(new_objp);
1942 
1943                 /* Free the ks_obj list */
1944                 ks_obj_next = ks_obj->next;
1945                 if (ks_obj->buf)
1946                         free(ks_obj->buf);
1947                 free(ks_obj);
1948                 ks_obj = ks_obj_next;
1949         }
1950 
1951         return (CKR_OK);
1952 
1953 cleanup:
1954         while (ks_obj) {
1955                 ks_obj_next = ks_obj->next;
1956                 free(ks_obj->buf);
1957                 free(ks_obj);
1958                 ks_obj = ks_obj_next;
1959         }
1960         return (rv);
1961 }
1962 
1963 /*
1964  * soft_gen_crypt_key()
1965  *
1966  * Arguments:
1967  *
1968  *      pPIN:   pointer to caller provided Pin
1969  *      key:    output argument which contains the address of the
1970  *              pointer to encryption key in the soft_object_t.
1971  *              It is caller's responsibility to call soft_delete_object()
1972  *              if this key is no longer in use.
1973  *      saltdata: input argument (if non-NULL), or
1974  *                output argument (if NULL):
1975  *                address of pointer to the "salt" of the encryption key
1976  *
1977  * Description:
1978  *
1979  *      Generate an encryption key of the input PIN.
1980  *
1981  * Returns:
1982  *
1983  *      CKR_OK: no error
1984  *      Other: some error occurred while generating the encryption key
1985  *
1986  */
1987 CK_RV
1988 soft_gen_crypt_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
1989 {
1990         CK_OBJECT_CLASS class = CKO_SECRET_KEY;
1991         CK_ATTRIBUTE tmpl[5];
1992         int attrs = 0;
1993         CK_RV rv;
1994         CK_MECHANISM Mechanism;
1995         CK_PKCS5_PBKD2_PARAMS params;
1996         CK_BYTE         salt[PBKD2_SALT_SIZE];
1997         CK_ULONG        keylen = AES_MIN_KEY_BYTES;
1998         CK_KEY_TYPE keytype = CKK_AES;
1999         static CK_BBOOL truevalue = TRUE;
2000         soft_object_t *secret_key;
2001         CK_OBJECT_HANDLE hKey;
2002         CK_ULONG        passwd_size;
2003 
2004         if (pPIN == NULL)
2005                 return (CKR_FUNCTION_FAILED);
2006 
2007         tmpl[attrs].type = CKA_CLASS;
2008         tmpl[attrs].pValue = &class;
2009         tmpl[attrs].ulValueLen = sizeof (class);
2010         attrs++;
2011 
2012         tmpl[attrs].type = CKA_KEY_TYPE;
2013         tmpl[attrs].pValue = &keytype;
2014         tmpl[attrs].ulValueLen = sizeof (keytype);
2015         attrs++;
2016 
2017         tmpl[attrs].type = CKA_ENCRYPT;
2018         tmpl[attrs].pValue = &truevalue;
2019         tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2020         attrs++;
2021 
2022         tmpl[attrs].type = CKA_DECRYPT;
2023         tmpl[attrs].pValue = &truevalue;
2024         tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2025         attrs++;
2026 
2027         tmpl[attrs].type = CKA_VALUE_LEN;
2028         tmpl[attrs].pValue = &keylen;
2029         tmpl[attrs].ulValueLen = sizeof (keylen);
2030         attrs++;
2031 
2032         if (*saltdata == NULL) {
2033                 bzero(salt, sizeof (salt));
2034                 (void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
2035                 *saltdata = malloc(PBKD2_SALT_SIZE);
2036                 if (*saltdata == NULL)
2037                         return (CKR_HOST_MEMORY);
2038                 (void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
2039         } else {
2040                 bzero(salt, sizeof (salt));
2041                 (void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
2042         }
2043 
2044         Mechanism.mechanism = CKM_PKCS5_PBKD2;
2045         Mechanism.pParameter = &params;
2046         Mechanism.ulParameterLen = sizeof (params);
2047         passwd_size = (CK_ULONG)strlen((const char *)pPIN);
2048 
2049         params.saltSource = CKZ_SALT_SPECIFIED;
2050         params.pSaltSourceData = (void *)salt;
2051         params.ulSaltSourceDataLen = sizeof (salt);
2052         params.iterations = PBKD2_ITERATIONS;
2053         params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
2054         params.pPrfData = NULL;
2055         params.ulPrfDataLen = 0;
2056         params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
2057         params.ulPasswordLen = &passwd_size;
2058 
2059         rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
2060             CKO_SECRET_KEY, CKK_AES, 0, SOFT_GEN_KEY, B_TRUE);
2061 
2062         if (rv != CKR_OK) {
2063                 return (rv);
2064         }
2065 
2066         /* Obtain the secret object pointer. */
2067         secret_key = (soft_object_t *)hKey;
2068         keylen = OBJ_SEC_VALUE_LEN(secret_key);
2069         if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
2070                 soft_delete_object(&token_session, secret_key,
2071                     B_FALSE, B_FALSE);
2072                 return (CKR_HOST_MEMORY);
2073         }
2074 
2075         rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
2076             secret_key);
2077 
2078         if (rv != CKR_OK)
2079                 soft_delete_object(&token_session, secret_key,
2080                     B_FALSE, B_FALSE);
2081         else
2082                 *key = secret_key;
2083 
2084         return (rv);
2085 
2086 }
2087 
2088 /*
2089  * soft_gen_hmac_key()
2090  *
2091  * Arguments:
2092  *
2093  *      pPIN:   pointer to caller provided Pin
2094  *      key:    output argument which contains the address of the
2095  *              pointer to hmac key in the soft_object_t.
2096  *              It is caller's responsibility to call soft_delete_object()
2097  *              if this key is no longer in use.
2098  *      saltdata: input argument (if non-NULL), or
2099  *                output argument (if NULL):
2100  *                address of pointer to the "salt" of the hmac key
2101  *
2102  * Description:
2103  *
2104  *      Generate a hmac key of the input PIN.
2105  *
2106  * Returns:
2107  *
2108  *      CKR_OK: no error
2109  *      Other: some error occurred while generating the hmac key
2110  *
2111  */
2112 CK_RV
2113 soft_gen_hmac_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
2114 {
2115         CK_OBJECT_CLASS class = CKO_SECRET_KEY;
2116         CK_ATTRIBUTE tmpl[5];
2117         int attrs = 0;
2118         CK_RV rv;
2119         CK_MECHANISM Mechanism;
2120         CK_PKCS5_PBKD2_PARAMS params;
2121         CK_BYTE         salt[PBKD2_SALT_SIZE];
2122         CK_ULONG        keylen = 16;
2123         CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
2124         static CK_BBOOL truevalue = TRUE;
2125         soft_object_t *secret_key;
2126         CK_OBJECT_HANDLE hKey;
2127         CK_ULONG        passwd_size;
2128 
2129         if (pPIN == NULL)
2130                 return (CKR_FUNCTION_FAILED);
2131 
2132         tmpl[attrs].type = CKA_CLASS;
2133         tmpl[attrs].pValue = &class;
2134         tmpl[attrs].ulValueLen = sizeof (class);
2135         attrs++;
2136 
2137         tmpl[attrs].type = CKA_KEY_TYPE;
2138         tmpl[attrs].pValue = &keytype;
2139         tmpl[attrs].ulValueLen = sizeof (keytype);
2140         attrs++;
2141 
2142         tmpl[attrs].type = CKA_SIGN;
2143         tmpl[attrs].pValue = &truevalue;
2144         tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2145         attrs++;
2146 
2147         tmpl[attrs].type = CKA_VERIFY;
2148         tmpl[attrs].pValue = &truevalue;
2149         tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2150         attrs++;
2151 
2152         tmpl[attrs].type = CKA_VALUE_LEN;
2153         tmpl[attrs].pValue = &keylen;
2154         tmpl[attrs].ulValueLen = sizeof (keylen);
2155         attrs++;
2156 
2157         if (*saltdata == NULL) {
2158                 bzero(salt, sizeof (salt));
2159                 (void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
2160                 *saltdata = malloc(PBKD2_SALT_SIZE);
2161                 if (*saltdata == NULL)
2162                         return (CKR_HOST_MEMORY);
2163                 (void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
2164         } else {
2165                 bzero(salt, sizeof (salt));
2166                 (void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
2167         }
2168 
2169         Mechanism.mechanism = CKM_PKCS5_PBKD2;
2170         Mechanism.pParameter = &params;
2171         Mechanism.ulParameterLen = sizeof (params);
2172         passwd_size = (CK_ULONG)strlen((const char *)pPIN);
2173 
2174         params.saltSource = CKZ_SALT_SPECIFIED;
2175         params.pSaltSourceData = (void *)salt;
2176         params.ulSaltSourceDataLen = sizeof (salt);
2177         params.iterations = PBKD2_ITERATIONS;
2178         params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
2179         params.pPrfData = NULL;
2180         params.ulPrfDataLen = 0;
2181         params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
2182         params.ulPasswordLen = &passwd_size;
2183 
2184         rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
2185             CKO_SECRET_KEY, CKK_GENERIC_SECRET, 0, SOFT_GEN_KEY, B_TRUE);
2186 
2187         if (rv != CKR_OK) {
2188                 return (rv);
2189         }
2190 
2191         /* Obtain the secret object pointer. */
2192         secret_key = (soft_object_t *)hKey;
2193         keylen = OBJ_SEC_VALUE_LEN(secret_key);
2194         if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
2195                 soft_delete_object(&token_session, secret_key,
2196                     B_FALSE, B_FALSE);
2197                 return (CKR_HOST_MEMORY);
2198         }
2199 
2200         rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
2201             secret_key);
2202 
2203         if (rv != CKR_OK)
2204                 soft_delete_object(&token_session, secret_key,
2205                     B_FALSE, B_FALSE);
2206         else
2207                 *key = secret_key;
2208 
2209         return (rv);
2210 
2211 }
2212 
2213 /*
2214  * The token session is just a psuedo session (a place holder)
2215  * to hold some information during encryption/decryption and
2216  * sign/verify operations when writing/reading the keystore
2217  * token object.
2218  */
2219 CK_RV
2220 soft_init_token_session(void)
2221 {
2222 
2223 
2224         token_session.magic_marker = SOFTTOKEN_SESSION_MAGIC;
2225         token_session.pApplication = NULL_PTR;
2226         token_session.Notify = NULL;
2227         token_session.flags = CKF_SERIAL_SESSION;
2228         token_session.state = CKS_RO_PUBLIC_SESSION;
2229         token_session.object_list = NULL;
2230         token_session.ses_refcnt = 0;
2231         token_session.ses_close_sync = 0;
2232         token_session.next = NULL;
2233         token_session.prev = NULL;
2234 
2235         /* Initialize the lock for the token session */
2236         if (pthread_mutex_init(&token_session.session_mutex, NULL) != 0) {
2237                 return (CKR_CANT_LOCK);
2238         }
2239 
2240         (void) pthread_cond_init(&token_session.ses_free_cond, NULL);
2241 
2242         return (CKR_OK);
2243 
2244 }
2245 
2246 void
2247 soft_destroy_token_session(void)
2248 {
2249 
2250         (void) pthread_cond_destroy(&token_session.ses_free_cond);
2251         (void) pthread_mutex_destroy(&token_session.session_mutex);
2252 
2253 }
2254 
2255 /*
2256  * Encrypt/Decrypt the private token object when dealing with the keystore.
2257  * This function only applies to the private token object.
2258  */
2259 CK_RV
2260 soft_keystore_crypt(soft_object_t *key_p, uchar_t *ivec, boolean_t encrypt,
2261         CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
2262 {
2263         CK_MECHANISM    mech;
2264         soft_aes_ctx_t *soft_aes_ctx;
2265         CK_RV rv;
2266         CK_ULONG tmplen, tmplen1;
2267 
2268         /*
2269          * The caller will pass NULL for "out" (output buffer) to find out
2270          * the output buffer size that it need to allocate for the encrption
2271          * or decryption.
2272          */
2273         if (out == NULL) {
2274                 mech.mechanism = CKM_AES_CBC_PAD;
2275                 mech.pParameter = (void *)ivec;
2276                 mech.ulParameterLen = AES_BLOCK_LEN;
2277 
2278                 if (encrypt)
2279                         rv = soft_aes_crypt_init_common(&token_session, &mech,
2280                             key_p, B_TRUE);
2281                 else
2282                         rv = soft_aes_crypt_init_common(&token_session, &mech,
2283                             key_p, B_FALSE);
2284 
2285                 if (rv != CKR_OK)
2286                         return (rv);
2287 
2288 
2289                 (void) pthread_mutex_lock(&token_session.session_mutex);
2290 
2291                 if (encrypt)
2292                         soft_aes_ctx =
2293                             (soft_aes_ctx_t *)token_session.encrypt.context;
2294                 else
2295                         soft_aes_ctx =
2296                             (soft_aes_ctx_t *)token_session.decrypt.context;
2297 
2298                 /* Copy Initialization Vector (IV) into the context. */
2299                 (void) memcpy(soft_aes_ctx->ivec, ivec, AES_BLOCK_LEN);
2300 
2301                 /* Allocate a context for AES cipher-block chaining. */
2302                 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2303                     soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2304                     soft_aes_ctx->ivec);
2305 
2306                 if (soft_aes_ctx->aes_cbc == NULL) {
2307                         bzero(soft_aes_ctx->key_sched,
2308                             soft_aes_ctx->keysched_len);
2309                         free(soft_aes_ctx->key_sched);
2310                         if (encrypt) {
2311                                 free(token_session.encrypt.context);
2312                                 token_session.encrypt.context = NULL;
2313                         } else {
2314                                 free(token_session.encrypt.context);
2315                                 token_session.encrypt.context = NULL;
2316                         }
2317 
2318                         (void) pthread_mutex_unlock(&token_session.
2319                             session_mutex);
2320                         return (CKR_HOST_MEMORY);
2321                 }
2322 
2323                 (void) pthread_mutex_unlock(&token_session.session_mutex);
2324                 /*
2325                  * Since out == NULL, the soft_aes_xxcrypt_common() will
2326                  * simply return the output buffer length to the caller.
2327                  */
2328                 if (encrypt) {
2329                         rv = soft_aes_encrypt_common(&token_session, in,
2330                             in_len, out, out_len, B_FALSE);
2331                 } else {
2332                         rv = soft_aes_decrypt_common(&token_session, in,
2333                             in_len, out, out_len, B_FALSE);
2334                 }
2335 
2336         } else {
2337                 /*
2338                  * The caller has allocated the output buffer, so that we
2339                  * are doing the real encryption/decryption this time.
2340                  */
2341                 tmplen = *out_len;
2342                 if (encrypt) {
2343                         rv = soft_aes_encrypt_common(&token_session, in,
2344                             in_len, out, &tmplen, B_TRUE);
2345                         if (rv == CKR_OK) {
2346                                 tmplen1 = *out_len - tmplen;
2347                                 rv = soft_encrypt_final(&token_session,
2348                                     out+tmplen, &tmplen1);
2349                                 *out_len = tmplen + tmplen1;
2350                         }
2351                 } else {
2352                         rv = soft_aes_decrypt_common(&token_session, in,
2353                             in_len, out, &tmplen, B_TRUE);
2354                         if (rv == CKR_OK) {
2355                                 tmplen1 = *out_len - tmplen;
2356                                 rv = soft_decrypt_final(&token_session,
2357                                     out+tmplen, &tmplen1);
2358                                 *out_len = tmplen + tmplen1;
2359                         }
2360                 }
2361         }
2362 
2363         return (rv);
2364 
2365 }
2366 
2367 /*
2368  * Sign/Verify the private token object for checking its data integrity
2369  * when dealing with the keystore.
2370  * This function only applies to the private token object.
2371  */
2372 CK_RV
2373 soft_keystore_hmac(soft_object_t *key_p, boolean_t sign,
2374         CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
2375 {
2376         CK_MECHANISM mech;
2377         CK_RV rv;
2378 
2379         mech.mechanism = CKM_MD5_HMAC;
2380         mech.pParameter = NULL_PTR;
2381         mech.ulParameterLen = 0;
2382 
2383         rv = soft_hmac_sign_verify_init_common(&token_session, &mech,
2384             key_p, sign);
2385 
2386         if (rv != CKR_OK)
2387                 return (rv);
2388 
2389         if (sign) {
2390                 rv = soft_sign(&token_session, in, in_len, out, out_len);
2391         } else {
2392                 rv = soft_verify(&token_session, in, in_len, out, *out_len);
2393         }
2394 
2395         return (rv);
2396 }