xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/new_host.c (revision 13d8aaa19025bce854122482c986b488bbb781e8)
1 /*
2  * The Initial Developer of the Original Code is International
3  * Business Machines Corporation. Portions created by IBM
4  * Corporation are Copyright (C) 2005 International Business
5  * Machines Corporation. All Rights Reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the Common Public License as published by
9  * IBM Corporation; either version 1 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * Common Public License for more details.
16  *
17  * You should have received a copy of the Common Public License
18  * along with this program; if not, a copy can be viewed at
19  * http://www.opensource.org/licenses/cpl1.0.php.
20  */
21 
22 /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
23 /*
24  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #include <pwd.h>
29 #include <grp.h>
30 
31 #include "tpmtok_int.h"
32 #include "tpmtok_defs.h"
33 
34 extern pthread_rwlock_t obj_list_rw_mutex;
35 
36 void SC_SetFunctionList(void);
37 
38 struct ST_FCN_LIST function_list;
39 
40 int  debugfile = 0;
41 
42 pid_t  initedpid = 0;  // for initialized pid
43 
44 CK_C_INITIALIZE_ARGS cinit_args = {NULL, NULL, NULL, NULL, 0, NULL};
45 
46 extern void stlogterm();
47 extern void stloginit();
48 extern void stlogit2(int type, char *fmt, ...);
49 extern void stlogit(char *fmt, ...);
50 
51 CK_BBOOL
52 st_Initialized()
53 {
54 	return (initedpid == getpid());
55 }
56 
57 void
58 Fork_Initializer(void)
59 {
60 	stlogterm();
61 	stloginit(); // Initialize Logging so we can capture EVERYTHING
62 
63 	// Force logout.  This cleans out the private session and list
64 	// and cleans out the private object map
65 	(void) session_mgr_logout_all();
66 
67 	// Clean out the public object map
68 	// First parm is no longer used..
69 	(void) object_mgr_purge_map((SESSION *)0xFFFF, PUBLIC);
70 	(void) object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE);
71 
72 	// This should clear the entire session list out
73 	(void) session_mgr_close_all_sessions();
74 
75 	next_session_handle = 1;
76 	next_object_handle = 1;
77 
78 	while (priv_token_obj_list) {
79 		priv_token_obj_list = dlist_remove_node(priv_token_obj_list,
80 		    priv_token_obj_list);
81 	}
82 
83 	while (publ_token_obj_list) {
84 		publ_token_obj_list = dlist_remove_node(publ_token_obj_list,
85 		    publ_token_obj_list);
86 	}
87 }
88 
89 #define	SESSION_HANDLE   sSession.sessionh
90 
91 #define	SESS_SET \
92 	CK_SESSION_HANDLE  hSession = sSession.sessionh;
93 
94 static CK_RV
95 validate_mechanism(CK_MECHANISM_PTR  pMechanism)
96 {
97 	CK_ULONG i;
98 
99 	for (i = 0; i < mech_list_len; i++) {
100 		if (pMechanism->mechanism == mech_list[i].mech_type) {
101 			return (CKR_OK);
102 		}
103 	}
104 	return (CKR_MECHANISM_INVALID);
105 }
106 
107 #define	VALID_MECH(p) \
108 	if (validate_mechanism(p) != CKR_OK) { \
109 		rc = CKR_MECHANISM_INVALID; \
110 		goto done; \
111 	}
112 
113 CK_RV
114 ST_Initialize(void *FunctionList,
115 	CK_SLOT_ID SlotNumber,
116 	unsigned char *Correlator)
117 {
118 	CK_RV  rc = CKR_OK;
119 	struct ST_FCN_LIST *flist = (struct ST_FCN_LIST *)FunctionList;
120 	TSS_HCONTEXT hContext = 0;
121 
122 	stlogterm();
123 	stloginit();
124 
125 	if (st_Initialized() == TRUE) {
126 		return (CKR_OK);
127 	}
128 	// assume that the upper API prevents multiple calls of initialize
129 	// since that only happens on C_Initialize and that is the
130 	// resonsibility of the upper layer..
131 	initialized = FALSE;
132 
133 	// check for other completing this before creating mutexes...
134 	// make sure that the same process tried to to the init...
135 	// thread issues should be caught up above...
136 	if (st_Initialized() == TRUE) {
137 		goto done;
138 	}
139 
140 	Fork_Initializer();
141 
142 	(void) pthread_mutex_init(&pkcs_mutex, NULL);
143 	(void) pthread_mutex_init(&obj_list_mutex, NULL);
144 	(void) pthread_rwlock_init(&obj_list_rw_mutex, NULL);
145 
146 	(void) pthread_mutex_init(&sess_list_mutex, NULL);
147 	(void) pthread_mutex_init(&login_mutex, NULL);
148 
149 	if (st_Initialized() == FALSE) {
150 		if ((rc = attach_shm()) != CKR_OK)
151 			goto done;
152 
153 		nv_token_data = &global_shm->nv_token_data;
154 
155 		initialized = TRUE;
156 		initedpid = getpid();
157 		SC_SetFunctionList();
158 
159 		/* Always call the token_specific_init function.... */
160 		rc = token_specific.t_init((char *)Correlator, SlotNumber,
161 		    &hContext);
162 		if (rc != 0)
163 			goto done;
164 	}
165 
166 	rc = load_token_data(hContext, nv_token_data);
167 
168 	if (rc != CKR_OK) {
169 		goto done;
170 	}
171 
172 	rc = load_public_token_objects();
173 	if (rc != CKR_OK)
174 		goto done;
175 
176 	(void) XProcLock(xproclock);
177 	global_shm->publ_loaded = TRUE;
178 	(void) XProcUnLock(xproclock);
179 
180 	init_slot_info(nv_token_data);
181 
182 	if (flist != NULL)
183 		(*flist) = function_list;
184 done:
185 	if (hContext)
186 		Tspi_Context_Close(hContext);
187 	return (rc);
188 }
189 
190 /*ARGSUSED*/
191 CK_RV
192 SC_Finalize(void *argptr)
193 {
194 	CK_RV	  rc;
195 	TSS_HCONTEXT hContext;
196 
197 	if (st_Initialized() == FALSE) {
198 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
199 	}
200 
201 	rc = pthread_mutex_lock(&pkcs_mutex);
202 	if (rc != CKR_OK) {
203 		return (rc);
204 	}
205 	//
206 	// If somebody else has taken care of things, leave...
207 	//
208 	if (st_Initialized() == FALSE) {
209 		(void) pthread_mutex_unlock(&pkcs_mutex);
210 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
211 	}
212 	if (open_tss_context(&hContext)) {
213 		(void) pthread_mutex_unlock(&pkcs_mutex);
214 		return (CKR_FUNCTION_FAILED);
215 	}
216 
217 	initialized = FALSE;
218 
219 	(void) session_mgr_close_all_sessions();
220 	(void) object_mgr_purge_token_objects(hContext);
221 	(void) Tspi_Context_Close(hContext);
222 
223 	(void) detach_shm();
224 	if (token_specific.t_final != NULL) {
225 		token_specific.t_final();
226 	}
227 
228 	rc = pthread_mutex_unlock(&pkcs_mutex);
229 	if (rc != CKR_OK) {
230 		return (rc);
231 	}
232 	return (CKR_OK);
233 }
234 
235 /*ARGSUSED*/
236 CK_RV
237 SC_GetTokenInfo(CK_SLOT_ID sid, CK_TOKEN_INFO_PTR  pInfo)
238 {
239 	CK_RV rc = CKR_OK;
240 	time_t now;
241 
242 	if (st_Initialized() == FALSE)
243 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
244 
245 	if (pInfo == NULL)
246 		return (CKR_FUNCTION_FAILED);
247 
248 	if (sid != TPM_SLOTID)
249 		return (CKR_SLOT_ID_INVALID);
250 
251 	(void) memcpy(pInfo, &nv_token_data->token_info,
252 	    sizeof (CK_TOKEN_INFO));
253 
254 	now = time((time_t *)NULL);
255 	(void) strftime((char *)pInfo->utcTime, 16, "%X", localtime(&now));
256 
257 	return (rc);
258 }
259 
260 /*ARGSUSED*/
261 CK_RV
262 SC_GetMechanismList(
263 	CK_SLOT_ID	sid,
264 	CK_MECHANISM_TYPE_PTR  pMechList,
265 	CK_ULONG_PTR	count)
266 {
267 	CK_ULONG   i;
268 	CK_RV	rc = CKR_OK;
269 
270 	if (st_Initialized() == FALSE) {
271 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
272 		goto done;
273 	}
274 
275 	if (count == NULL) {
276 		rc = CKR_FUNCTION_FAILED;
277 		goto done;
278 	}
279 
280 	if (sid != TPM_SLOTID) {
281 		rc = CKR_SLOT_ID_INVALID;
282 		goto done;
283 	}
284 
285 	if (pMechList == NULL) {
286 		*count = mech_list_len;
287 		rc = CKR_OK;
288 		goto done;
289 	}
290 
291 	if (*count < mech_list_len) {
292 		*count = mech_list_len;
293 		rc = CKR_BUFFER_TOO_SMALL;
294 		goto done;
295 	}
296 
297 	for (i = 0; i < mech_list_len; i++)
298 		pMechList[i] = mech_list[i].mech_type;
299 
300 	*count = mech_list_len;
301 	rc = CKR_OK;
302 
303 done:
304 	if (debugfile) {
305 		stlogit2(debugfile,
306 		    "% - 25s:  rc = 0x%08x, # mechanisms:  %d\n",
307 		    "C_GetMechanismList", rc, *count);
308 	}
309 	return (rc);
310 }
311 
312 /*ARGSUSED*/
313 CK_RV
314 SC_GetMechanismInfo(
315 	CK_SLOT_ID		sid,
316 	CK_MECHANISM_TYPE	type,
317 	CK_MECHANISM_INFO_PTR  pInfo)
318 {
319 	CK_ULONG  i;
320 	CK_RV	rc = CKR_OK;
321 
322 	if (st_Initialized() == FALSE) {
323 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
324 		goto done;
325 	}
326 
327 	if (pInfo == NULL) {
328 		rc = CKR_FUNCTION_FAILED;
329 		goto done;
330 	}
331 
332 	if (sid != TPM_SLOTID) {
333 		rc = CKR_SLOT_ID_INVALID;
334 		goto done;
335 	}
336 
337 	for (i = 0; i < mech_list_len; i++) {
338 		if (mech_list[i].mech_type == type) {
339 			(void) memcpy(pInfo, &mech_list[i].mech_info,
340 			    sizeof (CK_MECHANISM_INFO));
341 			rc = CKR_OK;
342 			goto done;
343 		}
344 	}
345 	rc = CKR_MECHANISM_INVALID;
346 
347 done:
348 	if (debugfile) {
349 		stlogit2(debugfile, "% - 25s:  "
350 		    "rc = 0x%08x, mech type = 0x%08x\n",
351 		    "C_GetMechanismInfo", rc, type);
352 	}
353 
354 	return (rc);
355 }
356 
357 /*ARGSUSED*/
358 CK_RV
359 SC_InitToken(
360 	CK_SLOT_ID  sid,
361 	CK_CHAR_PTR pPin,
362 	CK_ULONG    ulPinLen,
363 	CK_CHAR_PTR pLabel)
364 {
365 	CK_RV	rc = CKR_OK;
366 	CK_BYTE    hash_sha[SHA1_DIGEST_LENGTH];
367 	TOKEN_DATA	newtoken;
368 	TSS_HCONTEXT	hContext = 0;
369 
370 	if (st_Initialized() == FALSE) {
371 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
372 		goto done;
373 	}
374 	if (sid != TPM_SLOTID) {
375 		rc = CKR_SLOT_ID_INVALID;
376 		goto done;
377 	}
378 
379 	if (! pPin || ! pLabel) {
380 		rc = CKR_ARGUMENTS_BAD;
381 		goto done;
382 	}
383 	if (open_tss_context(&hContext)) {
384 		rc = CKR_FUNCTION_FAILED;
385 		goto done;
386 	}
387 
388 	rc = load_token_data(hContext, &newtoken);
389 	if (rc != CKR_OK) {
390 		goto done;
391 	}
392 
393 	if (newtoken.token_info.flags & CKF_SO_PIN_LOCKED) {
394 		rc = CKR_PIN_LOCKED;
395 		goto done;
396 	}
397 
398 	rc = token_specific.t_verify_so_pin(hContext, pPin, ulPinLen);
399 	if (rc != CKR_OK) {
400 		rc = CKR_PIN_INCORRECT;
401 		goto done;
402 	}
403 
404 	/*
405 	 * Before we reconstruct all the data, we should delete the
406 	 * token objects from the filesystem.
407 	 *
408 	 * Construct a string to delete the token objects.
409 	 */
410 	(void) object_mgr_destroy_token_objects(hContext);
411 
412 	(void) init_token_data(hContext, &newtoken);
413 	(void) init_slot_info(&newtoken);
414 
415 	/* change the label */
416 	(void) strncpy((char *)newtoken.token_info.label, (char *)pLabel,
417 	    sizeof (newtoken.token_info.label));
418 
419 	(void) memcpy(newtoken.so_pin_sha, hash_sha,
420 	    SHA1_DIGEST_LENGTH);
421 
422 	newtoken.token_info.flags |= CKF_TOKEN_INITIALIZED;
423 
424 	rc = save_token_data(&newtoken);
425 done:
426 	if (hContext)
427 		(void) Tspi_Context_Close(hContext);
428 
429 	return (rc);
430 }
431 
432 CK_RV
433 SC_InitPIN(
434 	ST_SESSION_HANDLE  sSession,
435 	CK_CHAR_PTR	pPin,
436 	CK_ULONG	   ulPinLen)
437 {
438 	SESSION	 * sess = NULL;
439 	CK_RV		rc = CKR_OK;
440 	CK_FLAGS	* flags = NULL;
441 	SESS_SET
442 
443 	if (st_Initialized() == FALSE) {
444 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
445 		goto done;
446 	}
447 
448 	if (! pPin) {
449 		rc = CKR_ARGUMENTS_BAD;
450 		goto done;
451 	}
452 
453 	sess = session_mgr_find(hSession);
454 	if (! sess) {
455 		rc = CKR_SESSION_HANDLE_INVALID;
456 		goto done;
457 	}
458 
459 	if (pin_locked(&sess->session_info,
460 	    nv_token_data->token_info.flags) == TRUE) {
461 		rc = CKR_PIN_LOCKED;
462 		goto done;
463 	}
464 
465 	if (sess->session_info.state != CKS_RW_SO_FUNCTIONS) {
466 		rc = CKR_USER_NOT_LOGGED_IN;
467 		goto done;
468 	}
469 
470 	rc = token_specific.t_init_pin(sess->hContext, pPin, ulPinLen);
471 	if (rc == CKR_OK) {
472 		flags = &nv_token_data->token_info.flags;
473 
474 		*flags &= ~(CKF_USER_PIN_LOCKED |
475 		    CKF_USER_PIN_FINAL_TRY |
476 		    CKF_USER_PIN_COUNT_LOW);
477 
478 		rc = save_token_data(nv_token_data);
479 		if (rc != CKR_OK) {
480 			goto done;
481 		}
482 	}
483 
484 done:
485 
486 	if (debugfile) {
487 		stlogit2(debugfile, "% - 25s:  session = %08x\n",
488 		    "C_InitPin", rc, hSession);
489 	}
490 
491 	return (rc);
492 }
493 
494 CK_RV
495 SC_SetPIN(ST_SESSION_HANDLE  sSession,
496 	CK_CHAR_PTR	pOldPin,
497 	CK_ULONG	   ulOldLen,
498 	CK_CHAR_PTR	pNewPin,
499 	CK_ULONG	   ulNewLen)
500 {
501 	SESSION	 * sess = NULL;
502 	CK_RV		rc = CKR_OK;
503 	SESS_SET
504 
505 	if (st_Initialized() == FALSE) {
506 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
507 		goto done;
508 	}
509 
510 	sess = session_mgr_find(hSession);
511 	if (! sess) {
512 		rc = CKR_SESSION_HANDLE_INVALID;
513 		goto done;
514 	}
515 
516 	if (pin_locked(&sess->session_info,
517 	    nv_token_data->token_info.flags) == TRUE) {
518 		rc = CKR_PIN_LOCKED;
519 		goto done;
520 	}
521 
522 	rc = token_specific.t_set_pin(sSession, pOldPin,
523 	    ulOldLen, pNewPin, ulNewLen);
524 
525 done:
526 	if (debugfile) {
527 		stlogit2(debugfile, "% - 25s:  session = %08x\n",
528 		    "C_SetPin", rc, hSession);
529 	}
530 
531 	return (rc);
532 }
533 
534 CK_RV
535 SC_OpenSession(
536 	CK_SLOT_ID		sid,
537 	CK_FLAGS		flags,
538 	CK_SESSION_HANDLE_PTR  phSession)
539 {
540 	SESSION		*sess;
541 	CK_RV		  rc = CKR_OK;
542 	TSS_HCONTEXT	hContext;
543 
544 	if (st_Initialized() == FALSE) {
545 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
546 		goto done;
547 	}
548 
549 	if ((flags & CKF_RW_SESSION) == 0) {
550 		if (session_mgr_so_session_exists()) {
551 			return (CKR_SESSION_READ_WRITE_SO_EXISTS);
552 		}
553 	}
554 	if (sid != TPM_SLOTID) {
555 		rc = CKR_SLOT_ID_INVALID;
556 		goto done;
557 	}
558 	if (open_tss_context(&hContext)) {
559 		rc = CKR_FUNCTION_FAILED;
560 		goto done;
561 	}
562 
563 	rc = pthread_mutex_lock(&pkcs_mutex);
564 	if (rc != CKR_OK) {
565 		(void) pthread_mutex_unlock(&pkcs_mutex);
566 		Tspi_Context_Close(hContext);
567 		goto done;
568 	}
569 	token_specific.t_session(sid);
570 
571 	(void) pthread_mutex_unlock(&pkcs_mutex);
572 
573 	rc = session_mgr_new(flags, &sess);
574 	if (rc != CKR_OK) {
575 		Tspi_Context_Close(hContext);
576 		goto done;
577 	}
578 	*phSession = sess->handle;
579 	sess->session_info.slotID = sid;
580 
581 	/* Open a new context for each session */
582 	sess->hContext = hContext;
583 done:
584 	return (rc);
585 }
586 
587 CK_RV
588 SC_CloseSession(ST_SESSION_HANDLE  sSession)
589 {
590 	SESSION  *sess = NULL;
591 	CK_RV	rc = CKR_OK;
592 	SESS_SET
593 
594 	if (st_Initialized() == FALSE) {
595 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
596 		goto done;
597 	}
598 
599 	sess = session_mgr_find(hSession);
600 	if (!sess) {
601 		rc = CKR_SESSION_HANDLE_INVALID;
602 		goto done;
603 	}
604 
605 	rc = session_mgr_close_session(sess);
606 
607 done:
608 
609 	return (rc);
610 }
611 
612 /*ARGSUSED*/
613 CK_RV
614 SC_CloseAllSessions(CK_SLOT_ID  sid)
615 {
616 	CK_RV rc = CKR_OK;
617 
618 	if (st_Initialized() == FALSE)
619 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
620 
621 	if (sid != TPM_SLOTID)
622 		return (CKR_SLOT_ID_INVALID);
623 
624 	rc = session_mgr_close_all_sessions();
625 
626 	return (rc);
627 }
628 
629 CK_RV
630 SC_GetSessionInfo(ST_SESSION_HANDLE   sSession,
631 	CK_SESSION_INFO_PTR pInfo)
632 {
633 	SESSION  * sess = NULL;
634 	CK_RV	rc = CKR_OK;
635 	SESS_SET
636 
637 	if (st_Initialized() == FALSE) {
638 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
639 		goto done;
640 	}
641 
642 	if (! pInfo) {
643 		rc = CKR_ARGUMENTS_BAD;
644 		goto done;
645 	}
646 
647 	sess = session_mgr_find(hSession);
648 	if (! sess) {
649 		rc = CKR_SESSION_HANDLE_INVALID;
650 		goto done;
651 	}
652 
653 	(void) memcpy(pInfo, &sess->session_info, sizeof (CK_SESSION_INFO));
654 
655 done:
656 	return (rc);
657 }
658 
659 CK_RV SC_GetOperationState(ST_SESSION_HANDLE  sSession,
660 	CK_BYTE_PTR	pOperationState,
661 	CK_ULONG_PTR	pulOperationStateLen)
662 {
663 	SESSION  * sess = NULL;
664 	CK_BBOOL   length_only = FALSE;
665 	CK_RV	rc = CKR_OK;
666 	SESS_SET
667 
668 	if (st_Initialized() == FALSE) {
669 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
670 		goto done;
671 	}
672 
673 	if (! pulOperationStateLen) {
674 		rc = CKR_ARGUMENTS_BAD;
675 		goto done;
676 	}
677 
678 	if (! pOperationState)
679 		length_only = TRUE;
680 
681 	sess = session_mgr_find(hSession);
682 	if (! sess) {
683 		rc = CKR_SESSION_HANDLE_INVALID;
684 		goto done;
685 	}
686 
687 	rc = session_mgr_get_op_state(sess, length_only,
688 	    pOperationState, pulOperationStateLen);
689 done:
690 	return (rc);
691 }
692 
693 CK_RV
694 SC_SetOperationState(ST_SESSION_HANDLE  sSession,
695 	CK_BYTE_PTR	pOperationState,
696 	CK_ULONG	   ulOperationStateLen,
697 	CK_OBJECT_HANDLE   hEncryptionKey,
698 	CK_OBJECT_HANDLE   hAuthenticationKey)
699 {
700 	SESSION  * sess = NULL;
701 	CK_RV	rc = CKR_OK;
702 	SESS_SET
703 
704 	if (st_Initialized() == FALSE) {
705 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
706 	}
707 
708 	if (!pOperationState || (ulOperationStateLen == 0)) {
709 		return (CKR_ARGUMENTS_BAD);
710 	}
711 
712 	sess = session_mgr_find(hSession);
713 	if (! sess) {
714 		return (CKR_SESSION_HANDLE_INVALID);
715 	}
716 
717 	rc = session_mgr_set_op_state(sess,
718 	    hEncryptionKey,  hAuthenticationKey,
719 	    pOperationState);
720 
721 	return (rc);
722 }
723 
724 CK_RV
725 SC_Login(ST_SESSION_HANDLE   sSession,
726 	CK_USER_TYPE	userType,
727 	CK_CHAR_PTR	pPin,
728 	CK_ULONG	ulPinLen)
729 {
730 	SESSION	* sess = NULL;
731 	CK_FLAGS    * flags = NULL, flagcheck, flagmask;
732 	CK_RV	 rc = CKR_OK;
733 
734 	SESS_SET
735 	// In v2.11, logins should be exclusive, since token
736 	// specific flags may need to be set for a bad login. - KEY
737 	rc = pthread_mutex_lock(&login_mutex);
738 	if (rc != CKR_OK) {
739 		return (CKR_FUNCTION_FAILED);
740 	}
741 
742 	if (st_Initialized() == FALSE) {
743 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
744 		goto done;
745 	}
746 
747 	sess = session_mgr_find(hSession);
748 	if (! sess) {
749 		rc = CKR_SESSION_HANDLE_INVALID;
750 		goto done;
751 	}
752 	flags = &nv_token_data->token_info.flags;
753 
754 	if (! pPin || ulPinLen > MAX_PIN_LEN) {
755 		set_login_flags(userType, flags);
756 		rc = CKR_PIN_INCORRECT;
757 		goto done;
758 	}
759 
760 	/*
761 	 * PKCS #11 v2.01 requires that all sessions have the same login status:
762 	 * --> all sessions are public, all are SO or all are USER
763 	 */
764 	if (userType == CKU_USER) {
765 		if (session_mgr_so_session_exists()) {
766 			rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
767 		}
768 		if (session_mgr_user_session_exists()) {
769 			rc = CKR_USER_ALREADY_LOGGED_IN;
770 		}
771 		} else if (userType == CKU_SO) {
772 
773 		if (session_mgr_user_session_exists()) {
774 			rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
775 		}
776 		if (session_mgr_so_session_exists()) {
777 			rc = CKR_USER_ALREADY_LOGGED_IN;
778 		}
779 		if (session_mgr_readonly_exists()) {
780 			rc = CKR_SESSION_READ_ONLY_EXISTS;
781 		}
782 	} else {
783 		rc = CKR_USER_TYPE_INVALID;
784 	}
785 	if (rc != CKR_OK)
786 		goto done;
787 
788 	if (userType == CKU_USER) {
789 		flagcheck = CKF_USER_PIN_LOCKED;
790 		flagmask = (CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY |
791 		    CKF_USER_PIN_COUNT_LOW);
792 	} else {
793 		flagcheck = CKF_SO_PIN_LOCKED;
794 		flagmask = (CKF_SO_PIN_LOCKED |
795 		    CKF_SO_PIN_FINAL_TRY |
796 		    CKF_SO_PIN_COUNT_LOW);
797 	}
798 	if (*flags & flagcheck) {
799 		rc = CKR_PIN_LOCKED;
800 		goto done;
801 	}
802 
803 	/* call the pluggable login function here */
804 	rc = token_specific.t_login(sess->hContext, userType, pPin, ulPinLen);
805 	if (rc == CKR_OK) {
806 		*flags &= ~(flagmask);
807 	} else if (rc == CKR_PIN_INCORRECT) {
808 		set_login_flags(userType, flags);
809 		goto done;
810 	} else {
811 		goto done;
812 	}
813 
814 	rc = session_mgr_login_all(userType);
815 
816 done:
817 	if (rc == CKR_OK)
818 		rc = save_token_data(nv_token_data);
819 	(void) pthread_mutex_unlock(&login_mutex);
820 	return (rc);
821 }
822 
823 CK_RV
824 SC_Logout(ST_SESSION_HANDLE  sSession)
825 {
826 	SESSION  * sess = NULL;
827 	CK_RV	rc = CKR_OK;
828 
829 	SESS_SET
830 
831 	if (st_Initialized() == FALSE) {
832 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
833 		goto done;
834 	}
835 
836 	sess = session_mgr_find(hSession);
837 	if (! sess) {
838 		rc = CKR_SESSION_HANDLE_INVALID;
839 		goto done;
840 	}
841 
842 	// all sessions have the same state so we just have to check one
843 	//
844 	if (session_mgr_public_session_exists()) {
845 		rc = CKR_USER_NOT_LOGGED_IN;
846 		goto done;
847 	}
848 
849 	(void) session_mgr_logout_all();
850 
851 	rc = token_specific.t_logout(sess->hContext);
852 
853 done:
854 	return (rc);
855 }
856 
857 CK_RV
858 SC_CreateObject(ST_SESSION_HANDLE    sSession,
859 	CK_ATTRIBUTE_PTR	pTemplate,
860 	CK_ULONG		ulCount,
861 	CK_OBJECT_HANDLE_PTR phObject)
862 {
863 	SESSION		* sess = NULL;
864 	CK_RV		   rc = CKR_OK;
865 	SESS_SET
866 
867 	if (st_Initialized() == FALSE) {
868 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
869 		goto done;
870 	}
871 
872 	sess = session_mgr_find(hSession);
873 	if (! sess) {
874 		rc = CKR_SESSION_HANDLE_INVALID;
875 		goto done;
876 	}
877 
878 	if (pin_expired(&sess->session_info,
879 	    nv_token_data->token_info.flags) == TRUE) {
880 		rc = CKR_PIN_EXPIRED;
881 		goto done;
882 	}
883 
884 	rc = object_mgr_add(sess, pTemplate, ulCount, phObject);
885 
886 done:
887 	return (rc);
888 
889 }
890 
891 CK_RV
892 SC_CopyObject(
893 	ST_SESSION_HANDLE    sSession,
894 	CK_OBJECT_HANDLE	hObject,
895 	CK_ATTRIBUTE_PTR	pTemplate,
896 	CK_ULONG		ulCount,
897 	CK_OBJECT_HANDLE_PTR phNewObject)
898 {
899 	SESSION		* sess = NULL;
900 	CK_RV		  rc = CKR_OK;
901 	SESS_SET
902 
903 	if (st_Initialized() == FALSE) {
904 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
905 		goto done;
906 	}
907 
908 	sess = session_mgr_find(hSession);
909 	if (! sess) {
910 		rc = CKR_SESSION_HANDLE_INVALID;
911 		goto done;
912 	}
913 
914 	if (pin_expired(&sess->session_info,
915 	    nv_token_data->token_info.flags) == TRUE) {
916 		rc = CKR_PIN_EXPIRED;
917 		goto done;
918 	}
919 
920 	rc = object_mgr_copy(sess, pTemplate, ulCount,
921 	    hObject, phNewObject);
922 
923 done:
924 	return (rc);
925 }
926 
927 CK_RV
928 SC_DestroyObject(ST_SESSION_HANDLE  sSession,
929 	CK_OBJECT_HANDLE   hObject)
930 {
931 	SESSION		* sess = NULL;
932 	CK_RV		   rc = CKR_OK;
933 	SESS_SET
934 
935 	if (st_Initialized() == FALSE) {
936 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
937 		goto done;
938 	}
939 
940 	sess = session_mgr_find(hSession);
941 	if (! sess) {
942 		rc = CKR_SESSION_HANDLE_INVALID;
943 		goto done;
944 	}
945 
946 	if (pin_expired(&sess->session_info,
947 	    nv_token_data->token_info.flags) == TRUE) {
948 		rc = CKR_PIN_EXPIRED;
949 		goto done;
950 	}
951 
952 	rc = object_mgr_destroy_object(sess, hObject);
953 done:
954 	return (rc);
955 }
956 
957 CK_RV
958 SC_GetObjectSize(
959 	ST_SESSION_HANDLE  sSession,
960 	CK_OBJECT_HANDLE   hObject,
961 	CK_ULONG_PTR	pulSize)
962 {
963 	SESSION		* sess = NULL;
964 	CK_RV		   rc = CKR_OK;
965 	SESS_SET
966 
967 	if (st_Initialized() == FALSE) {
968 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
969 		goto done;
970 	}
971 
972 	sess = session_mgr_find(hSession);
973 	if (! sess) {
974 		rc = CKR_SESSION_HANDLE_INVALID;
975 		goto done;
976 	}
977 
978 	rc = object_mgr_get_object_size(sess->hContext, hObject, pulSize);
979 
980 done:
981 	return (rc);
982 }
983 
984 CK_RV
985 SC_GetAttributeValue(ST_SESSION_HANDLE  sSession,
986 	CK_OBJECT_HANDLE   hObject,
987 	CK_ATTRIBUTE_PTR   pTemplate,
988 	CK_ULONG	   ulCount)
989 {
990 	SESSION	* sess = NULL;
991 	CK_RV	    rc = CKR_OK;
992 	SESS_SET
993 
994 	if (st_Initialized() == FALSE) {
995 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
996 		goto done;
997 	}
998 
999 	sess = session_mgr_find(hSession);
1000 	if (! sess) {
1001 		rc = CKR_SESSION_HANDLE_INVALID;
1002 		goto done;
1003 	}
1004 
1005 	rc = object_mgr_get_attribute_values(sess, hObject, pTemplate, ulCount);
1006 
1007 done:
1008 	return (rc);
1009 }
1010 
1011 CK_RV
1012 SC_SetAttributeValue(ST_SESSION_HANDLE    sSession,
1013 	CK_OBJECT_HANDLE	hObject,
1014 	CK_ATTRIBUTE_PTR	pTemplate,
1015 	CK_ULONG		ulCount)
1016 {
1017 	SESSION	* sess = NULL;
1018 	CK_RV	   rc = CKR_OK;
1019 	SESS_SET
1020 
1021 	if (st_Initialized() == FALSE) {
1022 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1023 		goto done;
1024 	}
1025 
1026 	sess = session_mgr_find(hSession);
1027 	if (! sess) {
1028 		rc = CKR_SESSION_HANDLE_INVALID;
1029 		goto done;
1030 	}
1031 
1032 	rc = object_mgr_set_attribute_values(sess, hObject, pTemplate, ulCount);
1033 
1034 done:
1035 	return (rc);
1036 }
1037 
1038 CK_RV
1039 SC_FindObjectsInit(ST_SESSION_HANDLE   sSession,
1040 	CK_ATTRIBUTE_PTR    pTemplate,
1041 	CK_ULONG	    ulCount)
1042 {
1043 	SESSION	* sess  = NULL;
1044 	CK_RV	    rc = CKR_OK;
1045 	SESS_SET
1046 
1047 	if (st_Initialized() == FALSE) {
1048 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1049 		goto done;
1050 	}
1051 
1052 	sess = session_mgr_find(hSession);
1053 	if (! sess) {
1054 		rc = CKR_SESSION_HANDLE_INVALID;
1055 		goto done;
1056 	}
1057 
1058 	if (pin_expired(&sess->session_info,
1059 	    nv_token_data->token_info.flags) == TRUE) {
1060 		rc = CKR_PIN_EXPIRED;
1061 		goto done;
1062 	}
1063 
1064 	if (sess->find_active == TRUE) {
1065 		rc = CKR_OPERATION_ACTIVE;
1066 		goto done;
1067 	}
1068 
1069 	rc = object_mgr_find_init(sess, pTemplate, ulCount);
1070 
1071 done:
1072 	return (rc);
1073 }
1074 
1075 CK_RV
1076 SC_FindObjects(ST_SESSION_HANDLE	sSession,
1077 	CK_OBJECT_HANDLE_PTR  phObject,
1078 	CK_ULONG		ulMaxObjectCount,
1079 	CK_ULONG_PTR	  pulObjectCount)
1080 {
1081 	SESSION    * sess  = NULL;
1082 	CK_ULONG	count = 0;
1083 	CK_RV	rc = CKR_OK;
1084 	SESS_SET
1085 
1086 	if (st_Initialized() == FALSE) {
1087 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1088 		goto done;
1089 	}
1090 
1091 	if (! phObject || ! pulObjectCount) {
1092 		rc = CKR_ARGUMENTS_BAD;
1093 		goto done;
1094 	}
1095 
1096 	sess = session_mgr_find(hSession);
1097 	if (! sess) {
1098 		rc = CKR_SESSION_HANDLE_INVALID;
1099 		goto done;
1100 	}
1101 
1102 	if (sess->find_active == FALSE) {
1103 		rc = CKR_OPERATION_NOT_INITIALIZED;
1104 		goto done;
1105 	}
1106 
1107 	if (! sess->find_list) {
1108 		rc = CKR_FUNCTION_FAILED;
1109 		goto done;
1110 	}
1111 	count = MIN(ulMaxObjectCount, (sess->find_count - sess->find_idx));
1112 
1113 	(void) memcpy(phObject, sess->find_list + sess->find_idx,
1114 	    count * sizeof (CK_OBJECT_HANDLE));
1115 	*pulObjectCount = count;
1116 
1117 	sess->find_idx += count;
1118 	rc = CKR_OK;
1119 
1120 done:
1121 	return (rc);
1122 }
1123 
1124 CK_RV
1125 SC_FindObjectsFinal(ST_SESSION_HANDLE  sSession)
1126 {
1127 	SESSION	* sess = NULL;
1128 	CK_RV	 rc = CKR_OK;
1129 	SESS_SET
1130 
1131 	if (st_Initialized() == FALSE) {
1132 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1133 		goto done;
1134 	}
1135 
1136 	sess = session_mgr_find(hSession);
1137 	if (! sess) {
1138 		rc = CKR_SESSION_HANDLE_INVALID;
1139 		goto done;
1140 	}
1141 
1142 	if (sess->find_active == FALSE) {
1143 		rc = CKR_OPERATION_NOT_INITIALIZED;
1144 		goto done;
1145 	}
1146 
1147 	if (sess->find_list)
1148 		free(sess->find_list);
1149 
1150 	sess->find_list   = NULL;
1151 	sess->find_len    = 0;
1152 	sess->find_idx    = 0;
1153 	sess->find_active = FALSE;
1154 
1155 	rc = CKR_OK;
1156 
1157 done:
1158 	return (rc);
1159 }
1160 
1161 CK_RV
1162 SC_EncryptInit(ST_SESSION_HANDLE  sSession,
1163 	CK_MECHANISM_PTR   pMechanism,
1164 	CK_OBJECT_HANDLE   hKey)
1165 {
1166 	SESSION		* sess = NULL;
1167 	CK_RV		   rc = CKR_OK;
1168 	SESS_SET
1169 
1170 	if (st_Initialized() == FALSE) {
1171 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1172 		goto done;
1173 	}
1174 
1175 	if (! pMechanism) {
1176 		rc = CKR_ARGUMENTS_BAD;
1177 		goto done;
1178 	}
1179 
1180 	VALID_MECH(pMechanism);
1181 
1182 	sess = session_mgr_find(hSession);
1183 	if (! sess) {
1184 		rc = CKR_SESSION_HANDLE_INVALID;
1185 		goto done;
1186 	}
1187 
1188 	if (pin_expired(&sess->session_info,
1189 	    nv_token_data->token_info.flags) == TRUE) {
1190 		rc = CKR_PIN_EXPIRED;
1191 		goto done;
1192 	}
1193 
1194 	if (sess->encr_ctx.active == TRUE) {
1195 		rc = CKR_OPERATION_ACTIVE;
1196 		goto done;
1197 	}
1198 
1199 	rc = encr_mgr_init(sess, &sess->encr_ctx, OP_ENCRYPT_INIT,
1200 	    pMechanism, hKey);
1201 done:
1202 	return (rc);
1203 }
1204 
1205 CK_RV
1206 SC_Encrypt(ST_SESSION_HANDLE  sSession,
1207 	CK_BYTE_PTR	pData,
1208 	CK_ULONG	   ulDataLen,
1209 	CK_BYTE_PTR	pEncryptedData,
1210 	CK_ULONG_PTR	pulEncryptedDataLen)
1211 {
1212 	SESSION	* sess = NULL;
1213 	CK_BBOOL	 length_only = FALSE;
1214 	CK_RV	    rc = CKR_OK;
1215 	SESS_SET
1216 
1217 	if (st_Initialized() == FALSE) {
1218 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1219 		goto done;
1220 	}
1221 
1222 	if (! pData || ! pulEncryptedDataLen) {
1223 		rc = CKR_ARGUMENTS_BAD;
1224 		goto done;
1225 	}
1226 
1227 	sess = session_mgr_find(hSession);
1228 	if (! sess) {
1229 		rc = CKR_SESSION_HANDLE_INVALID;
1230 		goto done;
1231 	}
1232 
1233 	if (sess->encr_ctx.active == FALSE) {
1234 		rc = CKR_OPERATION_NOT_INITIALIZED;
1235 		goto done;
1236 	}
1237 
1238 	if (! pEncryptedData)
1239 		length_only = TRUE;
1240 
1241 	rc = encr_mgr_encrypt(sess, length_only,
1242 	    &sess->encr_ctx, pData, ulDataLen,
1243 	    pEncryptedData, pulEncryptedDataLen);
1244 
1245 done:
1246 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1247 		(void) encr_mgr_cleanup(&sess->encr_ctx);
1248 
1249 	return (rc);
1250 }
1251 
1252 #if 0
1253 CK_RV
1254 SC_EncryptUpdate(ST_SESSION_HANDLE  sSession,
1255 	CK_BYTE_PTR	pPart,
1256 	CK_ULONG	   ulPartLen,
1257 	CK_BYTE_PTR	pEncryptedPart,
1258 	CK_ULONG_PTR	pulEncryptedPartLen)
1259 {
1260 	SESSION	* sess = NULL;
1261 	CK_BBOOL	 length_only = FALSE;
1262 	CK_RV	    rc = CKR_OK;
1263 	SESS_SET
1264 
1265 	if (st_Initialized() == FALSE) {
1266 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1267 		goto done;
1268 	}
1269 
1270 	if (! pPart || ! pulEncryptedPartLen) {
1271 		rc = CKR_ARGUMENTS_BAD;
1272 		goto done;
1273 	}
1274 
1275 	sess = session_mgr_find(hSession);
1276 	if (! sess) {
1277 		rc = CKR_SESSION_HANDLE_INVALID;
1278 		goto done;
1279 	}
1280 
1281 	if (sess->encr_ctx.active == FALSE) {
1282 		rc = CKR_OPERATION_NOT_INITIALIZED;
1283 		goto done;
1284 	}
1285 
1286 	if (! pEncryptedPart)
1287 		length_only = TRUE;
1288 
1289 	rc = encr_mgr_encrypt_update(sess,	   length_only,
1290 	    &sess->encr_ctx, pPart,	  ulPartLen,
1291 	    pEncryptedPart, pulEncryptedPartLen);
1292 
1293 done:
1294 	if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL)
1295 		(void) encr_mgr_cleanup(&sess->encr_ctx);
1296 
1297 	return (rc);
1298 }
1299 
1300 CK_RV
1301 SC_EncryptFinal(ST_SESSION_HANDLE  sSession,
1302 	CK_BYTE_PTR	pLastEncryptedPart,
1303 	CK_ULONG_PTR	pulLastEncryptedPartLen)
1304 {
1305 	SESSION	* sess = NULL;
1306 	CK_BBOOL	length_only = FALSE;
1307 	CK_RV	 rc = CKR_OK;
1308 	SESS_SET
1309 
1310 	if (st_Initialized() == FALSE) {
1311 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1312 		goto done;
1313 	}
1314 
1315 	if (! pulLastEncryptedPartLen) {
1316 		rc = CKR_ARGUMENTS_BAD;
1317 		goto done;
1318 	}
1319 
1320 	sess = session_mgr_find(hSession);
1321 	if (! sess) {
1322 		rc = CKR_SESSION_HANDLE_INVALID;
1323 		goto done;
1324 	}
1325 
1326 	if (sess->encr_ctx.active == FALSE) {
1327 		rc = CKR_OPERATION_NOT_INITIALIZED;
1328 		goto done;
1329 	}
1330 
1331 	if (! pLastEncryptedPart)
1332 		length_only = TRUE;
1333 
1334 	rc = encr_mgr_encrypt_final(sess, length_only, &sess->encr_ctx,
1335 	    pLastEncryptedPart, pulLastEncryptedPartLen);
1336 
1337 done:
1338 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1339 		(void) encr_mgr_cleanup(&sess->encr_ctx);
1340 
1341 	return (rc);
1342 }
1343 #endif
1344 
1345 CK_RV
1346 SC_DecryptInit(ST_SESSION_HANDLE  sSession,
1347 	CK_MECHANISM_PTR   pMechanism,
1348 	CK_OBJECT_HANDLE   hKey)
1349 {
1350 	SESSION   * sess = NULL;
1351 	CK_RV	rc = CKR_OK;
1352 	SESS_SET
1353 
1354 	if (st_Initialized() == FALSE) {
1355 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1356 		goto done;
1357 	}
1358 
1359 	if (! pMechanism) {
1360 		rc = CKR_ARGUMENTS_BAD;
1361 		goto done;
1362 	}
1363 	VALID_MECH(pMechanism);
1364 
1365 	sess = session_mgr_find(hSession);
1366 	if (! sess) {
1367 		rc = CKR_SESSION_HANDLE_INVALID;
1368 		goto done;
1369 	}
1370 
1371 	if (pin_expired(&sess->session_info,
1372 	    nv_token_data->token_info.flags) == TRUE) {
1373 		rc = CKR_PIN_EXPIRED;
1374 		goto done;
1375 	}
1376 
1377 	if (sess->decr_ctx.active == TRUE) {
1378 		rc = CKR_OPERATION_ACTIVE;
1379 		goto done;
1380 	}
1381 
1382 	rc = decr_mgr_init(sess, &sess->decr_ctx,
1383 	    OP_DECRYPT_INIT, pMechanism, hKey);
1384 
1385 done:
1386 	return (rc);
1387 }
1388 
1389 CK_RV
1390 SC_Decrypt(ST_SESSION_HANDLE  sSession,
1391 	CK_BYTE_PTR	pEncryptedData,
1392 	CK_ULONG	   ulEncryptedDataLen,
1393 	CK_BYTE_PTR	pData,
1394 	CK_ULONG_PTR	pulDataLen)
1395 {
1396 	SESSION  * sess = NULL;
1397 	CK_BBOOL   length_only = FALSE;
1398 	CK_RV	rc = CKR_OK;
1399 	SESS_SET
1400 
1401 	if (st_Initialized() == FALSE) {
1402 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1403 		goto done;
1404 	}
1405 
1406 	if (! pEncryptedData || ! pulDataLen) {
1407 		rc = CKR_ARGUMENTS_BAD;
1408 		goto done;
1409 	}
1410 
1411 	sess = session_mgr_find(hSession);
1412 	if (! sess) {
1413 		rc = CKR_SESSION_HANDLE_INVALID;
1414 		goto done;
1415 	}
1416 
1417 	if (sess->decr_ctx.active == FALSE) {
1418 		rc = CKR_OPERATION_NOT_INITIALIZED;
1419 		goto done;
1420 	}
1421 
1422 	if (! pData)
1423 		length_only = TRUE;
1424 
1425 	rc = decr_mgr_decrypt(sess,	   length_only,
1426 	    &sess->decr_ctx,
1427 	    pEncryptedData, ulEncryptedDataLen,
1428 	    pData,	  pulDataLen);
1429 
1430 done:
1431 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1432 		(void) decr_mgr_cleanup(&sess->decr_ctx);
1433 
1434 	return (rc);
1435 }
1436 
1437 CK_RV
1438 SC_DigestInit(ST_SESSION_HANDLE  sSession,
1439 	CK_MECHANISM_PTR   pMechanism)
1440 {
1441 	SESSION   * sess = NULL;
1442 	CK_RV	rc = CKR_OK;
1443 	SESS_SET
1444 
1445 	if (st_Initialized() == FALSE) {
1446 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1447 		goto done;
1448 	}
1449 	if (! pMechanism) {
1450 		rc = CKR_ARGUMENTS_BAD;
1451 		goto done;
1452 	}
1453 
1454 	VALID_MECH(pMechanism);
1455 
1456 	sess = session_mgr_find(hSession);
1457 	if (! sess) {
1458 		rc = CKR_SESSION_HANDLE_INVALID;
1459 		goto done;
1460 	}
1461 
1462 	if (pin_expired(&sess->session_info,
1463 	    nv_token_data->token_info.flags) == TRUE) {
1464 		rc = CKR_PIN_EXPIRED;
1465 		goto done;
1466 	}
1467 
1468 	if (sess->digest_ctx.active == TRUE) {
1469 		rc = CKR_OPERATION_ACTIVE;
1470 		goto done;
1471 	}
1472 
1473 	rc = digest_mgr_init(sess, &sess->digest_ctx, pMechanism);
1474 
1475 done:
1476 	return (rc);
1477 }
1478 
1479 CK_RV
1480 SC_Digest(ST_SESSION_HANDLE  sSession,
1481 	CK_BYTE_PTR	pData,
1482 	CK_ULONG	   ulDataLen,
1483 	CK_BYTE_PTR	pDigest,
1484 	CK_ULONG_PTR	pulDigestLen)
1485 {
1486 	SESSION  * sess = NULL;
1487 	CK_BBOOL   length_only = FALSE;
1488 	CK_RV	rc = CKR_OK;
1489 	SESS_SET
1490 
1491 	if (st_Initialized() == FALSE) {
1492 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1493 		goto done;
1494 	}
1495 
1496 	// Netscape has been known to pass a null pData to DigestUpdate
1497 	// but never for Digest.  It doesn't really make sense to allow it here
1498 	//
1499 	if (! pData || ! pulDigestLen) {
1500 		rc = CKR_ARGUMENTS_BAD;
1501 		goto done;
1502 	}
1503 
1504 	sess = session_mgr_find(hSession);
1505 	if (! sess) {
1506 		rc = CKR_SESSION_HANDLE_INVALID;
1507 		goto done;
1508 	}
1509 
1510 	if (sess->digest_ctx.active == FALSE) {
1511 		rc = CKR_OPERATION_NOT_INITIALIZED;
1512 		goto done;
1513 	}
1514 
1515 	if (! pDigest)
1516 		length_only = TRUE;
1517 
1518 	rc = digest_mgr_digest(sess,    length_only,
1519 	    &sess->digest_ctx, pData,   ulDataLen,
1520 	    pDigest, pulDigestLen);
1521 
1522 done:
1523 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1524 		(void) digest_mgr_cleanup(&sess->digest_ctx);
1525 
1526 	return (rc);
1527 }
1528 
1529 CK_RV
1530 SC_DigestUpdate(ST_SESSION_HANDLE  sSession,
1531 	CK_BYTE_PTR	pPart,
1532 	CK_ULONG	   ulPartLen)
1533 {
1534 	SESSION  * sess = NULL;
1535 	CK_RV	rc   = CKR_OK;
1536 	SESS_SET
1537 
1538 	if (st_Initialized() == FALSE) {
1539 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1540 		goto done;
1541 	}
1542 
1543 	if (! pPart && ulPartLen != 0) {
1544 		rc = CKR_ARGUMENTS_BAD;
1545 		goto done;
1546 	}
1547 
1548 	sess = session_mgr_find(hSession);
1549 	if (! sess) {
1550 		rc = CKR_SESSION_HANDLE_INVALID;
1551 		goto done;
1552 	}
1553 
1554 	if (sess->digest_ctx.active == FALSE) {
1555 		rc = CKR_OPERATION_NOT_INITIALIZED;
1556 		goto done;
1557 	}
1558 
1559 	if (pPart) {
1560 		rc = digest_mgr_digest_update(sess, &sess->digest_ctx,
1561 		    pPart, ulPartLen);
1562 	}
1563 done:
1564 	if (rc != CKR_OK)
1565 		(void) digest_mgr_cleanup(&sess->digest_ctx);
1566 
1567 	return (rc);
1568 }
1569 
1570 CK_RV
1571 SC_DigestKey(ST_SESSION_HANDLE  sSession,
1572 	CK_OBJECT_HANDLE   hKey)
1573 {
1574 	SESSION  * sess = NULL;
1575 	CK_RV	rc = CKR_OK;
1576 	SESS_SET
1577 
1578 	if (st_Initialized() == FALSE) {
1579 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1580 		goto done;
1581 	}
1582 
1583 	sess = session_mgr_find(hSession);
1584 	if (! sess) {
1585 		rc = CKR_SESSION_HANDLE_INVALID;
1586 		goto done;
1587 	}
1588 
1589 	if (sess->digest_ctx.active == FALSE) {
1590 		rc = CKR_OPERATION_NOT_INITIALIZED;
1591 		goto done;
1592 	}
1593 
1594 	rc = digest_mgr_digest_key(sess, &sess->digest_ctx, hKey);
1595 
1596 done:
1597 	if (rc != CKR_OK)
1598 		(void) digest_mgr_cleanup(&sess->digest_ctx);
1599 
1600 	return (rc);
1601 }
1602 
1603 CK_RV
1604 SC_DigestFinal(ST_SESSION_HANDLE  sSession,
1605 	CK_BYTE_PTR	pDigest,
1606 	CK_ULONG_PTR	pulDigestLen)
1607 {
1608 	SESSION  * sess = NULL;
1609 	CK_BBOOL   length_only = FALSE;
1610 	CK_RV	rc = CKR_OK;
1611 	SESS_SET
1612 
1613 	if (st_Initialized() == FALSE) {
1614 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1615 		goto done;
1616 	}
1617 
1618 	if (! pulDigestLen) {
1619 		rc = CKR_ARGUMENTS_BAD;
1620 		goto done;
1621 	}
1622 
1623 	sess = session_mgr_find(hSession);
1624 	if (! sess) {
1625 		rc = CKR_SESSION_HANDLE_INVALID;
1626 		goto done;
1627 	}
1628 
1629 	if (sess->digest_ctx.active == FALSE) {
1630 		rc = CKR_OPERATION_NOT_INITIALIZED;
1631 		goto done;
1632 	}
1633 
1634 	if (! pDigest)
1635 		length_only = TRUE;
1636 
1637 	rc = digest_mgr_digest_final(sess,
1638 	    &sess->digest_ctx, pDigest, pulDigestLen);
1639 
1640 done:
1641 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1642 		(void) digest_mgr_cleanup(&sess->digest_ctx);
1643 
1644 	return (rc);
1645 }
1646 
1647 CK_RV
1648 SC_SignInit(ST_SESSION_HANDLE  sSession,
1649 	CK_MECHANISM_PTR   pMechanism,
1650 	CK_OBJECT_HANDLE   hKey)
1651 {
1652 	SESSION   * sess = NULL;
1653 	CK_RV	rc = CKR_OK;
1654 	SESS_SET
1655 
1656 	if (st_Initialized() == FALSE) {
1657 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1658 		goto done;
1659 	}
1660 
1661 	if (! pMechanism) {
1662 		rc = CKR_ARGUMENTS_BAD;
1663 		goto done;
1664 	}
1665 
1666 	sess = session_mgr_find(hSession);
1667 	if (! sess) {
1668 		rc = CKR_SESSION_HANDLE_INVALID;
1669 		goto done;
1670 	}
1671 	VALID_MECH(pMechanism);
1672 
1673 	if (pin_expired(&sess->session_info,
1674 	    nv_token_data->token_info.flags) == TRUE) {
1675 		rc = CKR_PIN_EXPIRED;
1676 		goto done;
1677 	}
1678 
1679 	if (sess->sign_ctx.active == TRUE) {
1680 		rc = CKR_OPERATION_ACTIVE;
1681 		goto done;
1682 	}
1683 
1684 	rc = sign_mgr_init(sess, &sess->sign_ctx, pMechanism, FALSE, hKey);
1685 
1686 done:
1687 	return (rc);
1688 }
1689 
1690 CK_RV
1691 SC_Sign(ST_SESSION_HANDLE  sSession,
1692 	CK_BYTE_PTR	pData,
1693 	CK_ULONG	   ulDataLen,
1694 	CK_BYTE_PTR	pSignature,
1695 	CK_ULONG_PTR	pulSignatureLen)
1696 {
1697 	SESSION  * sess = NULL;
1698 	CK_BBOOL   length_only = FALSE;
1699 	CK_RV	rc = CKR_OK;
1700 	SESS_SET
1701 
1702 	if (st_Initialized() == FALSE) {
1703 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1704 		goto done;
1705 	}
1706 
1707 	if (! pData || ! pulSignatureLen) {
1708 		rc = CKR_ARGUMENTS_BAD;
1709 		goto done;
1710 	}
1711 
1712 	sess = session_mgr_find(hSession);
1713 	if (! sess) {
1714 		rc = CKR_SESSION_HANDLE_INVALID;
1715 		goto done;
1716 	}
1717 
1718 	if (sess->sign_ctx.active == FALSE) {
1719 		rc = CKR_OPERATION_NOT_INITIALIZED;
1720 		goto done;
1721 	}
1722 
1723 	if (! pSignature)
1724 		length_only = TRUE;
1725 
1726 	rc = sign_mgr_sign(sess,	length_only,
1727 	    &sess->sign_ctx, pData,	ulDataLen,
1728 	    pSignature, pulSignatureLen);
1729 
1730 done:
1731 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1732 		(void) sign_mgr_cleanup(&sess->sign_ctx);
1733 
1734 	return (rc);
1735 }
1736 
1737 CK_RV
1738 SC_SignUpdate(ST_SESSION_HANDLE  sSession,
1739 	CK_BYTE_PTR	pPart,
1740 	CK_ULONG	   ulPartLen)
1741 {
1742 	SESSION  * sess = NULL;
1743 	CK_RV	rc   = CKR_OK;
1744 	SESS_SET
1745 
1746 	if (st_Initialized() == FALSE) {
1747 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1748 		goto done;
1749 	}
1750 
1751 	if (! pPart) {
1752 		rc = CKR_ARGUMENTS_BAD;
1753 		goto done;
1754 	}
1755 
1756 	sess = session_mgr_find(hSession);
1757 	if (! sess) {
1758 		rc = CKR_SESSION_HANDLE_INVALID;
1759 		goto done;
1760 	}
1761 
1762 	if (sess->sign_ctx.active == FALSE) {
1763 		rc = CKR_OPERATION_NOT_INITIALIZED;
1764 		goto done;
1765 	}
1766 
1767 	rc = sign_mgr_sign_update(sess, &sess->sign_ctx, pPart, ulPartLen);
1768 
1769 done:
1770 	if (rc != CKR_OK)
1771 		(void) sign_mgr_cleanup(&sess->sign_ctx);
1772 
1773 	return (rc);
1774 }
1775 
1776 CK_RV
1777 SC_SignFinal(ST_SESSION_HANDLE  sSession,
1778 	CK_BYTE_PTR	pSignature,
1779 	CK_ULONG_PTR	pulSignatureLen)
1780 {
1781 	SESSION  * sess = NULL;
1782 	CK_BBOOL   length_only = FALSE;
1783 	CK_RV	rc = CKR_OK;
1784 	SESS_SET
1785 
1786 	if (st_Initialized() == FALSE) {
1787 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1788 		goto done;
1789 	}
1790 
1791 	if (! pulSignatureLen) {
1792 		rc = CKR_ARGUMENTS_BAD;
1793 		goto done;
1794 	}
1795 
1796 	sess = session_mgr_find(hSession);
1797 	if (! sess) {
1798 		rc = CKR_SESSION_HANDLE_INVALID;
1799 		goto done;
1800 	}
1801 
1802 	if (sess->sign_ctx.active == FALSE) {
1803 		rc = CKR_OPERATION_NOT_INITIALIZED;
1804 		goto done;
1805 	}
1806 
1807 	if (! pSignature)
1808 		length_only = TRUE;
1809 
1810 	rc = sign_mgr_sign_final(sess,	length_only,
1811 	    &sess->sign_ctx, pSignature, pulSignatureLen);
1812 
1813 done:
1814 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1815 		(void) sign_mgr_cleanup(&sess->sign_ctx);
1816 
1817 	return (rc);
1818 }
1819 
1820 CK_RV
1821 SC_SignRecoverInit(ST_SESSION_HANDLE  sSession,
1822 	CK_MECHANISM_PTR   pMechanism,
1823 	CK_OBJECT_HANDLE   hKey)
1824 {
1825 	SESSION   * sess = NULL;
1826 	CK_RV	rc = CKR_OK;
1827 	SESS_SET
1828 
1829 	if (st_Initialized() == FALSE) {
1830 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1831 		goto done;
1832 	}
1833 	if (! pMechanism) {
1834 		rc = CKR_ARGUMENTS_BAD;
1835 		goto done;
1836 	}
1837 	VALID_MECH(pMechanism);
1838 
1839 	sess = session_mgr_find(hSession);
1840 	if (! sess) {
1841 		rc = CKR_SESSION_HANDLE_INVALID;
1842 		goto done;
1843 	}
1844 
1845 	if (pin_expired(&sess->session_info,
1846 	    nv_token_data->token_info.flags) == TRUE) {
1847 		rc = CKR_PIN_EXPIRED;
1848 		goto done;
1849 	}
1850 
1851 	if (sess->sign_ctx.active == TRUE) {
1852 		rc = CKR_OPERATION_ACTIVE;
1853 		goto done;
1854 	}
1855 
1856 	rc = sign_mgr_init(sess, &sess->sign_ctx, pMechanism, TRUE, hKey);
1857 
1858 done:
1859 	return (rc);
1860 }
1861 
1862 CK_RV
1863 SC_SignRecover(ST_SESSION_HANDLE  sSession,
1864 	CK_BYTE_PTR	pData,
1865 	CK_ULONG	   ulDataLen,
1866 	CK_BYTE_PTR	pSignature,
1867 	CK_ULONG_PTR	pulSignatureLen)
1868 {
1869 	SESSION  * sess = NULL;
1870 	CK_BBOOL   length_only = FALSE;
1871 	CK_RV	rc = CKR_OK;
1872 	SESS_SET
1873 
1874 	if (st_Initialized() == FALSE) {
1875 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1876 		goto done;
1877 	}
1878 
1879 	if (! pData || ! pulSignatureLen) {
1880 		rc = CKR_ARGUMENTS_BAD;
1881 		goto done;
1882 	}
1883 
1884 	sess = session_mgr_find(hSession);
1885 	if (! sess) {
1886 		rc = CKR_SESSION_HANDLE_INVALID;
1887 		goto done;
1888 	}
1889 
1890 	if ((sess->sign_ctx.active == FALSE) ||
1891 	    (sess->sign_ctx.recover == FALSE)) {
1892 		rc = CKR_OPERATION_NOT_INITIALIZED;
1893 		goto done;
1894 	}
1895 
1896 	if (! pSignature)
1897 		length_only = TRUE;
1898 
1899 	rc = sign_mgr_sign_recover(sess,	length_only,
1900 	    &sess->sign_ctx, pData,	ulDataLen,
1901 	    pSignature, pulSignatureLen);
1902 
1903 done:
1904 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
1905 		(void) sign_mgr_cleanup(&sess->sign_ctx);
1906 
1907 	return (rc);
1908 }
1909 
1910 CK_RV
1911 SC_VerifyInit(ST_SESSION_HANDLE  sSession,
1912 	CK_MECHANISM_PTR   pMechanism,
1913 	CK_OBJECT_HANDLE   hKey)
1914 {
1915 	SESSION   * sess = NULL;
1916 	CK_RV	rc = CKR_OK;
1917 	SESS_SET
1918 
1919 	if (st_Initialized() == FALSE) {
1920 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1921 		goto done;
1922 	}
1923 	if (! pMechanism) {
1924 		rc = CKR_ARGUMENTS_BAD;
1925 		goto done;
1926 	}
1927 	VALID_MECH(pMechanism);
1928 
1929 	sess = session_mgr_find(hSession);
1930 	if (! sess) {
1931 		rc = CKR_SESSION_HANDLE_INVALID;
1932 		goto done;
1933 	}
1934 
1935 	if (pin_expired(&sess->session_info,
1936 	    nv_token_data->token_info.flags) == TRUE) {
1937 		rc = CKR_PIN_EXPIRED;
1938 		goto done;
1939 	}
1940 
1941 	if (sess->verify_ctx.active == TRUE) {
1942 		rc = CKR_OPERATION_ACTIVE;
1943 		goto done;
1944 	}
1945 
1946 	rc = verify_mgr_init(sess, &sess->verify_ctx, pMechanism, FALSE, hKey);
1947 
1948 done:
1949 	return (rc);
1950 }
1951 
1952 CK_RV
1953 SC_Verify(ST_SESSION_HANDLE  sSession,
1954 	CK_BYTE_PTR	pData,
1955 	CK_ULONG	   ulDataLen,
1956 	CK_BYTE_PTR	pSignature,
1957 	CK_ULONG	   ulSignatureLen)
1958 {
1959 	SESSION  * sess = NULL;
1960 	CK_RV	rc = CKR_OK;
1961 	SESS_SET
1962 
1963 	if (st_Initialized() == FALSE) {
1964 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1965 		goto done;
1966 	}
1967 
1968 	if (! pData || ! pSignature) {
1969 		rc = CKR_ARGUMENTS_BAD;
1970 		goto done;
1971 	}
1972 
1973 	sess = session_mgr_find(hSession);
1974 	if (! sess) {
1975 		rc = CKR_SESSION_HANDLE_INVALID;
1976 		goto done;
1977 	}
1978 
1979 	if (sess->verify_ctx.active == FALSE) {
1980 		rc = CKR_OPERATION_NOT_INITIALIZED;
1981 		goto done;
1982 	}
1983 
1984 	rc = verify_mgr_verify(sess,
1985 	    &sess->verify_ctx, pData,	ulDataLen,
1986 	    pSignature, ulSignatureLen);
1987 
1988 done:
1989 	(void) verify_mgr_cleanup(&sess->verify_ctx);
1990 
1991 	return (rc);
1992 }
1993 
1994 CK_RV
1995 SC_VerifyUpdate(ST_SESSION_HANDLE  sSession,
1996 	CK_BYTE_PTR	pPart,
1997 	CK_ULONG	   ulPartLen)
1998 {
1999 	SESSION  * sess = NULL;
2000 	CK_RV	rc   = CKR_OK;
2001 	SESS_SET
2002 
2003 	if (st_Initialized() == FALSE) {
2004 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2005 		goto done;
2006 	}
2007 
2008 	if (! pPart) {
2009 		rc = CKR_ARGUMENTS_BAD;
2010 		goto done;
2011 	}
2012 
2013 	sess = session_mgr_find(hSession);
2014 	if (! sess) {
2015 		rc = CKR_SESSION_HANDLE_INVALID;
2016 		goto done;
2017 	}
2018 
2019 	if (sess->verify_ctx.active == FALSE) {
2020 		rc = CKR_OPERATION_NOT_INITIALIZED;
2021 		goto done;
2022 	}
2023 
2024 	rc = verify_mgr_verify_update(sess, &sess->verify_ctx,
2025 	    pPart, ulPartLen);
2026 done:
2027 	if (rc != CKR_OK)
2028 		(void) verify_mgr_cleanup(&sess->verify_ctx);
2029 
2030 	return (rc);
2031 }
2032 
2033 CK_RV
2034 SC_VerifyFinal(ST_SESSION_HANDLE  sSession,
2035 	CK_BYTE_PTR	pSignature,
2036 	CK_ULONG	   ulSignatureLen)
2037 {
2038 	SESSION  * sess = NULL;
2039 	CK_RV	rc = CKR_OK;
2040 	SESS_SET
2041 
2042 	if (st_Initialized() == FALSE) {
2043 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2044 		goto done;
2045 	}
2046 
2047 	if (! pSignature) {
2048 		rc = CKR_ARGUMENTS_BAD;
2049 		goto done;
2050 	}
2051 
2052 	sess = session_mgr_find(hSession);
2053 	if (! sess) {
2054 		rc = CKR_SESSION_HANDLE_INVALID;
2055 		goto done;
2056 	}
2057 
2058 	if (sess->verify_ctx.active == FALSE) {
2059 		rc = CKR_OPERATION_NOT_INITIALIZED;
2060 		goto done;
2061 	}
2062 
2063 	rc = verify_mgr_verify_final(sess, &sess->verify_ctx,
2064 	    pSignature, ulSignatureLen);
2065 
2066 done:
2067 	(void) verify_mgr_cleanup(&sess->verify_ctx);
2068 
2069 	return (rc);
2070 }
2071 
2072 CK_RV
2073 SC_VerifyRecoverInit(ST_SESSION_HANDLE  sSession,
2074 	CK_MECHANISM_PTR   pMechanism,
2075 	CK_OBJECT_HANDLE   hKey)
2076 {
2077 	SESSION   * sess = NULL;
2078 	CK_RV	rc = CKR_OK;
2079 	SESS_SET
2080 
2081 	if (st_Initialized() == FALSE) {
2082 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2083 		goto done;
2084 	}
2085 	if (! pMechanism) {
2086 		rc = CKR_ARGUMENTS_BAD;
2087 		goto done;
2088 	}
2089 	VALID_MECH(pMechanism);
2090 
2091 	sess = session_mgr_find(hSession);
2092 	if (! sess) {
2093 		rc = CKR_SESSION_HANDLE_INVALID;
2094 		goto done;
2095 	}
2096 
2097 	if (pin_expired(&sess->session_info,
2098 	    nv_token_data->token_info.flags) == TRUE) {
2099 		rc = CKR_PIN_EXPIRED;
2100 		goto done;
2101 	}
2102 
2103 	if (sess->verify_ctx.active == TRUE) {
2104 		rc = CKR_OPERATION_ACTIVE;
2105 		goto done;
2106 	}
2107 
2108 	rc = verify_mgr_init(sess, &sess->verify_ctx, pMechanism, TRUE, hKey);
2109 
2110 done:
2111 	return (rc);
2112 }
2113 
2114 CK_RV
2115 SC_VerifyRecover(ST_SESSION_HANDLE  sSession,
2116 	CK_BYTE_PTR	pSignature,
2117 	CK_ULONG	   ulSignatureLen,
2118 	CK_BYTE_PTR	pData,
2119 	CK_ULONG_PTR	pulDataLen)
2120 {
2121 	SESSION  * sess = NULL;
2122 	CK_BBOOL   length_only = FALSE;
2123 	CK_RV	rc = CKR_OK;
2124 	SESS_SET
2125 
2126 	if (st_Initialized() == FALSE) {
2127 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2128 		goto done;
2129 	}
2130 
2131 	if (! pSignature || ! pulDataLen) {
2132 		rc = CKR_ARGUMENTS_BAD;
2133 		goto done;
2134 	}
2135 
2136 	sess = session_mgr_find(hSession);
2137 	if (! sess) {
2138 		rc = CKR_SESSION_HANDLE_INVALID;
2139 		goto done;
2140 	}
2141 
2142 	if ((sess->verify_ctx.active == FALSE) ||
2143 	    (sess->verify_ctx.recover == FALSE)) {
2144 		rc = CKR_OPERATION_NOT_INITIALIZED;
2145 		goto done;
2146 	}
2147 	if (! pData)
2148 		length_only = TRUE;
2149 
2150 	rc = verify_mgr_verify_recover(sess,	length_only,
2151 	    &sess->verify_ctx, pSignature, ulSignatureLen,
2152 	    pData,	pulDataLen);
2153 
2154 done:
2155 	if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
2156 		(void) verify_mgr_cleanup(&sess->verify_ctx);
2157 
2158 	return (rc);
2159 }
2160 
2161 CK_RV
2162 SC_GenerateKeyPair(ST_SESSION_HANDLE	sSession,
2163 	CK_MECHANISM_PTR	pMechanism,
2164 	CK_ATTRIBUTE_PTR	pPublicKeyTemplate,
2165 	CK_ULONG		ulPublicKeyAttributeCount,
2166 	CK_ATTRIBUTE_PTR	pPrivateKeyTemplate,
2167 	CK_ULONG		ulPrivateKeyAttributeCount,
2168 	CK_OBJECT_HANDLE_PTR  phPublicKey,
2169 	CK_OBJECT_HANDLE_PTR  phPrivateKey)
2170 {
2171 	SESSION	* sess = NULL;
2172 	CK_RV	   rc = CKR_OK;
2173 	SESS_SET
2174 
2175 	if (st_Initialized() == FALSE) {
2176 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2177 		goto done;
2178 	}
2179 
2180 	if (! pMechanism || ! phPublicKey || ! phPrivateKey ||
2181 	    (! pPublicKeyTemplate && (ulPublicKeyAttributeCount != 0)) ||
2182 	    (! pPrivateKeyTemplate && (ulPrivateKeyAttributeCount != 0))) {
2183 		rc = CKR_ARGUMENTS_BAD;
2184 		goto done;
2185 	}
2186 	VALID_MECH(pMechanism);
2187 
2188 	sess = session_mgr_find(hSession);
2189 	if (! sess) {
2190 		rc = CKR_SESSION_HANDLE_INVALID;
2191 		goto done;
2192 	}
2193 
2194 	if (pin_expired(&sess->session_info,
2195 	    nv_token_data->token_info.flags) == TRUE) {
2196 		rc = CKR_PIN_EXPIRED;
2197 		goto done;
2198 	}
2199 
2200 	rc = key_mgr_generate_key_pair(sess, pMechanism,
2201 	    pPublicKeyTemplate,  ulPublicKeyAttributeCount,
2202 	    pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
2203 	    phPublicKey,	 phPrivateKey);
2204 done:
2205 	return (rc);
2206 }
2207 
2208 CK_RV
2209 SC_WrapKey(ST_SESSION_HANDLE  sSession,
2210 	CK_MECHANISM_PTR   pMechanism,
2211 	CK_OBJECT_HANDLE   hWrappingKey,
2212 	CK_OBJECT_HANDLE   hKey,
2213 	CK_BYTE_PTR	pWrappedKey,
2214 	CK_ULONG_PTR	pulWrappedKeyLen)
2215 {
2216 	SESSION  * sess = NULL;
2217 	CK_BBOOL   length_only = FALSE;
2218 	CK_RV	rc = CKR_OK;
2219 	SESS_SET
2220 
2221 	if (st_Initialized() == FALSE) {
2222 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2223 		goto done;
2224 	}
2225 
2226 	if (! pMechanism || ! pulWrappedKeyLen) {
2227 		rc = CKR_ARGUMENTS_BAD;
2228 		goto done;
2229 	}
2230 	VALID_MECH(pMechanism);
2231 
2232 	if (! pWrappedKey)
2233 		length_only = TRUE;
2234 
2235 	sess = session_mgr_find(hSession);
2236 	if (! sess) {
2237 		rc = CKR_SESSION_HANDLE_INVALID;
2238 		goto done;
2239 	}
2240 
2241 	if (pin_expired(&sess->session_info,
2242 	    nv_token_data->token_info.flags) == TRUE) {
2243 		rc = CKR_PIN_EXPIRED;
2244 		goto done;
2245 	}
2246 
2247 	rc = key_mgr_wrap_key(sess, length_only,
2248 	    pMechanism, hWrappingKey, hKey,
2249 	    pWrappedKey,  pulWrappedKeyLen);
2250 
2251 done:
2252 	return (rc);
2253 }
2254 
2255 CK_RV
2256 SC_UnwrapKey(ST_SESSION_HANDLE	sSession,
2257 	CK_MECHANISM_PTR	pMechanism,
2258 	CK_OBJECT_HANDLE	hUnwrappingKey,
2259 	CK_BYTE_PTR	   pWrappedKey,
2260 	CK_ULONG		ulWrappedKeyLen,
2261 	CK_ATTRIBUTE_PTR	pTemplate,
2262 	CK_ULONG		ulCount,
2263 	CK_OBJECT_HANDLE_PTR  phKey)
2264 {
2265 	SESSION	* sess = NULL;
2266 	CK_RV	    rc = CKR_OK;
2267 	SESS_SET
2268 
2269 	if (st_Initialized() == FALSE) {
2270 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2271 		goto done;
2272 	}
2273 
2274 	if (! pMechanism || ! pWrappedKey ||
2275 	    (! pTemplate && ulCount != 0) || ! phKey) {
2276 		rc = CKR_ARGUMENTS_BAD;
2277 		goto done;
2278 	}
2279 	VALID_MECH(pMechanism);
2280 
2281 	sess = session_mgr_find(hSession);
2282 	if (! sess) {
2283 		rc = CKR_SESSION_HANDLE_INVALID;
2284 		goto done;
2285 	}
2286 
2287 	if (pin_expired(&sess->session_info,
2288 	    nv_token_data->token_info.flags) == TRUE) {
2289 		rc = CKR_PIN_EXPIRED;
2290 		goto done;
2291 	}
2292 
2293 	rc = key_mgr_unwrap_key(sess,	   pMechanism,
2294 	    pTemplate,	ulCount,
2295 	    pWrappedKey,    ulWrappedKeyLen,
2296 	    hUnwrappingKey, phKey);
2297 
2298 done:
2299 	return (rc);
2300 }
2301 
2302 /*ARGSUSED*/
2303 CK_RV
2304 SC_SeedRandom(ST_SESSION_HANDLE  sSession,
2305 	CK_BYTE_PTR	pSeed,
2306 	CK_ULONG	   ulSeedLen)
2307 {
2308 	if (st_Initialized() == FALSE) {
2309 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2310 	}
2311 	return (CKR_OK);
2312 }
2313 
2314 CK_RV
2315 SC_GenerateRandom(ST_SESSION_HANDLE  sSession,
2316 	CK_BYTE_PTR	pRandomData,
2317 	CK_ULONG	   ulRandomLen)
2318 {
2319 	SESSION *sess = NULL;
2320 	CK_RV    rc = CKR_OK;
2321 	SESS_SET
2322 
2323 	if (st_Initialized() == FALSE) {
2324 		rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2325 		goto done;
2326 	}
2327 
2328 	if (! pRandomData && ulRandomLen != 0) {
2329 		rc = CKR_ARGUMENTS_BAD;
2330 		goto done;
2331 	}
2332 
2333 	sess = session_mgr_find(hSession);
2334 	if (! sess) {
2335 		rc = CKR_SESSION_HANDLE_INVALID;
2336 		goto done;
2337 	}
2338 
2339 	rc = token_rng(sess->hContext, pRandomData, ulRandomLen);
2340 
2341 done:
2342 	return (rc);
2343 }
2344 
2345 void
2346 SC_SetFunctionList(void) {
2347 	function_list.ST_Initialize	= ST_Initialize;
2348 	function_list.ST_Finalize	= SC_Finalize;
2349 	function_list.ST_GetTokenInfo	= SC_GetTokenInfo;
2350 	function_list.ST_GetMechanismList    = SC_GetMechanismList;
2351 	function_list.ST_GetMechanismInfo    = SC_GetMechanismInfo;
2352 	function_list.ST_InitToken	   = SC_InitToken;
2353 	function_list.ST_InitPIN		= SC_InitPIN;
2354 	function_list.ST_SetPIN		= SC_SetPIN;
2355 	function_list.ST_OpenSession	 = SC_OpenSession;
2356 	function_list.ST_CloseSession	= SC_CloseSession;
2357 	function_list.ST_GetSessionInfo	= SC_GetSessionInfo;
2358 	function_list.ST_GetOperationState   = SC_GetOperationState;
2359 	function_list.ST_SetOperationState   = SC_SetOperationState;
2360 	function_list.ST_Login		= SC_Login;
2361 	function_list.ST_Logout		= SC_Logout;
2362 	function_list.ST_CreateObject	= SC_CreateObject;
2363 	function_list.ST_CopyObject	  = SC_CopyObject;
2364 	function_list.ST_DestroyObject	= SC_DestroyObject;
2365 	function_list.ST_GetObjectSize	= SC_GetObjectSize;
2366 	function_list.ST_GetAttributeValue   = SC_GetAttributeValue;
2367 	function_list.ST_SetAttributeValue   = SC_SetAttributeValue;
2368 	function_list.ST_FindObjectsInit	= SC_FindObjectsInit;
2369 	function_list.ST_FindObjects	 = SC_FindObjects;
2370 	function_list.ST_FindObjectsFinal    = SC_FindObjectsFinal;
2371 	function_list.ST_EncryptInit	 = SC_EncryptInit;
2372 	function_list.ST_Encrypt		= SC_Encrypt;
2373 	function_list.ST_EncryptUpdate	= NULL /* SC_EncryptUpdate */;
2374 	function_list.ST_EncryptFinal	= NULL /* SC_EncryptFinal */;
2375 	function_list.ST_DecryptInit	 = SC_DecryptInit;
2376 	function_list.ST_Decrypt		= SC_Decrypt;
2377 	function_list.ST_DecryptUpdate	= NULL /* SC_DecryptUpdate */;
2378 	function_list.ST_DecryptFinal	= NULL /* SC_DecryptFinal */;
2379 	function_list.ST_DigestInit	  = SC_DigestInit;
2380 	function_list.ST_Digest		= SC_Digest;
2381 	function_list.ST_DigestUpdate	= SC_DigestUpdate;
2382 	function_list.ST_DigestKey	   = SC_DigestKey;
2383 	function_list.ST_DigestFinal	 = SC_DigestFinal;
2384 	function_list.ST_SignInit	    = SC_SignInit;
2385 	function_list.ST_Sign		= SC_Sign;
2386 	function_list.ST_SignUpdate	  = SC_SignUpdate;
2387 	function_list.ST_SignFinal	   = SC_SignFinal;
2388 	function_list.ST_SignRecoverInit	= SC_SignRecoverInit;
2389 	function_list.ST_SignRecover	 = SC_SignRecover;
2390 	function_list.ST_VerifyInit	  = SC_VerifyInit;
2391 	function_list.ST_Verify		= SC_Verify;
2392 	function_list.ST_VerifyUpdate	= SC_VerifyUpdate;
2393 	function_list.ST_VerifyFinal	 = SC_VerifyFinal;
2394 	function_list.ST_VerifyRecoverInit   = SC_VerifyRecoverInit;
2395 	function_list.ST_VerifyRecover	= SC_VerifyRecover;
2396 	function_list.ST_DigestEncryptUpdate = NULL;
2397 	function_list.ST_DecryptDigestUpdate = NULL;
2398 	function_list.ST_SignEncryptUpdate   = NULL;
2399 	function_list.ST_DecryptVerifyUpdate = NULL;
2400 	function_list.ST_GenerateKey	 = NULL;
2401 	function_list.ST_GenerateKeyPair	= SC_GenerateKeyPair;
2402 	function_list.ST_WrapKey		= SC_WrapKey;
2403 	function_list.ST_UnwrapKey	   = SC_UnwrapKey;
2404 	function_list.ST_DeriveKey	   = NULL;
2405 	function_list.ST_SeedRandom	= SC_SeedRandom;
2406 	function_list.ST_GenerateRandom	= SC_GenerateRandom;
2407 	function_list.ST_GetFunctionStatus   = NULL;
2408 	function_list.ST_CancelFunction	= NULL;
2409 }
2410