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