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