10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51937Sizick  * Common Development and Distribution License (the "License").
61937Sizick  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*12573SDina.Nimeh@Sun.COM 
220Sstevel@tonic-gate /*
2312256SPeter.Shoults@Sun.COM  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <strings.h>
270Sstevel@tonic-gate #include <cryptoutil.h>
280Sstevel@tonic-gate #include <security/cryptoki.h>
297188Smcpowers #include <sys/crypto/common.h>
300Sstevel@tonic-gate #include <arcfour.h>
310Sstevel@tonic-gate #include "softGlobal.h"
320Sstevel@tonic-gate #include "softSession.h"
330Sstevel@tonic-gate #include <aes_impl.h>
34676Sizick #include <blowfish_impl.h>
355697Smcpowers #include <des_impl.h>
365697Smcpowers #include <ecc_impl.h>
370Sstevel@tonic-gate #include "softDH.h"
380Sstevel@tonic-gate #include "softObject.h"
390Sstevel@tonic-gate #include "softKeystore.h"
400Sstevel@tonic-gate #include "softKeystoreUtil.h"
410Sstevel@tonic-gate 
420Sstevel@tonic-gate 
430Sstevel@tonic-gate static CK_MECHANISM_TYPE soft_mechanisms[] = {
440Sstevel@tonic-gate 	CKM_DES_CBC,
450Sstevel@tonic-gate 	CKM_DES_CBC_PAD,
460Sstevel@tonic-gate 	CKM_DES_ECB,
470Sstevel@tonic-gate 	CKM_DES_KEY_GEN,
480Sstevel@tonic-gate 	CKM_DES_MAC_GENERAL,
490Sstevel@tonic-gate 	CKM_DES_MAC,
500Sstevel@tonic-gate 	CKM_DES3_CBC,
510Sstevel@tonic-gate 	CKM_DES3_CBC_PAD,
520Sstevel@tonic-gate 	CKM_DES3_ECB,
5310444SVladimir.Kotal@Sun.COM 	CKM_DES2_KEY_GEN,
540Sstevel@tonic-gate 	CKM_DES3_KEY_GEN,
550Sstevel@tonic-gate 	CKM_AES_CBC,
560Sstevel@tonic-gate 	CKM_AES_CBC_PAD,
577188Smcpowers 	CKM_AES_CTR,
580Sstevel@tonic-gate 	CKM_AES_ECB,
590Sstevel@tonic-gate 	CKM_AES_KEY_GEN,
60676Sizick 	CKM_BLOWFISH_CBC,
61676Sizick 	CKM_BLOWFISH_KEY_GEN,
620Sstevel@tonic-gate 	CKM_SHA_1,
630Sstevel@tonic-gate 	CKM_SHA_1_HMAC,
640Sstevel@tonic-gate 	CKM_SHA_1_HMAC_GENERAL,
65676Sizick 	CKM_SHA256,
66676Sizick 	CKM_SHA256_HMAC,
67676Sizick 	CKM_SHA256_HMAC_GENERAL,
68676Sizick 	CKM_SHA384,
69676Sizick 	CKM_SHA384_HMAC,
70676Sizick 	CKM_SHA384_HMAC_GENERAL,
71676Sizick 	CKM_SHA512,
72676Sizick 	CKM_SHA512_HMAC,
73676Sizick 	CKM_SHA512_HMAC_GENERAL,
740Sstevel@tonic-gate 	CKM_SSL3_SHA1_MAC,
750Sstevel@tonic-gate 	CKM_MD5,
760Sstevel@tonic-gate 	CKM_MD5_HMAC,
770Sstevel@tonic-gate 	CKM_MD5_HMAC_GENERAL,
780Sstevel@tonic-gate 	CKM_SSL3_MD5_MAC,
790Sstevel@tonic-gate 	CKM_RC4,
800Sstevel@tonic-gate 	CKM_RC4_KEY_GEN,
810Sstevel@tonic-gate 	CKM_DSA,
820Sstevel@tonic-gate 	CKM_DSA_SHA1,
830Sstevel@tonic-gate 	CKM_DSA_KEY_PAIR_GEN,
840Sstevel@tonic-gate 	CKM_RSA_PKCS,
850Sstevel@tonic-gate 	CKM_RSA_PKCS_KEY_PAIR_GEN,
860Sstevel@tonic-gate 	CKM_RSA_X_509,
870Sstevel@tonic-gate 	CKM_MD5_RSA_PKCS,
880Sstevel@tonic-gate 	CKM_SHA1_RSA_PKCS,
89676Sizick 	CKM_SHA256_RSA_PKCS,
90676Sizick 	CKM_SHA384_RSA_PKCS,
91676Sizick 	CKM_SHA512_RSA_PKCS,
920Sstevel@tonic-gate 	CKM_DH_PKCS_KEY_PAIR_GEN,
930Sstevel@tonic-gate 	CKM_DH_PKCS_DERIVE,
940Sstevel@tonic-gate 	CKM_MD5_KEY_DERIVATION,
950Sstevel@tonic-gate 	CKM_SHA1_KEY_DERIVATION,
96676Sizick 	CKM_SHA256_KEY_DERIVATION,
97676Sizick 	CKM_SHA384_KEY_DERIVATION,
98676Sizick 	CKM_SHA512_KEY_DERIVATION,
990Sstevel@tonic-gate 	CKM_PBE_SHA1_RC4_128,
1000Sstevel@tonic-gate 	CKM_PKCS5_PBKD2,
1010Sstevel@tonic-gate 	CKM_SSL3_PRE_MASTER_KEY_GEN,
1020Sstevel@tonic-gate 	CKM_TLS_PRE_MASTER_KEY_GEN,
1030Sstevel@tonic-gate 	CKM_SSL3_MASTER_KEY_DERIVE,
1040Sstevel@tonic-gate 	CKM_TLS_MASTER_KEY_DERIVE,
1050Sstevel@tonic-gate 	CKM_SSL3_MASTER_KEY_DERIVE_DH,
1060Sstevel@tonic-gate 	CKM_TLS_MASTER_KEY_DERIVE_DH,
1070Sstevel@tonic-gate 	CKM_SSL3_KEY_AND_MAC_DERIVE,
108872Sizick 	CKM_TLS_KEY_AND_MAC_DERIVE,
1095697Smcpowers 	CKM_TLS_PRF,
1105697Smcpowers 	CKM_EC_KEY_PAIR_GEN,
1115697Smcpowers 	CKM_ECDSA,
1125697Smcpowers 	CKM_ECDSA_SHA1,
1135697Smcpowers 	CKM_ECDH1_DERIVE
1140Sstevel@tonic-gate };
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate /*
1170Sstevel@tonic-gate  * This is the table of CK_MECHANISM_INFO structs for the supported mechanisms.
1180Sstevel@tonic-gate  * The index for this table is the same as the one above for the same
1190Sstevel@tonic-gate  * mechanism.
1200Sstevel@tonic-gate  * The minimum and maximum sizes of the key for the mechanism can be measured
1210Sstevel@tonic-gate  * in bits or in bytes (i.e. mechanism-dependent). This table specifies the
1220Sstevel@tonic-gate  * supported range of key sizes in bytes; unless noted as in bits.
1230Sstevel@tonic-gate  */
1240Sstevel@tonic-gate static CK_MECHANISM_INFO soft_mechanism_info[] = {
1250Sstevel@tonic-gate 	{DES_MINBYTES, DES_MAXBYTES,
1260Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1270Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES_CBC */
1280Sstevel@tonic-gate 	{DES_MINBYTES, DES_MAXBYTES,
1290Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1300Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES_CBC_PAD */
1310Sstevel@tonic-gate 	{DES_MINBYTES, DES_MAXBYTES,
1320Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1330Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES_ECB */
1340Sstevel@tonic-gate 	{DES_MINBYTES, DES_MAXBYTES,
1350Sstevel@tonic-gate 		CKF_GENERATE},			/* CKM_DES_KEY_GEN */
1360Sstevel@tonic-gate 	{DES_MINBYTES, DES_MAXBYTES,
1370Sstevel@tonic-gate 		CKF_SIGN|CKF_VERIFY},		/* CKM_DES_MAC_GENERAL */
1380Sstevel@tonic-gate 	{DES_MINBYTES, DES_MAXBYTES,
1390Sstevel@tonic-gate 		CKF_SIGN|CKF_VERIFY},		/* CKM_DES_MAC */
1400Sstevel@tonic-gate 	{DES3_MINBYTES, DES3_MAXBYTES,
1410Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1420Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES3_CBC */
1430Sstevel@tonic-gate 	{DES3_MINBYTES, DES3_MAXBYTES,
1440Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1450Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES3_CBC_PAD */
1460Sstevel@tonic-gate 	{DES3_MINBYTES, DES3_MAXBYTES,
1470Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1480Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES3_ECB */
14910444SVladimir.Kotal@Sun.COM 	{DES2_MAXBYTES, DES2_MAXBYTES,
15010444SVladimir.Kotal@Sun.COM 		CKF_GENERATE},			/* CKM_DES2_KEY_GEN */
15110444SVladimir.Kotal@Sun.COM 	{DES3_MAXBYTES, DES3_MAXBYTES,		/* CKK_DES3 only */
1520Sstevel@tonic-gate 		CKF_GENERATE},			/* CKM_DES3_KEY_GEN */
1530Sstevel@tonic-gate 	{AES_MINBYTES, AES_MAXBYTES,
1540Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1550Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_CBC */
1560Sstevel@tonic-gate 	{AES_MINBYTES, AES_MAXBYTES,
1570Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1580Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_CBC_PAD */
1590Sstevel@tonic-gate 	{AES_MINBYTES, AES_MAXBYTES,
1600Sstevel@tonic-gate 		CKF_ENCRYPT|CKF_DECRYPT|
1617188Smcpowers 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_CTR */
1627188Smcpowers 	{AES_MINBYTES, AES_MAXBYTES,
1637188Smcpowers 		CKF_ENCRYPT|CKF_DECRYPT|
1640Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_ECB */
1650Sstevel@tonic-gate 	{AES_MINBYTES, AES_MAXBYTES,
1660Sstevel@tonic-gate 		CKF_GENERATE},			/* CKM_AES_KEY_GEN */
167676Sizick 	{BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
168676Sizick 		CKF_ENCRYPT|CKF_DECRYPT|
169676Sizick 		CKF_WRAP|CKF_UNWRAP},		/* CKM_BLOWFISH_ECB */
170676Sizick 	{BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
171676Sizick 		CKF_GENERATE},			/* CKM_BLOWFISH_KEY_GEN */
1720Sstevel@tonic-gate 	{0, 0, CKF_DIGEST},			/* CKM_SHA_1 */
1730Sstevel@tonic-gate 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA_1_HMAC */
1740Sstevel@tonic-gate 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA_1_HMAC_GENERAL */
175676Sizick 	{0, 0, CKF_DIGEST},			/* CKM_SHA256 */
176676Sizick 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA256_HMAC */
177676Sizick 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA256_HMAC_GENERAL */
178676Sizick 	{0, 0, CKF_DIGEST},			/* CKM_SHA384 */
179676Sizick 	{1, 128, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA384_HMAC */
180676Sizick 	{1, 128, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA384_HMAC_GENERAL */
181676Sizick 	{0, 0, CKF_DIGEST},			/* CKM_SHA512 */
182676Sizick 	{1, 128, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA512_HMAC */
183676Sizick 	{1, 128, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA512_HMAC_GENERAL */
1840Sstevel@tonic-gate 	{1, 512, CKF_SIGN|CKF_VERIFY},		/* CKM_SSL3_SHA1_MAC */
1850Sstevel@tonic-gate 	{0, 0, CKF_DIGEST},			/* CKM_MD5 */
1860Sstevel@tonic-gate 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_MD5_HMAC */
1870Sstevel@tonic-gate 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_MD5_HMAC_GENERAL */
1880Sstevel@tonic-gate 	{1, 512, CKF_SIGN|CKF_VERIFY},		/* CKM_SSL3_MD5_MAC */
1890Sstevel@tonic-gate 	{8, ARCFOUR_MAX_KEY_BITS, CKF_ENCRYPT|CKF_DECRYPT}, /* CKM_RC4; */
1900Sstevel@tonic-gate 							    /* in bits  */
1910Sstevel@tonic-gate 	{8, ARCFOUR_MAX_KEY_BITS, CKF_GENERATE }, /* CKM_RC4_KEY_GEN; in bits */
1920Sstevel@tonic-gate 	{512, 1024, CKF_SIGN|CKF_VERIFY},	/* CKM_DSA; in bits */
1930Sstevel@tonic-gate 	{512, 1024, CKF_SIGN|CKF_VERIFY},	/* CKM_DSA_SHA1; in bits */
1940Sstevel@tonic-gate 	{512, 1024, CKF_GENERATE_KEY_PAIR},	/* CKM_DSA_KEY_PAIR_GEN; */
1950Sstevel@tonic-gate 						/* in bits */
1960Sstevel@tonic-gate 	{256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
1970Sstevel@tonic-gate 		CKF_SIGN|CKF_SIGN_RECOVER|
1980Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP|
1990Sstevel@tonic-gate 		CKF_VERIFY|CKF_VERIFY_RECOVER},	/* CKM_RSA_PKCS; in bits */
2000Sstevel@tonic-gate 	{256, 4096, CKF_GENERATE_KEY_PAIR},	/* CKM_RSA_PKCS_KEY_PAIR_GEN; */
2010Sstevel@tonic-gate 						/* in bits */
2020Sstevel@tonic-gate 	{256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
2030Sstevel@tonic-gate 		CKF_SIGN|CKF_SIGN_RECOVER|
2040Sstevel@tonic-gate 		CKF_WRAP|CKF_UNWRAP|
2050Sstevel@tonic-gate 		CKF_VERIFY|CKF_VERIFY_RECOVER},	/* CKM_RSA_X_509 in bits */
2060Sstevel@tonic-gate 	{256, 4096, CKF_SIGN|CKF_VERIFY},	/* CKM_MD5_RSA_PKCS in bits */
2070Sstevel@tonic-gate 	{256, 4096, CKF_SIGN|CKF_VERIFY},	/* CKM_SHA1_RSA_PKCS in bits */
208676Sizick 	{256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_RSA_PKCS in bits */
209676Sizick 	{256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_RSA_PKCS in bits */
210676Sizick 	{256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_RSA_PKCS in bits */
211*12573SDina.Nimeh@Sun.COM 	{DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
2120Sstevel@tonic-gate 						/* CKM_DH_PKCS_KEY_PAIR_GEN */
2130Sstevel@tonic-gate 						/* in bits */
214*12573SDina.Nimeh@Sun.COM 	{DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_DERIVE},
2150Sstevel@tonic-gate 						/* CKM_DH_PKCS_DERIVE; */
2160Sstevel@tonic-gate 						/* in bits */
2170Sstevel@tonic-gate 	{1, 16, CKF_DERIVE},			/* CKM_MD5_KEY_DERIVATION */
2180Sstevel@tonic-gate 	{1, 20, CKF_DERIVE},			/* CKM_SHA1_KEY_DERIVATION */
219676Sizick 	{1, 32, CKF_DERIVE},			/* CKM_SHA256_KEY_DERIVATION */
220676Sizick 	{1, 48, CKF_DERIVE},			/* CKM_SHA384_KEY_DERIVATION */
221676Sizick 	{1, 64, CKF_DERIVE},			/* CKM_SHA512_KEY_DERIVATION */
2220Sstevel@tonic-gate 	{0, 0, CKF_GENERATE},			/* CKM_PBE_SHA1_RC4_128 */
2230Sstevel@tonic-gate 	{0, 0, CKF_GENERATE},			/* CKM_PKCS5_PBKD2 */
2240Sstevel@tonic-gate 	{48, 48, CKF_GENERATE},		/* CKM_SSL3_PRE_MASTER_KEY_GEN */
2250Sstevel@tonic-gate 	{48, 48, CKF_GENERATE},		/* CKM_TLS_PRE_MASTER_KEY_GEN */
2260Sstevel@tonic-gate 	{48, 48, CKF_DERIVE},		/* CKM_SSL3_MASTER_KEY_DERIVE */
2270Sstevel@tonic-gate 	{48, 48, CKF_DERIVE},		/* CKM_TLS_MASTER_KEY_DERIVE */
2280Sstevel@tonic-gate 	{48, 48, CKF_DERIVE},		/* CKM_SSL3_MASTER_KEY_DERIVE_DH */
2290Sstevel@tonic-gate 	{48, 48, CKF_DERIVE},		/* CKM_TLS_MASTER_KEY_DERIVE_DH */
2300Sstevel@tonic-gate 	{0, 0, CKF_DERIVE},		/* CKM_SSL3_KEY_AND_MAC_DERIVE */
231872Sizick 	{0, 0, CKF_DERIVE},		/* CKM_TLS_KEY_AND_MAC_DERIVE */
2325697Smcpowers 	{0, 0, CKF_DERIVE},		/* CKM_TLS_PRF */
2335697Smcpowers 	{EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
2345697Smcpowers 	{EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
2355697Smcpowers 	{EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
2365697Smcpowers 	{EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_DERIVE}
2370Sstevel@tonic-gate };
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate /*
2400Sstevel@tonic-gate  * Slot ID for softtoken is always 1. tokenPresent is ignored.
2410Sstevel@tonic-gate  * Also, only one slot is used.
2420Sstevel@tonic-gate  */
2430Sstevel@tonic-gate /*ARGSUSED*/
2440Sstevel@tonic-gate CK_RV
C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)2450Sstevel@tonic-gate C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
2460Sstevel@tonic-gate     CK_ULONG_PTR pulCount)
2470Sstevel@tonic-gate {
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	CK_RV rv;
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	if (!softtoken_initialized)
2520Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	if (pulCount == NULL) {
2550Sstevel@tonic-gate 		return (CKR_ARGUMENTS_BAD);
2560Sstevel@tonic-gate 	}
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 	if (pSlotList == NULL) {
2590Sstevel@tonic-gate 		/*
2600Sstevel@tonic-gate 		 * Application only wants to know the number of slots.
2610Sstevel@tonic-gate 		 */
2620Sstevel@tonic-gate 		*pulCount = 1;
2630Sstevel@tonic-gate 		return (CKR_OK);
2640Sstevel@tonic-gate 	}
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 	if ((*pulCount < 1) && (pSlotList != NULL)) {
2670Sstevel@tonic-gate 		rv = CKR_BUFFER_TOO_SMALL;
2680Sstevel@tonic-gate 	} else {
2690Sstevel@tonic-gate 		pSlotList[0] = SOFTTOKEN_SLOTID;
2700Sstevel@tonic-gate 		rv = CKR_OK;
2710Sstevel@tonic-gate 	}
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate 	*pulCount = 1;
2740Sstevel@tonic-gate 	return (rv);
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate CK_RV
C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)2790Sstevel@tonic-gate C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
2800Sstevel@tonic-gate {
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	if (!softtoken_initialized)
2830Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 	if (pInfo == NULL)
2860Sstevel@tonic-gate 		return (CKR_ARGUMENTS_BAD);
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 	/* Make sure the slot ID is valid */
2890Sstevel@tonic-gate 	if (slotID != SOFTTOKEN_SLOTID)
2900Sstevel@tonic-gate 		return (CKR_SLOT_ID_INVALID);
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate 	/* Provide information about the slot in the provided buffer */
2930Sstevel@tonic-gate 	(void) strncpy((char *)pInfo->slotDescription, SOFT_SLOT_DESCRIPTION,
2940Sstevel@tonic-gate 	    64);
2950Sstevel@tonic-gate 	(void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
2968732SAnthony.Scarpino@Sun.COM 	pInfo->flags = CKF_TOKEN_PRESENT;
2970Sstevel@tonic-gate 	pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
2980Sstevel@tonic-gate 	pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
2990Sstevel@tonic-gate 	pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
3000Sstevel@tonic-gate 	pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	return (CKR_OK);
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate CK_RV
C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)3060Sstevel@tonic-gate C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
3070Sstevel@tonic-gate {
30812517SPeter.Shoults@Sun.COM 	boolean_t pin_initialized = B_FALSE;
30912517SPeter.Shoults@Sun.COM 	char	*ks_cryptpin = NULL;
31012517SPeter.Shoults@Sun.COM 
3110Sstevel@tonic-gate 	if (!softtoken_initialized)
3120Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	/* Make sure the slot ID is valid */
3150Sstevel@tonic-gate 	if (slotID != SOFTTOKEN_SLOTID)
3160Sstevel@tonic-gate 		return (CKR_SLOT_ID_INVALID);
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate 	if (pInfo == NULL)
3190Sstevel@tonic-gate 		return (CKR_ARGUMENTS_BAD);
3200Sstevel@tonic-gate 
32112517SPeter.Shoults@Sun.COM 	/*
32212517SPeter.Shoults@Sun.COM 	 * It is intentional that we don't forward the error code
32312517SPeter.Shoults@Sun.COM 	 * returned from soft_keystore_pin_initialized() to the caller
32412517SPeter.Shoults@Sun.COM 	 */
32512256SPeter.Shoults@Sun.COM 	pInfo->flags = SOFT_TOKEN_FLAGS;
32612256SPeter.Shoults@Sun.COM 	if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE) {
32712256SPeter.Shoults@Sun.COM 		pInfo->flags |= CKF_WRITE_PROTECTED;
32812517SPeter.Shoults@Sun.COM 	} else {
32912517SPeter.Shoults@Sun.COM 		if ((soft_keystore_pin_initialized(&pin_initialized,
33012517SPeter.Shoults@Sun.COM 		    &ks_cryptpin, B_FALSE) == CKR_OK) && !pin_initialized)
33112517SPeter.Shoults@Sun.COM 			pInfo->flags |= CKF_USER_PIN_TO_BE_CHANGED;
33212256SPeter.Shoults@Sun.COM 	}
33312517SPeter.Shoults@Sun.COM 
33412517SPeter.Shoults@Sun.COM 	if (ks_cryptpin)
33512517SPeter.Shoults@Sun.COM 		free(ks_cryptpin);
33612517SPeter.Shoults@Sun.COM 
3370Sstevel@tonic-gate 	/* Provide information about a token in the provided buffer */
3380Sstevel@tonic-gate 	(void) strncpy((char *)pInfo->label, SOFT_TOKEN_LABEL, 32);
3390Sstevel@tonic-gate 	(void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
3400Sstevel@tonic-gate 	(void) strncpy((char *)pInfo->model, TOKEN_MODEL, 16);
3410Sstevel@tonic-gate 	(void) strncpy((char *)pInfo->serialNumber, SOFT_TOKEN_SERIAL, 16);
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 	pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
3440Sstevel@tonic-gate 	pInfo->ulSessionCount = soft_session_cnt;
3450Sstevel@tonic-gate 	pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
3460Sstevel@tonic-gate 	pInfo->ulRwSessionCount = soft_session_rw_cnt;
3470Sstevel@tonic-gate 	pInfo->ulMaxPinLen = MAX_PIN_LEN;
3480Sstevel@tonic-gate 	pInfo->ulMinPinLen = MIN_PIN_LEN;
3490Sstevel@tonic-gate 	pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
3500Sstevel@tonic-gate 	pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
3510Sstevel@tonic-gate 	pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
3520Sstevel@tonic-gate 	pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
3530Sstevel@tonic-gate 	pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
3540Sstevel@tonic-gate 	pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
3550Sstevel@tonic-gate 	pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
3560Sstevel@tonic-gate 	pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
3570Sstevel@tonic-gate 	(void) memset(pInfo->utcTime, ' ', 16);
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 	return (CKR_OK);
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate /*ARGSUSED*/
3630Sstevel@tonic-gate CK_RV
C_WaitForSlotEvent(CK_FLAGS flags,CK_SLOT_ID_PTR pSlot,CK_VOID_PTR pReserved)3640Sstevel@tonic-gate C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
3650Sstevel@tonic-gate {
3660Sstevel@tonic-gate 	if (!softtoken_initialized)
3670Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 	/*
3700Sstevel@tonic-gate 	 * This is currently not implemented, however we could cause this
3710Sstevel@tonic-gate 	 * to wait for the token files to appear if soft_token_present is
3720Sstevel@tonic-gate 	 * false.
3730Sstevel@tonic-gate 	 * However there is currently no polite and portable way to do that
3740Sstevel@tonic-gate 	 * because we might not even be able to get to an fd to the
3750Sstevel@tonic-gate 	 * parent directory, so instead we don't support any slot events.
3760Sstevel@tonic-gate 	 */
3770Sstevel@tonic-gate 	return (CKR_FUNCTION_NOT_SUPPORTED);
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate CK_RV
C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)3820Sstevel@tonic-gate C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
3830Sstevel@tonic-gate     CK_ULONG_PTR pulCount)
3840Sstevel@tonic-gate {
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate 	ulong_t i;
3870Sstevel@tonic-gate 	ulong_t mechnum;
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate 	if (!softtoken_initialized)
3900Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate 	if (slotID != SOFTTOKEN_SLOTID)
3930Sstevel@tonic-gate 		return (CKR_SLOT_ID_INVALID);
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 	mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	if (pMechanismList == NULL) {
3980Sstevel@tonic-gate 		/*
3990Sstevel@tonic-gate 		 * Application only wants to know the number of
4000Sstevel@tonic-gate 		 * supported mechanism types.
4010Sstevel@tonic-gate 		 */
4020Sstevel@tonic-gate 		*pulCount = mechnum;
4030Sstevel@tonic-gate 		return (CKR_OK);
4040Sstevel@tonic-gate 	}
4050Sstevel@tonic-gate 
4060Sstevel@tonic-gate 	if (*pulCount < mechnum) {
4070Sstevel@tonic-gate 		*pulCount = mechnum;
4080Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
4090Sstevel@tonic-gate 	}
4100Sstevel@tonic-gate 
4110Sstevel@tonic-gate 	for (i = 0; i < mechnum; i++) {
4120Sstevel@tonic-gate 		pMechanismList[i] = soft_mechanisms[i];
4130Sstevel@tonic-gate 	}
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 	*pulCount = mechnum;
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	return (CKR_OK);
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate CK_RV
C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)4220Sstevel@tonic-gate C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
4230Sstevel@tonic-gate     CK_MECHANISM_INFO_PTR pInfo)
4240Sstevel@tonic-gate {
4250Sstevel@tonic-gate 
4260Sstevel@tonic-gate 	ulong_t i;
4270Sstevel@tonic-gate 	ulong_t mechnum;
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	if (!softtoken_initialized)
4300Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate 	if (slotID != SOFTTOKEN_SLOTID)
4330Sstevel@tonic-gate 		return (CKR_SLOT_ID_INVALID);
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 	if (pInfo == NULL) {
4360Sstevel@tonic-gate 		return (CKR_ARGUMENTS_BAD);
4370Sstevel@tonic-gate 	}
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate 	mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
4400Sstevel@tonic-gate 	for (i = 0; i < mechnum; i++) {
4410Sstevel@tonic-gate 		if (soft_mechanisms[i] == type)
4420Sstevel@tonic-gate 			break;
4430Sstevel@tonic-gate 	}
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	if (i == mechnum)
4460Sstevel@tonic-gate 		/* unsupported mechanism */
4470Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	pInfo->ulMinKeySize = soft_mechanism_info[i].ulMinKeySize;
4500Sstevel@tonic-gate 	pInfo->ulMaxKeySize = soft_mechanism_info[i].ulMaxKeySize;
4510Sstevel@tonic-gate 	pInfo->flags = soft_mechanism_info[i].flags;
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 	return (CKR_OK);
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate /*ARGSUSED*/
4580Sstevel@tonic-gate CK_RV
C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)4590Sstevel@tonic-gate C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
4600Sstevel@tonic-gate     CK_UTF8CHAR_PTR pLabel)
4610Sstevel@tonic-gate {
4620Sstevel@tonic-gate 	if (!softtoken_initialized)
4630Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
4640Sstevel@tonic-gate 
46512256SPeter.Shoults@Sun.COM 	if (create_keystore() != 0)
46612256SPeter.Shoults@Sun.COM 		return (CKR_FUNCTION_FAILED);
46712256SPeter.Shoults@Sun.COM 
46812256SPeter.Shoults@Sun.COM 	return (CKR_OK);
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate /*ARGSUSED*/
4720Sstevel@tonic-gate CK_RV
C_InitPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)4730Sstevel@tonic-gate C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
4740Sstevel@tonic-gate {
4750Sstevel@tonic-gate 	if (!softtoken_initialized)
4760Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 	return (CKR_FUNCTION_NOT_SUPPORTED);
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate 
4820Sstevel@tonic-gate CK_RV
C_SetPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pOldPin,CK_ULONG ulOldPinLen,CK_UTF8CHAR_PTR pNewPin,CK_ULONG ulNewPinLen)4830Sstevel@tonic-gate C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
4840Sstevel@tonic-gate     CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
4850Sstevel@tonic-gate {
4860Sstevel@tonic-gate 
4870Sstevel@tonic-gate 	soft_session_t *session_p;
4880Sstevel@tonic-gate 	CK_RV rv;
4890Sstevel@tonic-gate 	boolean_t lock_held = B_FALSE;
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 	if (!softtoken_initialized)
4920Sstevel@tonic-gate 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 	/*
4950Sstevel@tonic-gate 	 * Obtain the session pointer. Also, increment the session
4960Sstevel@tonic-gate 	 * reference count.
4970Sstevel@tonic-gate 	 */
4980Sstevel@tonic-gate 	rv = handle2session(hSession, &session_p);
4990Sstevel@tonic-gate 	if (rv != CKR_OK)
5000Sstevel@tonic-gate 		return (rv);
5010Sstevel@tonic-gate 
50212256SPeter.Shoults@Sun.COM 	if (!soft_keystore_status(KEYSTORE_LOAD)) {
5030Sstevel@tonic-gate 		SES_REFRELE(session_p, lock_held);
5040Sstevel@tonic-gate 		return (CKR_DEVICE_REMOVED);
5050Sstevel@tonic-gate 	}
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate 	if ((ulOldPinLen < MIN_PIN_LEN) || (ulOldPinLen > MAX_PIN_LEN) ||
5080Sstevel@tonic-gate 	    (ulNewPinLen < MIN_PIN_LEN) ||(ulNewPinLen > MAX_PIN_LEN)) {
5090Sstevel@tonic-gate 		SES_REFRELE(session_p, lock_held);
5100Sstevel@tonic-gate 		return (CKR_PIN_LEN_RANGE);
5110Sstevel@tonic-gate 	}
5120Sstevel@tonic-gate 
5130Sstevel@tonic-gate 	if ((pOldPin == NULL_PTR) || (pNewPin == NULL_PTR)) {
5140Sstevel@tonic-gate 		/*
5150Sstevel@tonic-gate 		 * We don't support CKF_PROTECTED_AUTHENTICATION_PATH
5160Sstevel@tonic-gate 		 */
5170Sstevel@tonic-gate 		SES_REFRELE(session_p, lock_held);
5180Sstevel@tonic-gate 		return (CKR_ARGUMENTS_BAD);
5190Sstevel@tonic-gate 	}
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	/* check the state of the session */
5220Sstevel@tonic-gate 	if ((session_p->state != CKS_RW_PUBLIC_SESSION) &&
5230Sstevel@tonic-gate 	    (session_p->state != CKS_RW_USER_FUNCTIONS)) {
5240Sstevel@tonic-gate 		SES_REFRELE(session_p, lock_held);
5250Sstevel@tonic-gate 		return (CKR_SESSION_READ_ONLY);
5260Sstevel@tonic-gate 	}
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 	rv = soft_setpin(pOldPin, ulOldPinLen, pNewPin, ulNewPinLen);
5290Sstevel@tonic-gate 
5300Sstevel@tonic-gate 	SES_REFRELE(session_p, lock_held);
5310Sstevel@tonic-gate 	return (rv);
5320Sstevel@tonic-gate }
533