Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.

  23  */
  24 
  25 #include <crypt.h>
  26 #include <cryptoutil.h>
  27 #include <pwd.h>
  28 #include <pthread.h>
  29 #include <stdlib.h>
  30 #include <string.h>
  31 #include <strings.h>
  32 #include <sys/types.h>
  33 #include <sys/sysmacros.h>
  34 #include <security/cryptoki.h>
  35 #include "softGlobal.h"
  36 #include "softCrypt.h"
  37 #include "softSession.h"
  38 #include "softObject.h"
  39 #include "softKeys.h"
  40 #include "softKeystore.h"
  41 #include "softKeystoreUtil.h"
  42 #include "softMAC.h"


  81          */
  82         uid = geteuid();
  83         if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
  84                 return (-1);
  85         }
  86 
  87         if (*salt == NULL) {
  88                 new_salt = B_TRUE;
  89                 /*
  90                  * crypt_gensalt() will allocate memory to store the new salt.
  91                  * on return.  Pass "$5" here to default to crypt_sha256 since
  92                  * SHA256 is a FIPS 140-2 certified algorithm and we shouldn't
  93                  * assume the system default is that strong.
  94                  */
  95                 if ((*salt = crypt_gensalt("$5", pw)) == NULL) {
  96                         return (-1);
  97                 }
  98         }
  99 
 100         if ((*result = crypt((char *)pPin, *salt)) == NULL) {
 101                 if (new_salt)
 102                         free(*salt);



 103                 return (-1);
 104         }
 105 
 106         return (0);
 107 }
 108 
 109 /*
 110  * Authenticate user's PIN for C_Login.
 111  */
 112 CK_RV
 113 soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
 114 {
 115 
 116         char    *user_cryptpin = NULL;
 117         char    *ks_cryptpin = NULL;
 118         char    *salt = NULL;
 119         uchar_t *tmp_pin = NULL;
 120         boolean_t pin_initialized = B_FALSE;
 121         CK_RV   rv = CKR_OK;

 122 
 123         /*
 124          * Check to see if keystore is initialized.
 125          */
 126         rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
 127             B_FALSE);
 128         if (rv != CKR_OK)
 129                 return (rv);
 130 
 131         /*
 132          * Authenticate user's PIN for C_Login.
 133          */
 134         if (pin_initialized) {
 135 
 136                 if (soft_keystore_get_pin_salt(&salt) < 0) {
 137                         rv = CKR_FUNCTION_FAILED;
 138                         goto cleanup;
 139                 }
 140 
 141                 /*


 172                  */
 173                 if (soft_keystore_authpin(tmp_pin) != 0) {
 174                         rv = CKR_FUNCTION_FAILED;
 175                 } else {
 176                         rv = CKR_OK;
 177                 }
 178                 goto cleanup;
 179         } else {
 180                 /*
 181                  * The PIN is not initialized in the keystore
 182                  * We will let it pass the authentication anyway but set the
 183                  * "userpin_change_needed" flag so that the application
 184                  * will get CKR_PIN_EXPIRED by other C_functions such as
 185                  * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
 186                  */
 187                 soft_slot.userpin_change_needed = 1;
 188                 rv = CKR_OK;
 189         }
 190 
 191 cleanup:
 192         if (salt)
 193                 free(salt);
 194         if (tmp_pin)
 195                 free(tmp_pin);
 196         if (ks_cryptpin)
 197                 free(ks_cryptpin);
 198 





 199         return (rv);
 200 }
 201 
 202 /*
 203  * The second level C_SetPIN function.
 204  */
 205 CK_RV
 206 soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
 207     CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
 208 {
 209 
 210         char    *user_cryptpin = NULL;
 211         char    *ks_cryptpin = NULL;
 212         char    *salt = NULL;
 213         boolean_t pin_initialized = B_FALSE;
 214         uchar_t *tmp_old_pin = NULL, *tmp_new_pin = NULL;
 215         CK_RV   rv = CKR_OK;

 216 
 217         /*
 218          * Check to see if keystore is initialized.
 219          */
 220         rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
 221             B_FALSE);
 222         if (rv != CKR_OK)
 223                 return (rv);
 224 
 225         /*
 226          * Authenticate user's PIN for C_SetPIN.
 227          */
 228         if (pin_initialized) {
 229                 /*
 230                  * Generate the hashed value based on the user supplied PIN.
 231                  */
 232                 if (soft_keystore_get_pin_salt(&salt) < 0) {
 233                         rv = CKR_FUNCTION_FAILED;
 234                         goto cleanup;
 235                 }


 273                 rv = CKR_HOST_MEMORY;
 274                 goto cleanup;
 275         }
 276         (void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
 277         tmp_new_pin[ulNewPinLen] = '\0';
 278 
 279         /*
 280          * Set the new pin after the old pin is authenticated.
 281          */
 282         if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
 283                 rv = CKR_FUNCTION_FAILED;
 284                 goto cleanup;
 285         } else {
 286                 (void) pthread_mutex_lock(&soft_giant_mutex);
 287                 soft_slot.userpin_change_needed = 0;
 288                 (void) pthread_mutex_unlock(&soft_giant_mutex);
 289                 rv = CKR_OK;
 290         }
 291 
 292 cleanup:
 293         if (salt)
 294                 free(salt);
 295         if (ks_cryptpin)
 296                 free(ks_cryptpin);
 297         if (tmp_old_pin)
 298                 free(tmp_old_pin);
 299         if (tmp_new_pin)
 300                 free(tmp_new_pin);








 301 
 302         return (rv);
 303 }
 304 
 305 /*
 306  * soft_keystore_pack_obj()
 307  *
 308  * Arguments:
 309  *
 310  *      obj:    pointer to the soft_object_t of the token object to
 311  *              be packed
 312  *      ks_buf: output argument which contains the address of the
 313  *              pointer to the buf of the packed token object
 314  *              soft_keystore_pack_obj() will allocate memory for the buf,
 315  *              it is caller's responsibility to free it.
 316  *      len:    output argument which contains the address of the
 317  *              buffer length of the packed token object
 318  *
 319  * Description:
 320  *


 458          * Unpack extra attribute list.
 459          */
 460         for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
 461                 /* LINTED: pointer alignment */
 462                 attr_hdr = (ks_attr_hdr_t *)buf;
 463                 (void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
 464                 template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
 465                 template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
 466                 buf = buf + sizeof (ks_attr_hdr_t);
 467                 /* Allocate storage for the value of the attribute. */
 468                 if (template.ulValueLen > 0) {
 469                         template.pValue = malloc(template.ulValueLen);
 470                         if (template.pValue == NULL) {
 471                                 return (CKR_HOST_MEMORY);
 472                         }
 473                         (void) memcpy(template.pValue, buf,
 474                             template.ulValueLen);
 475                 }
 476 
 477                 rv = soft_add_extra_attr(&template, obj);
 478                 if (template.pValue) {
 479                         free(template.pValue);
 480                 }
 481 
 482                 if (rv != CKR_OK) {
 483                         return (rv);
 484                 }
 485 
 486                 buf = buf + ROUNDUP(template.ulValueLen, 8);
 487         }
 488 
 489         /*
 490          * Unpack the key itself.
 491          */
 492         rv = soft_unpack_object(obj, buf);
 493         return (rv);
 494 
 495 }
 496 
 497 
 498 /*
 499  * soft_unpack_obj_attribute()
 500  *


 526 {
 527 
 528         CK_RV rv;
 529         CK_ATTRIBUTE template;
 530 
 531         /* LINTED: pointer alignment */
 532         template.ulValueLen = SWAP64(*(uint64_t *)buf);
 533         buf = buf + sizeof (uint64_t);
 534         template.pValue = malloc(template.ulValueLen);
 535         if (template.pValue == NULL) {
 536                 return (CKR_HOST_MEMORY);
 537         }
 538 
 539         (void) memcpy(template.pValue, buf, template.ulValueLen);
 540         if (cert) {
 541                 rv = get_cert_attr_from_template(cert_dest, &template);
 542         } else {
 543                 rv = get_bigint_attr_from_template(key_dest, &template);
 544         }
 545 
 546         free(template.pValue);
 547         if (rv != CKR_OK) {
 548                 return (rv);
 549         }
 550 
 551         *offset = sizeof (uint64_t) + template.ulValueLen;
 552         return (CKR_OK);
 553 }
 554 
 555 
 556 /*
 557  * Calculate the total buffer length required to store the
 558  * object key (the third part) in a keystore format.
 559  */
 560 ulong_t
 561 soft_pack_object_size(soft_object_t *objp)
 562 {
 563 
 564         CK_OBJECT_CLASS class = objp->class;
 565         CK_KEY_TYPE     keytype = objp->key_type;
 566         CK_CERTIFICATE_TYPE certtype = objp->cert_type;


1840         return (rv);
1841 }
1842 
1843 
1844 /*
1845  * Store the token object to a keystore file.
1846  */
1847 CK_RV
1848 soft_put_object_to_keystore(soft_object_t *objp)
1849 {
1850 
1851         uchar_t *buf;
1852         size_t len;
1853         CK_RV rv;
1854 
1855         rv = soft_keystore_pack_obj(objp, &buf, &len);
1856         if (rv != CKR_OK)
1857                 return (rv);
1858 
1859         (void) pthread_mutex_lock(&soft_slot.slot_mutex);
1860         if (objp->object_type == TOKEN_PUBLIC) {
1861                 if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
1862                     B_FALSE, &objp->ks_handle)) == -1) {
1863                         (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1864                         free(buf);
1865                         return (CKR_FUNCTION_FAILED);
1866                 }
1867         } else {
1868                 if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
1869                     B_FALSE, &objp->ks_handle)) == -1) {
1870                         (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1871                         free(buf);
1872                         return (CKR_FUNCTION_FAILED);
1873                 }
1874         }
1875         (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1876         free(buf);
1877         return (CKR_OK);
1878 


1879 }
1880 
1881 /*
1882  * Modify the in-core token object and then write it to
1883  * a keystore file.
1884  */
1885 CK_RV
1886 soft_modify_object_to_keystore(soft_object_t *objp)
1887 {
1888 
1889         uchar_t *buf;
1890         size_t len;
1891         CK_RV rv;
1892 
1893         rv = soft_keystore_pack_obj(objp, &buf, &len);
1894         if (rv != CKR_OK)
1895                 return (rv);
1896 
1897         /* B_TRUE: caller has held a writelock on the keystore */
1898         if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
1899             B_TRUE) < 0) {
1900                 return (CKR_FUNCTION_FAILED);
1901         }
1902 
1903         free(buf);
1904         return (CKR_OK);
1905 
1906 }
1907 
1908 /*
1909  * Read the token object from the keystore file.
1910  */
1911 CK_RV
1912 soft_get_token_objects_from_keystore(ks_search_type_t type)
1913 {
1914         CK_RV rv;
1915         ks_obj_t        *ks_obj = NULL, *ks_obj_next;
1916         soft_object_t *new_objp = NULL;
1917 
1918         /* Load the token object from keystore based on the object type */
1919         rv = soft_keystore_get_objs(type, &ks_obj, B_FALSE);
1920         if (rv != CKR_OK) {
1921                 return (rv);
1922         }
1923 
1924         while (ks_obj) {
1925 
1926                 new_objp = calloc(1, sizeof (soft_object_t));
1927                 if (new_objp == NULL) {
1928                         rv = CKR_HOST_MEMORY;
1929                         goto cleanup;
1930                 }
1931                 /* Convert the keystore format to memory format */
1932                 rv = soft_keystore_unpack_obj(new_objp, ks_obj);
1933                 if (rv != CKR_OK) {
1934                         if (new_objp->class == CKO_CERTIFICATE)
1935                                 soft_cleanup_cert_object(new_objp);
1936                         else
1937                                 soft_cleanup_object(new_objp);
1938                         goto cleanup;
1939                 }
1940 
1941                 soft_add_token_object_to_slot(new_objp);
1942 
1943                 /* Free the ks_obj list */
1944                 ks_obj_next = ks_obj->next;
1945                 if (ks_obj->buf)
1946                         free(ks_obj->buf);
1947                 free(ks_obj);
1948                 ks_obj = ks_obj_next;
1949         }
1950 
1951         return (CKR_OK);
1952 
1953 cleanup:
1954         while (ks_obj) {
1955                 ks_obj_next = ks_obj->next;
1956                 free(ks_obj->buf);
1957                 free(ks_obj);
1958                 ks_obj = ks_obj_next;
1959         }
1960         return (rv);
1961 }
1962 
1963 /*
1964  * soft_gen_crypt_key()
1965  *
1966  * Arguments:
1967  *
1968  *      pPIN:   pointer to caller provided Pin
1969  *      key:    output argument which contains the address of the
1970  *              pointer to encryption key in the soft_object_t.
1971  *              It is caller's responsibility to call soft_delete_object()
1972  *              if this key is no longer in use.
1973  *      saltdata: input argument (if non-NULL), or
1974  *                output argument (if NULL):
1975  *                address of pointer to the "salt" of the encryption key
1976  *


2287 
2288 
2289                 (void) pthread_mutex_lock(&token_session.session_mutex);
2290 
2291                 if (encrypt)
2292                         soft_aes_ctx =
2293                             (soft_aes_ctx_t *)token_session.encrypt.context;
2294                 else
2295                         soft_aes_ctx =
2296                             (soft_aes_ctx_t *)token_session.decrypt.context;
2297 
2298                 /* Copy Initialization Vector (IV) into the context. */
2299                 (void) memcpy(soft_aes_ctx->ivec, ivec, AES_BLOCK_LEN);
2300 
2301                 /* Allocate a context for AES cipher-block chaining. */
2302                 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2303                     soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2304                     soft_aes_ctx->ivec);
2305 
2306                 if (soft_aes_ctx->aes_cbc == NULL) {
2307                         bzero(soft_aes_ctx->key_sched,
2308                             soft_aes_ctx->keysched_len);
2309                         free(soft_aes_ctx->key_sched);
2310                         if (encrypt) {
2311                                 free(token_session.encrypt.context);
2312                                 token_session.encrypt.context = NULL;
2313                         } else {
2314                                 free(token_session.encrypt.context);
2315                                 token_session.encrypt.context = NULL;
2316                         }
2317 
2318                         (void) pthread_mutex_unlock(&token_session.
2319                             session_mutex);
2320                         return (CKR_HOST_MEMORY);
2321                 }
2322 
2323                 (void) pthread_mutex_unlock(&token_session.session_mutex);
2324                 /*
2325                  * Since out == NULL, the soft_aes_xxcrypt_common() will
2326                  * simply return the output buffer length to the caller.
2327                  */
2328                 if (encrypt) {
2329                         rv = soft_aes_encrypt_common(&token_session, in,




   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"


  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                 /*


 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                 }


 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  *


 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  *


 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;


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  *


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,