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