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