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