xref: /titanic_51/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c (revision bdfc6d18da790deeec2e0eb09c625902defe2498)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <strings.h>
30 #include <cryptoutil.h>
31 #include <security/cryptoki.h>
32 #include <arcfour.h>
33 #include "softGlobal.h"
34 #include "softSession.h"
35 #include <des_impl.h>
36 #include <aes_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_DES3_KEY_GEN,
54 	CKM_AES_CBC,
55 	CKM_AES_CBC_PAD,
56 	CKM_AES_ECB,
57 	CKM_AES_KEY_GEN,
58 	CKM_SHA_1,
59 	CKM_SHA_1_HMAC,
60 	CKM_SHA_1_HMAC_GENERAL,
61 	CKM_SSL3_SHA1_MAC,
62 	CKM_MD5,
63 	CKM_MD5_HMAC,
64 	CKM_MD5_HMAC_GENERAL,
65 	CKM_SSL3_MD5_MAC,
66 	CKM_RC4,
67 	CKM_RC4_KEY_GEN,
68 	CKM_DSA,
69 	CKM_DSA_SHA1,
70 	CKM_DSA_KEY_PAIR_GEN,
71 	CKM_RSA_PKCS,
72 	CKM_RSA_PKCS_KEY_PAIR_GEN,
73 	CKM_RSA_X_509,
74 	CKM_MD5_RSA_PKCS,
75 	CKM_SHA1_RSA_PKCS,
76 	CKM_DH_PKCS_KEY_PAIR_GEN,
77 	CKM_DH_PKCS_DERIVE,
78 	CKM_MD5_KEY_DERIVATION,
79 	CKM_SHA1_KEY_DERIVATION,
80 	CKM_PBE_SHA1_RC4_128,
81 	CKM_PKCS5_PBKD2,
82 	CKM_SSL3_PRE_MASTER_KEY_GEN,
83 	CKM_TLS_PRE_MASTER_KEY_GEN,
84 	CKM_SSL3_MASTER_KEY_DERIVE,
85 	CKM_TLS_MASTER_KEY_DERIVE,
86 	CKM_SSL3_MASTER_KEY_DERIVE_DH,
87 	CKM_TLS_MASTER_KEY_DERIVE_DH,
88 	CKM_SSL3_KEY_AND_MAC_DERIVE,
89 	CKM_TLS_KEY_AND_MAC_DERIVE
90 };
91 
92 /*
93  * This is the table of CK_MECHANISM_INFO structs for the supported mechanisms.
94  * The index for this table is the same as the one above for the same
95  * mechanism.
96  * The minimum and maximum sizes of the key for the mechanism can be measured
97  * in bits or in bytes (i.e. mechanism-dependent). This table specifies the
98  * supported range of key sizes in bytes; unless noted as in bits.
99  */
100 static CK_MECHANISM_INFO soft_mechanism_info[] = {
101 	{DES_MINBYTES, DES_MAXBYTES,
102 		CKF_ENCRYPT|CKF_DECRYPT|
103 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES_CBC */
104 	{DES_MINBYTES, DES_MAXBYTES,
105 		CKF_ENCRYPT|CKF_DECRYPT|
106 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES_CBC_PAD */
107 	{DES_MINBYTES, DES_MAXBYTES,
108 		CKF_ENCRYPT|CKF_DECRYPT|
109 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES_ECB */
110 	{DES_MINBYTES, DES_MAXBYTES,
111 		CKF_GENERATE},			/* CKM_DES_KEY_GEN */
112 	{DES_MINBYTES, DES_MAXBYTES,
113 		CKF_SIGN|CKF_VERIFY},		/* CKM_DES_MAC_GENERAL */
114 	{DES_MINBYTES, DES_MAXBYTES,
115 		CKF_SIGN|CKF_VERIFY},		/* CKM_DES_MAC */
116 /*
117  * Note that DES3 is allowed even if CRYPTO_UNLIMITED is not specified.
118  * This is because 3DES has an exception to the Solaris PAC enforced
119  * no crypto greater than 128 bit in core Solaris rule.
120  * The actual key length of 3DES is 192, but most cryptographers regard
121  * it to be effectively 112.
122  */
123 	{DES3_MINBYTES, DES3_MAXBYTES,
124 		CKF_ENCRYPT|CKF_DECRYPT|
125 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES3_CBC */
126 	{DES3_MINBYTES, DES3_MAXBYTES,
127 		CKF_ENCRYPT|CKF_DECRYPT|
128 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES3_CBC_PAD */
129 	{DES3_MINBYTES, DES3_MAXBYTES,
130 		CKF_ENCRYPT|CKF_DECRYPT|
131 		CKF_WRAP|CKF_UNWRAP},		/* CKM_DES3_ECB */
132 	{DES3_MINBYTES, DES3_MAXBYTES,
133 		CKF_GENERATE},			/* CKM_DES3_KEY_GEN */
134 	{AES_MINBYTES, AES_MAXBYTES,
135 		CKF_ENCRYPT|CKF_DECRYPT|
136 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_CBC */
137 	{AES_MINBYTES, AES_MAXBYTES,
138 		CKF_ENCRYPT|CKF_DECRYPT|
139 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_CBC_PAD */
140 	{AES_MINBYTES, AES_MAXBYTES,
141 		CKF_ENCRYPT|CKF_DECRYPT|
142 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_ECB */
143 	{AES_MINBYTES, AES_MAXBYTES,
144 		CKF_GENERATE},			/* CKM_AES_KEY_GEN */
145 	{0, 0, CKF_DIGEST},			/* CKM_SHA_1 */
146 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA_1_HMAC */
147 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_SHA_1_HMAC_GENERAL */
148 	{1, 512, CKF_SIGN|CKF_VERIFY},		/* CKM_SSL3_SHA1_MAC */
149 	{0, 0, CKF_DIGEST},			/* CKM_MD5 */
150 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_MD5_HMAC */
151 	{1, 64, CKF_SIGN|CKF_VERIFY},		/* CKM_MD5_HMAC_GENERAL */
152 	{1, 512, CKF_SIGN|CKF_VERIFY},		/* CKM_SSL3_MD5_MAC */
153 	{8, ARCFOUR_MAX_KEY_BITS, CKF_ENCRYPT|CKF_DECRYPT}, /* CKM_RC4; */
154 							    /* in bits  */
155 	{8, ARCFOUR_MAX_KEY_BITS, CKF_GENERATE }, /* CKM_RC4_KEY_GEN; in bits */
156 	{512, 1024, CKF_SIGN|CKF_VERIFY},	/* CKM_DSA; in bits */
157 	{512, 1024, CKF_SIGN|CKF_VERIFY},	/* CKM_DSA_SHA1; in bits */
158 	{512, 1024, CKF_GENERATE_KEY_PAIR},	/* CKM_DSA_KEY_PAIR_GEN; */
159 						/* in bits */
160 	{256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
161 		CKF_SIGN|CKF_SIGN_RECOVER|
162 		CKF_WRAP|CKF_UNWRAP|
163 		CKF_VERIFY|CKF_VERIFY_RECOVER},	/* CKM_RSA_PKCS; in bits */
164 	{256, 4096, CKF_GENERATE_KEY_PAIR},	/* CKM_RSA_PKCS_KEY_PAIR_GEN; */
165 						/* in bits */
166 	{256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
167 		CKF_SIGN|CKF_SIGN_RECOVER|
168 		CKF_WRAP|CKF_UNWRAP|
169 		CKF_VERIFY|CKF_VERIFY_RECOVER},	/* CKM_RSA_X_509 in bits */
170 	{256, 4096, CKF_SIGN|CKF_VERIFY},	/* CKM_MD5_RSA_PKCS in bits */
171 	{256, 4096, CKF_SIGN|CKF_VERIFY},	/* CKM_SHA1_RSA_PKCS in bits */
172 	{MIN_DH_KEYLENGTH, MAX_DH_KEYLENGTH, CKF_GENERATE_KEY_PAIR},
173 						/* CKM_DH_PKCS_KEY_PAIR_GEN */
174 						/* in bits */
175 	{MIN_DH_KEYLENGTH, MAX_DH_KEYLENGTH, CKF_DERIVE},
176 						/* CKM_DH_PKCS_DERIVE; */
177 						/* in bits */
178 	{1, 16, CKF_DERIVE},			/* CKM_MD5_KEY_DERIVATION */
179 	{1, 20, CKF_DERIVE},			/* CKM_SHA1_KEY_DERIVATION */
180 	{0, 0, CKF_GENERATE},			/* CKM_PBE_SHA1_RC4_128 */
181 	{0, 0, CKF_GENERATE},			/* CKM_PKCS5_PBKD2 */
182 	{48, 48, CKF_GENERATE},		/* CKM_SSL3_PRE_MASTER_KEY_GEN */
183 	{48, 48, CKF_GENERATE},		/* CKM_TLS_PRE_MASTER_KEY_GEN */
184 	{48, 48, CKF_DERIVE},		/* CKM_SSL3_MASTER_KEY_DERIVE */
185 	{48, 48, CKF_DERIVE},		/* CKM_TLS_MASTER_KEY_DERIVE */
186 	{48, 48, CKF_DERIVE},		/* CKM_SSL3_MASTER_KEY_DERIVE_DH */
187 	{48, 48, CKF_DERIVE},		/* CKM_TLS_MASTER_KEY_DERIVE_DH */
188 	{0, 0, CKF_DERIVE},		/* CKM_SSL3_KEY_AND_MAC_DERIVE */
189 	{0, 0, CKF_DERIVE}		/* CKM_TLS_KEY_AND_MAC_DERIVE */
190 };
191 
192 /*
193  * Slot ID for softtoken is always 1. tokenPresent is ignored.
194  * Also, only one slot is used.
195  */
196 /*ARGSUSED*/
197 CK_RV
198 C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
199     CK_ULONG_PTR pulCount)
200 {
201 
202 	CK_RV rv;
203 
204 	if (!softtoken_initialized)
205 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
206 
207 	if (pulCount == NULL) {
208 		return (CKR_ARGUMENTS_BAD);
209 	}
210 
211 	if (pSlotList == NULL) {
212 		/*
213 		 * Application only wants to know the number of slots.
214 		 */
215 		*pulCount = 1;
216 		return (CKR_OK);
217 	}
218 
219 	if ((*pulCount < 1) && (pSlotList != NULL)) {
220 		rv = CKR_BUFFER_TOO_SMALL;
221 	} else {
222 		pSlotList[0] = SOFTTOKEN_SLOTID;
223 		rv = CKR_OK;
224 	}
225 
226 	*pulCount = 1;
227 	return (rv);
228 }
229 
230 
231 CK_RV
232 C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
233 {
234 
235 	if (!softtoken_initialized)
236 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
237 
238 	if (pInfo == NULL)
239 		return (CKR_ARGUMENTS_BAD);
240 
241 	/* Make sure the slot ID is valid */
242 	if (slotID != SOFTTOKEN_SLOTID)
243 		return (CKR_SLOT_ID_INVALID);
244 
245 	/* Provide information about the slot in the provided buffer */
246 	(void) strncpy((char *)pInfo->slotDescription, SOFT_SLOT_DESCRIPTION,
247 	    64);
248 	(void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
249 	pInfo->flags = 0;
250 	if (soft_token_present) {
251 		pInfo->flags |= CKF_TOKEN_PRESENT;
252 	}
253 	pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
254 	pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
255 	pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
256 	pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
257 
258 	return (CKR_OK);
259 }
260 
261 
262 CK_RV
263 C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
264 {
265 
266 	ulong_t	token_flag = 0;
267 	boolean_t pin_initialized = B_FALSE;
268 	char	*ks_cryptpin = NULL;
269 	CK_RV rv = CKR_OK;
270 
271 	if (!softtoken_initialized)
272 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
273 
274 	/* Make sure the slot ID is valid */
275 	if (slotID != SOFTTOKEN_SLOTID)
276 		return (CKR_SLOT_ID_INVALID);
277 
278 	if (pInfo == NULL)
279 		return (CKR_ARGUMENTS_BAD);
280 
281 	if (!soft_token_present)
282 		return (CKR_DEVICE_REMOVED);
283 
284 	/* Provide information about a token in the provided buffer */
285 	(void) strncpy((char *)pInfo->label, SOFT_TOKEN_LABEL, 32);
286 	(void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
287 	(void) strncpy((char *)pInfo->model, TOKEN_MODEL, 16);
288 	(void) strncpy((char *)pInfo->serialNumber, SOFT_TOKEN_SERIAL, 16);
289 
290 	rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
291 	    B_FALSE);
292 	if (rv != CKR_OK)
293 		return (rv);
294 	if (!pin_initialized)
295 		token_flag = CKF_USER_PIN_TO_BE_CHANGED;
296 	if (ks_cryptpin)
297 		free(ks_cryptpin);
298 
299 	pInfo->flags = SOFT_TOKEN_FLAGS | token_flag;
300 	pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
301 	pInfo->ulSessionCount = soft_session_cnt;
302 	pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
303 	pInfo->ulRwSessionCount = soft_session_rw_cnt;
304 	pInfo->ulMaxPinLen = MAX_PIN_LEN;
305 	pInfo->ulMinPinLen = MIN_PIN_LEN;
306 	pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
307 	pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
308 	pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
309 	pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
310 	pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
311 	pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
312 	pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
313 	pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
314 	(void) memset(pInfo->utcTime, ' ', 16);
315 
316 	return (CKR_OK);
317 }
318 
319 /*ARGSUSED*/
320 CK_RV
321 C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
322 {
323 	if (!softtoken_initialized)
324 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
325 
326 	/*
327 	 * This is currently not implemented, however we could cause this
328 	 * to wait for the token files to appear if soft_token_present is
329 	 * false.
330 	 * However there is currently no polite and portable way to do that
331 	 * because we might not even be able to get to an fd to the
332 	 * parent directory, so instead we don't support any slot events.
333 	 */
334 	return (CKR_FUNCTION_NOT_SUPPORTED);
335 }
336 
337 
338 CK_RV
339 C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
340     CK_ULONG_PTR pulCount)
341 {
342 
343 	ulong_t i;
344 	ulong_t mechnum;
345 
346 	if (!softtoken_initialized)
347 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
348 
349 	if (slotID != SOFTTOKEN_SLOTID)
350 		return (CKR_SLOT_ID_INVALID);
351 
352 	mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
353 
354 	if (pMechanismList == NULL) {
355 		/*
356 		 * Application only wants to know the number of
357 		 * supported mechanism types.
358 		 */
359 		*pulCount = mechnum;
360 		return (CKR_OK);
361 	}
362 
363 	if (*pulCount < mechnum) {
364 		*pulCount = mechnum;
365 		return (CKR_BUFFER_TOO_SMALL);
366 	}
367 
368 	for (i = 0; i < mechnum; i++) {
369 		pMechanismList[i] = soft_mechanisms[i];
370 	}
371 
372 	*pulCount = mechnum;
373 
374 	return (CKR_OK);
375 }
376 
377 
378 CK_RV
379 C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
380     CK_MECHANISM_INFO_PTR pInfo)
381 {
382 
383 	ulong_t i;
384 	ulong_t mechnum;
385 
386 	if (!softtoken_initialized)
387 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
388 
389 	if (slotID != SOFTTOKEN_SLOTID)
390 		return (CKR_SLOT_ID_INVALID);
391 
392 	if (pInfo == NULL) {
393 		return (CKR_ARGUMENTS_BAD);
394 	}
395 
396 	mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
397 	for (i = 0; i < mechnum; i++) {
398 		if (soft_mechanisms[i] == type)
399 			break;
400 	}
401 
402 	if (i == mechnum)
403 		/* unsupported mechanism */
404 		return (CKR_MECHANISM_INVALID);
405 
406 	pInfo->ulMinKeySize = soft_mechanism_info[i].ulMinKeySize;
407 	pInfo->ulMaxKeySize = soft_mechanism_info[i].ulMaxKeySize;
408 	pInfo->flags = soft_mechanism_info[i].flags;
409 
410 	return (CKR_OK);
411 }
412 
413 
414 /*ARGSUSED*/
415 CK_RV
416 C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
417     CK_UTF8CHAR_PTR pLabel)
418 {
419 	if (!softtoken_initialized)
420 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
421 
422 	return (CKR_FUNCTION_NOT_SUPPORTED);
423 }
424 
425 /*ARGSUSED*/
426 CK_RV
427 C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
428 {
429 	if (!softtoken_initialized)
430 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
431 
432 	return (CKR_FUNCTION_NOT_SUPPORTED);
433 }
434 
435 
436 CK_RV
437 C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
438     CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
439 {
440 
441 	soft_session_t *session_p;
442 	CK_RV rv;
443 	boolean_t lock_held = B_FALSE;
444 
445 	if (!softtoken_initialized)
446 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
447 
448 	/*
449 	 * Obtain the session pointer. Also, increment the session
450 	 * reference count.
451 	 */
452 	rv = handle2session(hSession, &session_p);
453 	if (rv != CKR_OK)
454 		return (rv);
455 
456 	if (!soft_token_present) {
457 		SES_REFRELE(session_p, lock_held);
458 		return (CKR_DEVICE_REMOVED);
459 	}
460 
461 	if ((ulOldPinLen < MIN_PIN_LEN) || (ulOldPinLen > MAX_PIN_LEN) ||
462 	    (ulNewPinLen < MIN_PIN_LEN) ||(ulNewPinLen > MAX_PIN_LEN)) {
463 		SES_REFRELE(session_p, lock_held);
464 		return (CKR_PIN_LEN_RANGE);
465 	}
466 
467 	if ((pOldPin == NULL_PTR) || (pNewPin == NULL_PTR)) {
468 		/*
469 		 * We don't support CKF_PROTECTED_AUTHENTICATION_PATH
470 		 */
471 		SES_REFRELE(session_p, lock_held);
472 		return (CKR_ARGUMENTS_BAD);
473 	}
474 
475 	/* check the state of the session */
476 	if ((session_p->state != CKS_RW_PUBLIC_SESSION) &&
477 	    (session_p->state != CKS_RW_USER_FUNCTIONS)) {
478 		SES_REFRELE(session_p, lock_held);
479 		return (CKR_SESSION_READ_ONLY);
480 	}
481 
482 	rv = soft_setpin(pOldPin, ulOldPinLen, pNewPin, ulNewPinLen);
483 
484 	SES_REFRELE(session_p, lock_held);
485 	return (rv);
486 }
487