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