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
34extern pthread_rwlock_t obj_list_rw_mutex;
35
36void SC_SetFunctionList(void);
37
38struct ST_FCN_LIST function_list;
39
40int  debugfile = 0;
41
42pid_t  initedpid = 0;  // for initialized pid
43
44CK_C_INITIALIZE_ARGS cinit_args = {NULL, NULL, NULL, NULL, 0, NULL};
45
46extern void stlogterm();
47extern void stloginit();
48extern void stlogit2(int type, char *fmt, ...);
49extern void stlogit(char *fmt, ...);
50
51CK_BBOOL
52st_Initialized()
53{
54	return (initedpid == getpid());
55}
56
57void
58Fork_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
94static CK_RV
95validate_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
113CK_RV
114ST_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
194done:
195	if (hContext)
196		Tspi_Context_Close(hContext);
197	return (rc);
198}
199
200/*ARGSUSED*/
201CK_RV
202SC_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*/
248CK_RV
249SC_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*/
273CK_RV
274SC_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
315done:
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*/
325CK_RV
326SC_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
359done:
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*/
370CK_RV
371SC_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);
437done:
438	if (hContext)
439		(void) Tspi_Context_Close(hContext);
440
441	return (rc);
442}
443
444CK_RV
445SC_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
496done:
497
498	if (debugfile) {
499		stlogit2(debugfile, "% - 25s:  session = %08x\n",
500		    "C_InitPin", rc, hSession);
501	}
502
503	return (rc);
504}
505
506CK_RV
507SC_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
537done:
538	if (debugfile) {
539		stlogit2(debugfile, "% - 25s:  session = %08x\n",
540		    "C_SetPin", rc, hSession);
541	}
542
543	return (rc);
544}
545
546CK_RV
547SC_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;
595done:
596	return (rc);
597}
598
599CK_RV
600SC_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
623done:
624
625	return (rc);
626}
627
628/*ARGSUSED*/
629CK_RV
630SC_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
645CK_RV
646SC_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
671done:
672	return (rc);
673}
674
675CK_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);
705done:
706	return (rc);
707}
708
709CK_RV
710SC_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
740CK_RV
741SC_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
836done:
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
843CK_RV
844SC_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
873done:
874	return (rc);
875}
876
877CK_RV
878SC_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
905done:
906	return (rc);
907
908}
909
910CK_RV
911SC_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
942done:
943	return (rc);
944}
945
946CK_RV
947SC_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);
972done:
973	return (rc);
974}
975
976CK_RV
977SC_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
999done:
1000	return (rc);
1001}
1002
1003CK_RV
1004SC_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
1026done:
1027	return (rc);
1028}
1029
1030CK_RV
1031SC_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
1053done:
1054	return (rc);
1055}
1056
1057CK_RV
1058SC_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
1090done:
1091	return (rc);
1092}
1093
1094CK_RV
1095SC_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
1139done:
1140	return (rc);
1141}
1142
1143CK_RV
1144SC_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
1176done:
1177	return (rc);
1178}
1179
1180CK_RV
1181SC_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);
1220done:
1221	return (rc);
1222}
1223
1224CK_RV
1225SC_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
1263done:
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
1271CK_RV
1272SC_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
1311done:
1312	if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL)
1313		(void) encr_mgr_cleanup(&sess->encr_ctx);
1314
1315	return (rc);
1316}
1317
1318CK_RV
1319SC_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
1355done:
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
1363CK_RV
1364SC_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
1403done:
1404	return (rc);
1405}
1406
1407CK_RV
1408SC_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
1448done:
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
1455CK_RV
1456SC_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
1493done:
1494	return (rc);
1495}
1496
1497CK_RV
1498SC_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
1537done:
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
1544CK_RV
1545SC_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	}
1578done:
1579	if (rc != CKR_OK)
1580		(void) digest_mgr_cleanup(&sess->digest_ctx);
1581
1582	return (rc);
1583}
1584
1585CK_RV
1586SC_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
1611done:
1612	if (rc != CKR_OK)
1613		(void) digest_mgr_cleanup(&sess->digest_ctx);
1614
1615	return (rc);
1616}
1617
1618CK_RV
1619SC_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
1655done:
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
1662CK_RV
1663SC_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
1701done:
1702	return (rc);
1703}
1704
1705CK_RV
1706SC_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
1744done:
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
1751CK_RV
1752SC_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
1783done:
1784	if (rc != CKR_OK)
1785		(void) sign_mgr_cleanup(&sess->sign_ctx);
1786
1787	return (rc);
1788}
1789
1790CK_RV
1791SC_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
1827done:
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
1834CK_RV
1835SC_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
1872done:
1873	return (rc);
1874}
1875
1876CK_RV
1877SC_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
1915done:
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
1922CK_RV
1923SC_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
1960done:
1961	return (rc);
1962}
1963
1964CK_RV
1965SC_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
1998done:
1999	(void) verify_mgr_cleanup(&sess->verify_ctx);
2000
2001	return (rc);
2002}
2003
2004CK_RV
2005SC_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);
2036done:
2037	if (rc != CKR_OK)
2038		(void) verify_mgr_cleanup(&sess->verify_ctx);
2039
2040	return (rc);
2041}
2042
2043CK_RV
2044SC_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
2076done:
2077	(void) verify_mgr_cleanup(&sess->verify_ctx);
2078
2079	return (rc);
2080}
2081
2082CK_RV
2083SC_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
2120done:
2121	return (rc);
2122}
2123
2124CK_RV
2125SC_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
2163done:
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
2170CK_RV
2171SC_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);
2213done:
2214	return (rc);
2215}
2216
2217CK_RV
2218SC_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
2260done:
2261	return (rc);
2262}
2263
2264CK_RV
2265SC_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
2307done:
2308	return (rc);
2309}
2310
2311/*ARGSUSED*/
2312CK_RV
2313SC_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
2326CK_RV
2327SC_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
2353done:
2354	return (rc);
2355}
2356
2357void
2358SC_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