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 /*
  23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 #include <strings.h>
  27 #include <cryptoutil.h>
  28 #include <security/cryptoki.h>
  29 #include <sys/crypto/common.h>
  30 #include <arcfour.h>
  31 #include "softGlobal.h"
  32 #include "softSession.h"
  33 #include <aes_impl.h>
  34 #include <blowfish_impl.h>
  35 #include <des_impl.h>
  36 #include <ecc_impl.h>
  37 #include "softDH.h"
  38 #include "softObject.h"
  39 #include "softKeystore.h"
  40 #include "softKeystoreUtil.h"
  41 
  42 
  43 static CK_MECHANISM_TYPE soft_mechanisms[] = {
  44         CKM_DES_CBC,
  45         CKM_DES_CBC_PAD,
  46         CKM_DES_ECB,
  47         CKM_DES_KEY_GEN,
  48         CKM_DES_MAC_GENERAL,
  49         CKM_DES_MAC,
  50         CKM_DES3_CBC,
  51         CKM_DES3_CBC_PAD,
  52         CKM_DES3_ECB,
  53         CKM_DES2_KEY_GEN,
  54         CKM_DES3_KEY_GEN,
  55         CKM_AES_CBC,
  56         CKM_AES_CBC_PAD,
  57         CKM_AES_CTR,
  58         CKM_AES_ECB,
  59         CKM_AES_KEY_GEN,
  60         CKM_BLOWFISH_CBC,
  61         CKM_BLOWFISH_KEY_GEN,
  62         CKM_SHA_1,
  63         CKM_SHA_1_HMAC,
  64         CKM_SHA_1_HMAC_GENERAL,
  65         CKM_SHA256,
  66         CKM_SHA256_HMAC,
  67         CKM_SHA256_HMAC_GENERAL,
  68         CKM_SHA384,
  69         CKM_SHA384_HMAC,
  70         CKM_SHA384_HMAC_GENERAL,
  71         CKM_SHA512,
  72         CKM_SHA512_HMAC,
  73         CKM_SHA512_HMAC_GENERAL,
  74         CKM_SSL3_SHA1_MAC,
  75         CKM_MD5,
  76         CKM_MD5_HMAC,
  77         CKM_MD5_HMAC_GENERAL,
  78         CKM_SSL3_MD5_MAC,
  79         CKM_RC4,
  80         CKM_RC4_KEY_GEN,
  81         CKM_DSA,
  82         CKM_DSA_SHA1,
  83         CKM_DSA_KEY_PAIR_GEN,
  84         CKM_RSA_PKCS,
  85         CKM_RSA_PKCS_KEY_PAIR_GEN,
  86         CKM_RSA_X_509,
  87         CKM_MD5_RSA_PKCS,
  88         CKM_SHA1_RSA_PKCS,
  89         CKM_SHA256_RSA_PKCS,
  90         CKM_SHA384_RSA_PKCS,
  91         CKM_SHA512_RSA_PKCS,
  92         CKM_DH_PKCS_KEY_PAIR_GEN,
  93         CKM_DH_PKCS_DERIVE,
  94         CKM_MD5_KEY_DERIVATION,
  95         CKM_SHA1_KEY_DERIVATION,
  96         CKM_SHA256_KEY_DERIVATION,
  97         CKM_SHA384_KEY_DERIVATION,
  98         CKM_SHA512_KEY_DERIVATION,
  99         CKM_PBE_SHA1_RC4_128,
 100         CKM_PKCS5_PBKD2,
 101         CKM_SSL3_PRE_MASTER_KEY_GEN,
 102         CKM_TLS_PRE_MASTER_KEY_GEN,
 103         CKM_SSL3_MASTER_KEY_DERIVE,
 104         CKM_TLS_MASTER_KEY_DERIVE,
 105         CKM_SSL3_MASTER_KEY_DERIVE_DH,
 106         CKM_TLS_MASTER_KEY_DERIVE_DH,
 107         CKM_SSL3_KEY_AND_MAC_DERIVE,
 108         CKM_TLS_KEY_AND_MAC_DERIVE,
 109         CKM_TLS_PRF,
 110         CKM_EC_KEY_PAIR_GEN,
 111         CKM_ECDSA,
 112         CKM_ECDSA_SHA1,
 113         CKM_ECDH1_DERIVE
 114 };
 115 
 116 /*
 117  * This is the table of CK_MECHANISM_INFO structs for the supported mechanisms.
 118  * The index for this table is the same as the one above for the same
 119  * mechanism.
 120  * The minimum and maximum sizes of the key for the mechanism can be measured
 121  * in bits or in bytes (i.e. mechanism-dependent). This table specifies the
 122  * supported range of key sizes in bytes; unless noted as in bits.
 123  */
 124 static CK_MECHANISM_INFO soft_mechanism_info[] = {
 125         {DES_MINBYTES, DES_MAXBYTES,
 126                 CKF_ENCRYPT|CKF_DECRYPT|
 127                 CKF_WRAP|CKF_UNWRAP},           /* CKM_DES_CBC */
 128         {DES_MINBYTES, DES_MAXBYTES,
 129                 CKF_ENCRYPT|CKF_DECRYPT|
 130                 CKF_WRAP|CKF_UNWRAP},           /* CKM_DES_CBC_PAD */
 131         {DES_MINBYTES, DES_MAXBYTES,
 132                 CKF_ENCRYPT|CKF_DECRYPT|
 133                 CKF_WRAP|CKF_UNWRAP},           /* CKM_DES_ECB */
 134         {DES_MINBYTES, DES_MAXBYTES,
 135                 CKF_GENERATE},                  /* CKM_DES_KEY_GEN */
 136         {DES_MINBYTES, DES_MAXBYTES,
 137                 CKF_SIGN|CKF_VERIFY},           /* CKM_DES_MAC_GENERAL */
 138         {DES_MINBYTES, DES_MAXBYTES,
 139                 CKF_SIGN|CKF_VERIFY},           /* CKM_DES_MAC */
 140         {DES3_MINBYTES, DES3_MAXBYTES,
 141                 CKF_ENCRYPT|CKF_DECRYPT|
 142                 CKF_WRAP|CKF_UNWRAP},           /* CKM_DES3_CBC */
 143         {DES3_MINBYTES, DES3_MAXBYTES,
 144                 CKF_ENCRYPT|CKF_DECRYPT|
 145                 CKF_WRAP|CKF_UNWRAP},           /* CKM_DES3_CBC_PAD */
 146         {DES3_MINBYTES, DES3_MAXBYTES,
 147                 CKF_ENCRYPT|CKF_DECRYPT|
 148                 CKF_WRAP|CKF_UNWRAP},           /* CKM_DES3_ECB */
 149         {DES2_MAXBYTES, DES2_MAXBYTES,
 150                 CKF_GENERATE},                  /* CKM_DES2_KEY_GEN */
 151         {DES3_MAXBYTES, DES3_MAXBYTES,          /* CKK_DES3 only */
 152                 CKF_GENERATE},                  /* CKM_DES3_KEY_GEN */
 153         {AES_MINBYTES, AES_MAXBYTES,
 154                 CKF_ENCRYPT|CKF_DECRYPT|
 155                 CKF_WRAP|CKF_UNWRAP},           /* CKM_AES_CBC */
 156         {AES_MINBYTES, AES_MAXBYTES,
 157                 CKF_ENCRYPT|CKF_DECRYPT|
 158                 CKF_WRAP|CKF_UNWRAP},           /* CKM_AES_CBC_PAD */
 159         {AES_MINBYTES, AES_MAXBYTES,
 160                 CKF_ENCRYPT|CKF_DECRYPT|
 161                 CKF_WRAP|CKF_UNWRAP},           /* CKM_AES_CTR */
 162         {AES_MINBYTES, AES_MAXBYTES,
 163                 CKF_ENCRYPT|CKF_DECRYPT|
 164                 CKF_WRAP|CKF_UNWRAP},           /* CKM_AES_ECB */
 165         {AES_MINBYTES, AES_MAXBYTES,
 166                 CKF_GENERATE},                  /* CKM_AES_KEY_GEN */
 167         {BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
 168                 CKF_ENCRYPT|CKF_DECRYPT|
 169                 CKF_WRAP|CKF_UNWRAP},           /* CKM_BLOWFISH_ECB */
 170         {BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
 171                 CKF_GENERATE},                  /* CKM_BLOWFISH_KEY_GEN */
 172         {0, 0, CKF_DIGEST},                     /* CKM_SHA_1 */
 173         {1, 64, CKF_SIGN|CKF_VERIFY},           /* CKM_SHA_1_HMAC */
 174         {1, 64, CKF_SIGN|CKF_VERIFY},           /* CKM_SHA_1_HMAC_GENERAL */
 175         {0, 0, CKF_DIGEST},                     /* CKM_SHA256 */
 176         {1, 64, CKF_SIGN|CKF_VERIFY},           /* CKM_SHA256_HMAC */
 177         {1, 64, CKF_SIGN|CKF_VERIFY},           /* CKM_SHA256_HMAC_GENERAL */
 178         {0, 0, CKF_DIGEST},                     /* CKM_SHA384 */
 179         {1, 128, CKF_SIGN|CKF_VERIFY},          /* CKM_SHA384_HMAC */
 180         {1, 128, CKF_SIGN|CKF_VERIFY},          /* CKM_SHA384_HMAC_GENERAL */
 181         {0, 0, CKF_DIGEST},                     /* CKM_SHA512 */
 182         {1, 128, CKF_SIGN|CKF_VERIFY},          /* CKM_SHA512_HMAC */
 183         {1, 128, CKF_SIGN|CKF_VERIFY},          /* CKM_SHA512_HMAC_GENERAL */
 184         {1, 512, CKF_SIGN|CKF_VERIFY},          /* CKM_SSL3_SHA1_MAC */
 185         {0, 0, CKF_DIGEST},                     /* CKM_MD5 */
 186         {1, 64, CKF_SIGN|CKF_VERIFY},           /* CKM_MD5_HMAC */
 187         {1, 64, CKF_SIGN|CKF_VERIFY},           /* CKM_MD5_HMAC_GENERAL */
 188         {1, 512, CKF_SIGN|CKF_VERIFY},          /* CKM_SSL3_MD5_MAC */
 189         {8, ARCFOUR_MAX_KEY_BITS, CKF_ENCRYPT|CKF_DECRYPT}, /* CKM_RC4; */
 190                                                             /* in bits  */
 191         {8, ARCFOUR_MAX_KEY_BITS, CKF_GENERATE }, /* CKM_RC4_KEY_GEN; in bits */
 192         {512, 1024, CKF_SIGN|CKF_VERIFY},       /* CKM_DSA; in bits */
 193         {512, 1024, CKF_SIGN|CKF_VERIFY},       /* CKM_DSA_SHA1; in bits */
 194         {512, 1024, CKF_GENERATE_KEY_PAIR},     /* CKM_DSA_KEY_PAIR_GEN; */
 195                                                 /* in bits */
 196         {256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
 197                 CKF_SIGN|CKF_SIGN_RECOVER|
 198                 CKF_WRAP|CKF_UNWRAP|
 199                 CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_PKCS; in bits */
 200         {256, 4096, CKF_GENERATE_KEY_PAIR},     /* CKM_RSA_PKCS_KEY_PAIR_GEN; */
 201                                                 /* in bits */
 202         {256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
 203                 CKF_SIGN|CKF_SIGN_RECOVER|
 204                 CKF_WRAP|CKF_UNWRAP|
 205                 CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_X_509 in bits */
 206         {256, 4096, CKF_SIGN|CKF_VERIFY},       /* CKM_MD5_RSA_PKCS in bits */
 207         {256, 4096, CKF_SIGN|CKF_VERIFY},       /* CKM_SHA1_RSA_PKCS in bits */
 208         {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_RSA_PKCS in bits */
 209         {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_RSA_PKCS in bits */
 210         {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_RSA_PKCS in bits */
 211         {DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
 212                                                 /* CKM_DH_PKCS_KEY_PAIR_GEN */
 213                                                 /* in bits */
 214         {DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_DERIVE},
 215                                                 /* CKM_DH_PKCS_DERIVE; */
 216                                                 /* in bits */
 217         {1, 16, CKF_DERIVE},                    /* CKM_MD5_KEY_DERIVATION */
 218         {1, 20, CKF_DERIVE},                    /* CKM_SHA1_KEY_DERIVATION */
 219         {1, 32, CKF_DERIVE},                    /* CKM_SHA256_KEY_DERIVATION */
 220         {1, 48, CKF_DERIVE},                    /* CKM_SHA384_KEY_DERIVATION */
 221         {1, 64, CKF_DERIVE},                    /* CKM_SHA512_KEY_DERIVATION */
 222         {0, 0, CKF_GENERATE},                   /* CKM_PBE_SHA1_RC4_128 */
 223         {0, 0, CKF_GENERATE},                   /* CKM_PKCS5_PBKD2 */
 224         {48, 48, CKF_GENERATE},         /* CKM_SSL3_PRE_MASTER_KEY_GEN */
 225         {48, 48, CKF_GENERATE},         /* CKM_TLS_PRE_MASTER_KEY_GEN */
 226         {48, 48, CKF_DERIVE},           /* CKM_SSL3_MASTER_KEY_DERIVE */
 227         {48, 48, CKF_DERIVE},           /* CKM_TLS_MASTER_KEY_DERIVE */
 228         {48, 48, CKF_DERIVE},           /* CKM_SSL3_MASTER_KEY_DERIVE_DH */
 229         {48, 48, CKF_DERIVE},           /* CKM_TLS_MASTER_KEY_DERIVE_DH */
 230         {0, 0, CKF_DERIVE},             /* CKM_SSL3_KEY_AND_MAC_DERIVE */
 231         {0, 0, CKF_DERIVE},             /* CKM_TLS_KEY_AND_MAC_DERIVE */
 232         {0, 0, CKF_DERIVE},             /* CKM_TLS_PRF */
 233         {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
 234         {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
 235         {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
 236         {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_DERIVE}
 237 };
 238 
 239 /*
 240  * Slot ID for softtoken is always 1. tokenPresent is ignored.
 241  * Also, only one slot is used.
 242  */
 243 /*ARGSUSED*/
 244 CK_RV
 245 C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
 246     CK_ULONG_PTR pulCount)
 247 {
 248 
 249         CK_RV rv;
 250 
 251         if (!softtoken_initialized)
 252                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 253 
 254         if (pulCount == NULL) {
 255                 return (CKR_ARGUMENTS_BAD);
 256         }
 257 
 258         if (pSlotList == NULL) {
 259                 /*
 260                  * Application only wants to know the number of slots.
 261                  */
 262                 *pulCount = 1;
 263                 return (CKR_OK);
 264         }
 265 
 266         if ((*pulCount < 1) && (pSlotList != NULL)) {
 267                 rv = CKR_BUFFER_TOO_SMALL;
 268         } else {
 269                 pSlotList[0] = SOFTTOKEN_SLOTID;
 270                 rv = CKR_OK;
 271         }
 272 
 273         *pulCount = 1;
 274         return (rv);
 275 }
 276 
 277 
 278 CK_RV
 279 C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
 280 {
 281 
 282         if (!softtoken_initialized)
 283                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 284 
 285         if (pInfo == NULL)
 286                 return (CKR_ARGUMENTS_BAD);
 287 
 288         /* Make sure the slot ID is valid */
 289         if (slotID != SOFTTOKEN_SLOTID)
 290                 return (CKR_SLOT_ID_INVALID);
 291 
 292         /* Provide information about the slot in the provided buffer */
 293         (void) strncpy((char *)pInfo->slotDescription, SOFT_SLOT_DESCRIPTION,
 294             64);
 295         (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
 296         pInfo->flags = CKF_TOKEN_PRESENT;
 297         pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
 298         pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
 299         pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
 300         pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
 301 
 302         return (CKR_OK);
 303 }
 304 
 305 CK_RV
 306 C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
 307 {
 308         boolean_t pin_initialized = B_FALSE;
 309         char    *ks_cryptpin = NULL;
 310 
 311         if (!softtoken_initialized)
 312                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 313 
 314         /* Make sure the slot ID is valid */
 315         if (slotID != SOFTTOKEN_SLOTID)
 316                 return (CKR_SLOT_ID_INVALID);
 317 
 318         if (pInfo == NULL)
 319                 return (CKR_ARGUMENTS_BAD);
 320 
 321         /*
 322          * It is intentional that we don't forward the error code
 323          * returned from soft_keystore_pin_initialized() to the caller
 324          */
 325         pInfo->flags = SOFT_TOKEN_FLAGS;
 326         if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE) {
 327                 pInfo->flags |= CKF_WRITE_PROTECTED;
 328         } else {
 329                 if ((soft_keystore_pin_initialized(&pin_initialized,
 330                     &ks_cryptpin, B_FALSE) == CKR_OK) && !pin_initialized)
 331                         pInfo->flags |= CKF_USER_PIN_TO_BE_CHANGED;
 332         }
 333 
 334         if (ks_cryptpin)
 335                 free(ks_cryptpin);
 336 
 337         /* Provide information about a token in the provided buffer */
 338         (void) strncpy((char *)pInfo->label, SOFT_TOKEN_LABEL, 32);
 339         (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
 340         (void) strncpy((char *)pInfo->model, TOKEN_MODEL, 16);
 341         (void) strncpy((char *)pInfo->serialNumber, SOFT_TOKEN_SERIAL, 16);
 342 
 343         pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
 344         pInfo->ulSessionCount = soft_session_cnt;
 345         pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
 346         pInfo->ulRwSessionCount = soft_session_rw_cnt;
 347         pInfo->ulMaxPinLen = MAX_PIN_LEN;
 348         pInfo->ulMinPinLen = MIN_PIN_LEN;
 349         pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
 350         pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
 351         pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
 352         pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
 353         pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
 354         pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
 355         pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
 356         pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
 357         (void) memset(pInfo->utcTime, ' ', 16);
 358 
 359         return (CKR_OK);
 360 }
 361 
 362 /*ARGSUSED*/
 363 CK_RV
 364 C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
 365 {
 366         if (!softtoken_initialized)
 367                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 368 
 369         /*
 370          * This is currently not implemented, however we could cause this
 371          * to wait for the token files to appear if soft_token_present is
 372          * false.
 373          * However there is currently no polite and portable way to do that
 374          * because we might not even be able to get to an fd to the
 375          * parent directory, so instead we don't support any slot events.
 376          */
 377         return (CKR_FUNCTION_NOT_SUPPORTED);
 378 }
 379 
 380 
 381 CK_RV
 382 C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
 383     CK_ULONG_PTR pulCount)
 384 {
 385 
 386         ulong_t i;
 387         ulong_t mechnum;
 388 
 389         if (!softtoken_initialized)
 390                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 391 
 392         if (slotID != SOFTTOKEN_SLOTID)
 393                 return (CKR_SLOT_ID_INVALID);
 394 
 395         mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
 396 
 397         if (pMechanismList == NULL) {
 398                 /*
 399                  * Application only wants to know the number of
 400                  * supported mechanism types.
 401                  */
 402                 *pulCount = mechnum;
 403                 return (CKR_OK);
 404         }
 405 
 406         if (*pulCount < mechnum) {
 407                 *pulCount = mechnum;
 408                 return (CKR_BUFFER_TOO_SMALL);
 409         }
 410 
 411         for (i = 0; i < mechnum; i++) {
 412                 pMechanismList[i] = soft_mechanisms[i];
 413         }
 414 
 415         *pulCount = mechnum;
 416 
 417         return (CKR_OK);
 418 }
 419 
 420 
 421 CK_RV
 422 C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
 423     CK_MECHANISM_INFO_PTR pInfo)
 424 {
 425 
 426         ulong_t i;
 427         ulong_t mechnum;
 428 
 429         if (!softtoken_initialized)
 430                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 431 
 432         if (slotID != SOFTTOKEN_SLOTID)
 433                 return (CKR_SLOT_ID_INVALID);
 434 
 435         if (pInfo == NULL) {
 436                 return (CKR_ARGUMENTS_BAD);
 437         }
 438 
 439         mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
 440         for (i = 0; i < mechnum; i++) {
 441                 if (soft_mechanisms[i] == type)
 442                         break;
 443         }
 444 
 445         if (i == mechnum)
 446                 /* unsupported mechanism */
 447                 return (CKR_MECHANISM_INVALID);
 448 
 449         pInfo->ulMinKeySize = soft_mechanism_info[i].ulMinKeySize;
 450         pInfo->ulMaxKeySize = soft_mechanism_info[i].ulMaxKeySize;
 451         pInfo->flags = soft_mechanism_info[i].flags;
 452 
 453         return (CKR_OK);
 454 }
 455 
 456 
 457 /*ARGSUSED*/
 458 CK_RV
 459 C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
 460     CK_UTF8CHAR_PTR pLabel)
 461 {
 462         if (!softtoken_initialized)
 463                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 464 
 465         if (create_keystore() != 0)
 466                 return (CKR_FUNCTION_FAILED);
 467 
 468         return (CKR_OK);
 469 }
 470 
 471 /*ARGSUSED*/
 472 CK_RV
 473 C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
 474 {
 475         if (!softtoken_initialized)
 476                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 477 
 478         return (CKR_FUNCTION_NOT_SUPPORTED);
 479 }
 480 
 481 
 482 CK_RV
 483 C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
 484     CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
 485 {
 486 
 487         soft_session_t *session_p;
 488         CK_RV rv;
 489         boolean_t lock_held = B_FALSE;
 490 
 491         if (!softtoken_initialized)
 492                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 493 
 494         /*
 495          * Obtain the session pointer. Also, increment the session
 496          * reference count.
 497          */
 498         rv = handle2session(hSession, &session_p);
 499         if (rv != CKR_OK)
 500                 return (rv);
 501 
 502         if (!soft_keystore_status(KEYSTORE_LOAD)) {
 503                 SES_REFRELE(session_p, lock_held);
 504                 return (CKR_DEVICE_REMOVED);
 505         }
 506 
 507         if ((ulOldPinLen < MIN_PIN_LEN) || (ulOldPinLen > MAX_PIN_LEN) ||
 508             (ulNewPinLen < MIN_PIN_LEN) ||(ulNewPinLen > MAX_PIN_LEN)) {
 509                 SES_REFRELE(session_p, lock_held);
 510                 return (CKR_PIN_LEN_RANGE);
 511         }
 512 
 513         if ((pOldPin == NULL_PTR) || (pNewPin == NULL_PTR)) {
 514                 /*
 515                  * We don't support CKF_PROTECTED_AUTHENTICATION_PATH
 516                  */
 517                 SES_REFRELE(session_p, lock_held);
 518                 return (CKR_ARGUMENTS_BAD);
 519         }
 520 
 521         /* check the state of the session */
 522         if ((session_p->state != CKS_RW_PUBLIC_SESSION) &&
 523             (session_p->state != CKS_RW_USER_FUNCTIONS)) {
 524                 SES_REFRELE(session_p, lock_held);
 525                 return (CKR_SESSION_READ_ONLY);
 526         }
 527 
 528         rv = soft_setpin(pOldPin, ulOldPinLen, pNewPin, ulNewPinLen);
 529 
 530         SES_REFRELE(session_p, lock_held);
 531         return (rv);
 532 }