1/*
2 *		Common Public License Version 0.5
3 *
4 *		THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
5 *		THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
6 *		REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
7 *		RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
8 *
9 *		1. DEFINITIONS
10 *
11 *		"Contribution" means:
12 *		      a) in the case of the initial Contributor, the
13 *		      initial code and documentation distributed under
14 *		      this Agreement, and
15 *
16 *		      b) in the case of each subsequent Contributor:
17 *		      i) changes to the Program, and
18 *		      ii) additions to the Program;
19 *
20 *		      where such changes and/or additions to the Program
21 *		      originate from and are distributed by that
22 *		      particular Contributor. A Contribution 'originates'
23 *		      from a Contributor if it was added to the Program
24 *		      by such Contributor itself or anyone acting on such
25 *		      Contributor's behalf. Contributions do not include
26 *		      additions to the Program which: (i) are separate
27 *		      modules of software distributed in conjunction with
28 *		      the Program under their own license agreement, and
29 *		      (ii) are not derivative works of the Program.
30 *
31 *
32 *		"Contributor" means any person or entity that distributes
33 *		the Program.
34 *
35 *		"Licensed Patents " mean patent claims licensable by a
36 *		Contributor which are necessarily infringed by the use or
37 *		sale of its Contribution alone or when combined with the
38 *		Program.
39 *
40 *		"Program" means the Contributions distributed in
41 *		accordance with this Agreement.
42 *
43 *		"Recipient" means anyone who receives the Program under
44 *		this Agreement, including all Contributors.
45 *
46 *		2. GRANT OF RIGHTS
47 *
48 *		      a) Subject to the terms of this Agreement, each
49 *		      Contributor hereby grants Recipient a
50 *		      no - exclusive, worldwide, royalt - free copyright
51 *		      license to reproduce, prepare derivative works of,
52 *		      publicly display, publicly perform, distribute and
53 *		      sublicense the Contribution of such Contributor, if
54 *		      any, and such derivative works, in source code and
55 *		      object code form.
56 *
57 *		      b) Subject to the terms of this Agreement, each
58 *		      Contributor hereby grants Recipient a
59 *		      no - exclusive, worldwide, royalt - free patent
60 *		      license under Licensed Patents to make, use, sell,
61 *		      offer to sell, import and otherwise transfer the
62 *		      Contribution of such Contributor, if any, in source
63 *		      code and object code form. This patent license
64 *		      shall apply to the combination of the Contribution
65 *		      and the Program if, at the time the Contribution is
66 *		      added by the Contributor, such addition of the
67 *		      Contribution causes such combination to be covered
68 *		      by the Licensed Patents. The patent license shall
69 *		      not apply to any other combinations which include
70 *		      the Contribution. No hardware per se is licensed
71 *		      hereunder.
72 *
73 *		      c) Recipient understands that although each
74 *		      Contributor grants the licenses to its
75 *		      Contributions set forth herein, no assurances are
76 *		      provided by any Contributor that the Program does
77 *		      not infringe the patent or other intellectual
78 *		      property rights of any other entity. Each
79 *		      Contributor disclaims any liability to Recipient
80 *		      for claims brought by any other entity based on
81 *		      infringement of intellectual property rights or
82 *		      otherwise. As a condition to exercising the rights
83 *		      and licenses granted hereunder, each Recipient
84 *		      hereby assumes sole responsibility to secure any
85 *		      other intellectual property rights needed, if any.
86 *
87 *		      For example, if a third party patent license is
88 *		      required to allow Recipient to distribute the
89 *		      Program, it is Recipient's responsibility to
90 *		      acquire that license before distributing the
91 *		      Program.
92 *
93 *		      d) Each Contributor represents that to its
94 *		      knowledge it has sufficient copyright rights in its
95 *		      Contribution, if any, to grant the copyright
96 *		      license set forth in this Agreement.
97 *
98 *		3. REQUIREMENTS
99 *
100 *		A Contributor may choose to distribute the Program in
101 *		object code form under its own license agreement, provided
102 *		that:
103 *		      a) it complies with the terms and conditions of
104 *		      this Agreement; and
105 *
106 *		      b) its license agreement:
107 *		      i) effectively disclaims on behalf of all
108 *		      Contributors all warranties and conditions, express
109 *		      and implied, including warranties or conditions of
110 *		      title and no - infringement, and implied warranties
111 *		      or conditions of merchantability and fitness for a
112 *		      particular purpose;
113 *
114 *		      ii) effectively excludes on behalf of all
115 *		      Contributors all liability for damages, including
116 *		      direct, indirect, special, incidental and
117 *		      consequential damages, such as lost profits;
118 *
119 *		      iii) states that any provisions which differ from
120 *		      this Agreement are offered by that Contributor
121 *		      alone and not by any other party; and
122 *
123 *		      iv) states that source code for the Program is
124 *		      available from such Contributor, and informs
125 *		      licensees how to obtain it in a reasonable manner
126 *		      on or through a medium customarily used for
127 *		      software exchange.
128 *
129 *		When the Program is made available in source code form:
130 *		      a) it must be made available under this Agreement;
131 *		      and
132 *		      b) a copy of this Agreement must be included with
133 *		      each copy of the Program.
134 *
135 *		Contributors may not remove or alter any copyright notices
136 *		contained within the Program.
137 *
138 *		Each Contributor must identify itself as the originator of
139 *		its Contribution, if any, in a manner that reasonably
140 *		allows subsequent Recipients to identify the originator of
141 *		the Contribution.
142 *
143 *
144 *		4. COMMERCIAL DISTRIBUTION
145 *
146 *		Commercial distributors of software may accept certain
147 *		responsibilities with respect to end users, business
148 *		partners and the like. While this license is intended to
149 *		facilitate the commercial use of the Program, the
150 *		Contributor who includes the Program in a commercial
151 *		product offering should do so in a manner which does not
152 *		create potential liability for other Contributors.
153 *		Therefore, if a Contributor includes the Program in a
154 *		commercial product offering, such Contributor ("Commercial
155 *		Contributor") hereby agrees to defend and indemnify every
156 *		other Contributor ("Indemnified Contributor") against any
157 *		losses, damages and costs (collectively "Losses") arising
158 *		from claims, lawsuits and other legal actions brought by a
159 *		third party against the Indemnified Contributor to the
160 *		extent caused by the acts or omissions of such Commercial
161 *		Contributor in connection with its distribution of the
162 *		Program in a commercial product offering. The obligations
163 *		in this section do not apply to any claims or Losses
164 *		relating to any actual or alleged intellectual property
165 *		infringement. In order to qualify, an Indemnified
166 *		Contributor must: a) promptly notify the Commercial
167 *		Contributor in writing of such claim, and b) allow the
168 *		Commercial Contributor to control, and cooperate with the
169 *		Commercial Contributor in, the defense and any related
170 *		settlement negotiations. The Indemnified Contributor may
171 *		participate in any such claim at its own expense.
172 *
173 *
174 *		For example, a Contributor might include the Program in a
175 *		commercial product offering, Product X. That Contributor
176 *		is then a Commercial Contributor. If that Commercial
177 *		Contributor then makes performance claims, or offers
178 *		warranties related to Product X, those performance claims
179 *		and warranties are such Commercial Contributor's
180 *		responsibility alone. Under this section, the Commercial
181 *		Contributor would have to defend claims against the other
182 *		Contributors related to those performance claims and
183 *		warranties, and if a court requires any other Contributor
184 *		to pay any damages as a result, the Commercial Contributor
185 *		must pay those damages.
186 *
187 *
188 *		5. NO WARRANTY
189 *
190 *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
191 *		PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
192 *		WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
193 *		IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
194 *		CONDITIONS OF TITLE, NO - INFRINGEMENT, MERCHANTABILITY OR
195 *		FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
196 *		responsible for determining the appropriateness of using
197 *		and distributing the Program and assumes all risks
198 *		associated with its exercise of rights under this
199 *		Agreement, including but not limited to the risks and
200 *		costs of program errors, compliance with applicable laws,
201 *		damage to or loss of data, programs or equipment, and
202 *		unavailability or interruption of operations.
203 *
204 *		6. DISCLAIMER OF LIABILITY
205 *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
206 *		RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
207 *		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
208 *		OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
209 *		LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
210 *		LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
211 *		(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
212 *		OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
213 *		OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
214 *		POSSIBILITY OF SUCH DAMAGES.
215 *
216 *		7. GENERAL
217 *
218 *		If any provision of this Agreement is invalid or
219 *		unenforceable under applicable law, it shall not affect
220 *		the validity or enforceability of the remainder of the
221 *		terms of this Agreement, and without further action by the
222 *		parties hereto, such provision shall be reformed to the
223 *		minimum extent necessary to make such provision valid and
224 *		enforceable.
225 *
226 *
227 *		If Recipient institutes patent litigation against a
228 *		Contributor with respect to a patent applicable to
229 *		software (including a cros - claim or counterclaim in a
230 *		lawsuit), then any patent licenses granted by that
231 *		Contributor to such Recipient under this Agreement shall
232 *		terminate as of the date such litigation is filed. In
233 *		addition, If Recipient institutes patent litigation
234 *		against any entity (including a cros - claim or
235 *		counterclaim in a lawsuit) alleging that the Program
236 *		itself (excluding combinations of the Program with other
237 *		software or hardware) infringes such Recipient's
238 *		patent(s), then such Recipient's rights granted under
239 *		Section 2(b) shall terminate as of the date such
240 *		litigation is filed.
241 *
242 *		All Recipient's rights under this Agreement shall
243 *		terminate if it fails to comply with any of the material
244 *		terms or conditions of this Agreement and does not cure
245 *		such failure in a reasonable period of time after becoming
246 *		aware of such noncompliance. If all Recipient's rights
247 *		under this Agreement terminate, Recipient agrees to cease
248 *		use and distribution of the Program as soon as reasonably
249 *		practicable. However, Recipient's obligations under this
250 *		Agreement and any licenses granted by Recipient relating
251 *		to the Program shall continue and survive.
252 *
253 *		Everyone is permitted to copy and distribute copies of
254 *		this Agreement, but in order to avoid inconsistency the
255 *		Agreement is copyrighted and may only be modified in the
256 *		following manner. The Agreement Steward reserves the right
257 *		to publish new versions (including revisions) of this
258 *		Agreement from time to time. No one other than the
259 *		Agreement Steward has the right to modify this Agreement.
260 *
261 *		IBM is the initial Agreement Steward. IBM may assign the
262 *		responsibility to serve as the Agreement Steward to a
263 *		suitable separate entity. Each new version of the
264 *		Agreement will be given a distinguishing version number.
265 *		The Program (including Contributions) may always be
266 *		distributed subject to the version of the Agreement under
267 *		which it was received. In addition, after a new version of
268 *		the Agreement is published, Contributor may elect to
269 *		distribute the Program (including its Contributions) under
270 *		the new version. Except as expressly stated in Sections
271 *		2(a) and 2(b) above, Recipient receives no rights or
272 *		licenses to the intellectual property of any Contributor
273 *		under this Agreement, whether expressly, by implication,
274 *		estoppel or otherwise. All rights in the Program not
275 *		expressly granted under this Agreement are reserved.
276 *
277 *
278 *		This Agreement is governed by the laws of the State of New
279 *		York and the intellectual property laws of the United
280 *		States of America. No party to this Agreement will bring a
281 *		legal action under this Agreement more than one year after
282 *		the cause of action arose. Each party waives its rights to
283 *		a jury trial in any resulting litigation.
284 *
285 *
286 *
287 * (C) COPYRIGHT International Business Machines Corp. 2001, 2002
288 */
289/*
290 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
291 * Use is subject to license terms.
292 */
293
294#include "tpmtok_int.h"
295
296#define	LOG(x)  logit(LOG_DEBUG, x)
297
298/*
299 * NOTES:
300 * In many cases the specificaiton does not allow returns
301 * of CKR_ARGUMENTSB_BAD.  We break the spec, since validation of parameters
302 * to the function are best represented by this return code (where
303 * specific RC's such as CKR_INVALID_SESSION do not exist).
304 * NOTE NOTE NOTE NOTE
305 *    The parameter checking on the update operations may need to be
306 *    modified (as well as the encrypt/decrypt) to call the std API
307 *    anyway with sanatized parameters since on error, the encrypt/decrypt
308 *    sign operations are all supposed to complete.
309 *    Therefor the parameter checking here might need to be done in
310 *    the STDLL instead of the API.
311 *    This would affect ALL the Multipart operations which have
312 *    an init followed by one or more operations.
313 *
314 * Globals for the API
315 */
316API_Proc_Struct_t  *Anchor = NULL;
317static unsigned int   Initialized = 0;
318static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
319struct ST_FCN_LIST FuncList;
320CK_FUNCTION_LIST PK11_Functions;
321extern pthread_rwlock_t obj_list_rw_mutex;
322
323
324static void
325tpmtoken_fork_prepare()
326{
327	(void) pthread_mutex_lock(&global_mutex);
328	(void) pthread_mutex_lock(&pkcs_mutex);
329	(void) pthread_mutex_lock(&obj_list_mutex);
330	(void) pthread_rwlock_wrlock(&obj_list_rw_mutex);
331	(void) pthread_mutex_lock(&sess_list_mutex);
332	(void) pthread_mutex_lock(&login_mutex);
333	if (Anchor) {
334		(void) pthread_mutex_lock(&Anchor->ProcMutex);
335		(void) pthread_mutex_lock(&Anchor->SessListMutex);
336	}
337}
338
339static void
340tpmtoken_fork_parent()
341{
342	if (Anchor) {
343		(void) pthread_mutex_unlock(&Anchor->SessListMutex);
344		(void) pthread_mutex_unlock(&Anchor->ProcMutex);
345	}
346	(void) pthread_mutex_unlock(&login_mutex);
347	(void) pthread_mutex_unlock(&sess_list_mutex);
348	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
349	(void) pthread_mutex_unlock(&obj_list_mutex);
350	(void) pthread_mutex_unlock(&pkcs_mutex);
351	(void) pthread_mutex_unlock(&global_mutex);
352}
353
354static void
355tpmtoken_fork_child()
356{
357	if (Anchor) {
358		(void) pthread_mutex_unlock(&Anchor->SessListMutex);
359		(void) pthread_mutex_unlock(&Anchor->ProcMutex);
360	}
361
362	(void) pthread_mutex_unlock(&login_mutex);
363	(void) pthread_mutex_unlock(&sess_list_mutex);
364	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
365	(void) pthread_mutex_unlock(&obj_list_mutex);
366	(void) pthread_mutex_unlock(&pkcs_mutex);
367	(void) pthread_mutex_unlock(&global_mutex);
368
369	if (Anchor) {
370		Terminate_All_Process_Sessions();
371		free(Anchor);
372		Anchor = NULL;
373	}
374	if (FuncList.ST_Finalize)
375		FuncList.ST_Finalize(0);
376
377	logterm();
378	loginit();
379}
380
381/*ARGSUSED*/
382CK_RV
383C_CancelFunction(CK_SESSION_HANDLE hSession)
384{
385	LOG("C_CancelFunction");
386	if (API_Initialized() == FALSE) {
387		return (CKR_CRYPTOKI_NOT_INITIALIZED);
388	}
389	return (CKR_FUNCTION_NOT_PARALLEL);
390}
391
392CK_RV
393C_CloseAllSessions(CK_SLOT_ID slotID)
394{
395	Session_Struct_t *pCur, *pPrev;
396	CK_RV    rv;
397	/*
398	 * Although why does modutil do a close all sessions.  It is a single
399	 * application it can only close its sessions...
400	 * And all sessions should be closed anyhow.
401	 */
402	LOG("CloseAllSessions");
403	if (API_Initialized() == FALSE)
404		return (CKR_CRYPTOKI_NOT_INITIALIZED);
405
406	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
407		return (CKR_SLOT_ID_INVALID);
408	/*
409	 * Proc Mutex is locked when we remove from the seesion list in
410	 * Close SEssion.  Therefore we don't need to do any locking
411	 * the atomic operations are controled when we use the linked list
412	 */
413	pCur = (Anchor ? Anchor->SessListBeg : NULL);
414	while (pCur) {
415		/*
416		 * Session owned by the slot we are working on
417		 * There is a basic problem here.  We are using th pCur
418		 * to point to the current one, however we delete it from
419		 * the linked list and can no longer go Forward.  So we
420		 * have to use the fact that this is a doubly linked list
421		 * and get the previous pointer.  After deletion, the next
422		 * pointer of this block will point to the next one in the
423		 * list.
424		 * If the value is Null, then this was the first one in
425		 * the list and we just set pCur to the SessListBeg.
426		 */
427		if (pCur->SltId == slotID) {
428			pPrev = pCur->Previous;
429			rv = C_CloseSession((CK_SESSION_HANDLE)pCur);
430			if (rv == CKR_OK ||
431			    rv == CKR_SESSION_CLOSED ||
432			    rv == CKR_SESSION_HANDLE_INVALID) {
433				if (pPrev == NULL) {
434					pCur = Anchor->SessListBeg;
435				} else {
436					pCur = pPrev->Next;
437				}
438			} else {
439				return (rv);
440			}
441		} else {
442			pCur = pCur->Next;
443		}
444	}
445	LOG("CloseAllSessions OK");
446	return (CKR_OK);
447}
448CK_RV
449C_CloseSession(CK_SESSION_HANDLE hSession)
450{
451	CK_RV rv;
452	Session_Struct_t *sessp;
453	ST_SESSION_T rSession;
454	LOG("C_CloseSession");
455	if (API_Initialized() == FALSE) {
456		return (CKR_CRYPTOKI_NOT_INITIALIZED);
457	}
458	/* Validate Session */
459	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
460		return (CKR_SESSION_HANDLE_INVALID);
461	}
462
463	if (FuncList.ST_CloseSession) {
464		/* Map the Session to the slot session */
465		rv = FuncList.ST_CloseSession(rSession);
466
467		if (rv == CKR_OK) {
468			sessp = (Session_Struct_t *)hSession;
469			RemoveFromSessionList(sessp);
470		}
471	} else {
472		rv = CKR_FUNCTION_NOT_SUPPORTED;
473	}
474	return (rv);
475}
476
477CK_RV
478C_CopyObject(
479	CK_SESSION_HANDLE	hSession,
480	CK_OBJECT_HANDLE	hObject,
481	CK_ATTRIBUTE_PTR	pTemplate,
482	CK_ULONG		ulCount,
483	CK_OBJECT_HANDLE_PTR	phNewObject)
484{
485	CK_RV rv;
486	ST_SESSION_T rSession;
487	LOG("C_CopyObject");
488	if (API_Initialized() == FALSE) {
489		return (CKR_CRYPTOKI_NOT_INITIALIZED);
490	}
491	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
492		return (CKR_SESSION_HANDLE_INVALID);
493	}
494	if (!phNewObject) {
495		return (CKR_ARGUMENTS_BAD);
496	}
497	/*
498	 * A null template with a count will cause the lower layer
499	 * to have problems.
500	 * Template with 0 count is not a problem.
501	 */
502	if (!pTemplate && ulCount) {
503		return (CKR_ARGUMENTS_BAD);
504	}
505	if (FuncList.ST_CopyObject) {
506		rv = FuncList.ST_CopyObject(rSession, hObject, pTemplate,
507		    ulCount, phNewObject);
508	} else {
509		rv = CKR_FUNCTION_NOT_SUPPORTED;
510	}
511	return (rv);
512}
513
514CK_RV
515C_CreateObject(
516	CK_SESSION_HANDLE	hSession,
517	CK_ATTRIBUTE_PTR	pTemplate,
518	CK_ULONG		ulCount,
519	CK_OBJECT_HANDLE_PTR	phObject)
520{
521	CK_RV	rv;
522	ST_SESSION_T rSession;
523
524	if (API_Initialized() == FALSE) {
525		return (CKR_CRYPTOKI_NOT_INITIALIZED);
526	}
527	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
528		return (CKR_SESSION_HANDLE_INVALID);
529	}
530	if (! pTemplate) {
531		return (CKR_TEMPLATE_INCOMPLETE);
532	}
533	if (ulCount == 0) {
534		return (CKR_TEMPLATE_INCOMPLETE);
535	}
536	if (! phObject) {
537		return (CKR_ARGUMENTS_BAD);
538	}
539	if (FuncList.ST_CreateObject) {
540		// Map the Session to the slot session
541		rv = FuncList.ST_CreateObject(rSession, pTemplate,
542		    ulCount, phObject);
543	} else {
544		rv = CKR_FUNCTION_NOT_SUPPORTED;
545	}
546	return (rv);
547}
548
549CK_RV
550C_Decrypt(CK_SESSION_HANDLE hSession,
551	CK_BYTE_PTR	pEncryptedData,
552	CK_ULONG	ulEncryptedDataLen,
553	CK_BYTE_PTR	pData,
554	CK_ULONG_PTR	pulDataLen)
555{
556	CK_RV	rv;
557	ST_SESSION_T rSession;
558
559	if (API_Initialized() == FALSE) {
560		return (CKR_CRYPTOKI_NOT_INITIALIZED);
561	}
562	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
563		return (CKR_SESSION_HANDLE_INVALID);
564	}
565	if (FuncList.ST_Decrypt) {
566		rv = FuncList.ST_Decrypt(rSession, pEncryptedData,
567		    ulEncryptedDataLen, pData, pulDataLen);
568	} else {
569		rv = CKR_FUNCTION_NOT_SUPPORTED;
570	}
571	return (rv);
572}
573
574CK_RV
575C_DecryptDigestUpdate(
576	CK_SESSION_HANDLE hSession,
577	CK_BYTE_PTR	pEncryptedPart,
578	CK_ULONG	ulEncryptedPartLen,
579	CK_BYTE_PTR	pPart,
580	CK_ULONG_PTR	pulPartLen)
581{
582	CK_RV	rv;
583	ST_SESSION_T rSession;
584
585	if (API_Initialized() == FALSE) {
586		return (CKR_CRYPTOKI_NOT_INITIALIZED);
587	}
588	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
589		return (CKR_SESSION_HANDLE_INVALID);
590	}
591	if (! pEncryptedPart || ! pulPartLen) {
592		return (CKR_ARGUMENTS_BAD);
593	}
594	if (FuncList.ST_DecryptDigestUpdate) {
595		rv = FuncList.ST_DecryptDigestUpdate(rSession, pEncryptedPart,
596		    ulEncryptedPartLen, pPart, pulPartLen);
597	} else {
598		rv = CKR_FUNCTION_NOT_SUPPORTED;
599	}
600	return (rv);
601}
602
603CK_RV
604C_DecryptFinal(CK_SESSION_HANDLE hSession,
605	CK_BYTE_PTR	pLastPart,
606	CK_ULONG_PTR	pulLastPartLen)
607{
608	CK_RV	rv;
609	ST_SESSION_T rSession;
610
611	if (API_Initialized() == FALSE) {
612		return (CKR_CRYPTOKI_NOT_INITIALIZED);
613	}
614	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
615		return (CKR_SESSION_HANDLE_INVALID);
616	}
617	/*
618	 * It is acceptable to have a Null pointer for the data since
619	 * it is trying to get the length of the last part....
620	 * The spec is unclear if a second call to Final is needed
621	 * if there is no data in the last part.
622	 */
623	if (! pulLastPartLen) {
624		return (CKR_ARGUMENTS_BAD);
625	}
626	if (FuncList.ST_DecryptFinal) {
627		rv = FuncList.ST_DecryptFinal(rSession, pLastPart,
628		    pulLastPartLen);
629	} else {
630		rv = CKR_FUNCTION_NOT_SUPPORTED;
631	}
632	return (rv);
633}
634
635CK_RV
636C_DecryptInit(CK_SESSION_HANDLE hSession,
637	CK_MECHANISM_PTR pMechanism,
638	CK_OBJECT_HANDLE hKey)
639{
640	CK_RV rv;
641	ST_SESSION_T rSession;
642
643	if (API_Initialized() == FALSE) {
644		return (CKR_CRYPTOKI_NOT_INITIALIZED);
645	}
646	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
647		return (CKR_SESSION_HANDLE_INVALID);
648	}
649	if (! pMechanism) {
650		return (CKR_MECHANISM_INVALID);
651	}
652	if (FuncList.ST_DecryptInit) {
653		rv = FuncList.ST_DecryptInit(rSession, pMechanism, hKey);
654	} else {
655		rv = CKR_FUNCTION_NOT_SUPPORTED;
656	}
657	return (rv);
658}
659
660CK_RV
661C_DecryptUpdate(CK_SESSION_HANDLE hSession,
662	CK_BYTE_PTR	pEncryptedPart,
663	CK_ULONG	ulEncryptedPartLen,
664	CK_BYTE_PTR	pPart,
665	CK_ULONG_PTR	pulPartLen)
666{
667	CK_RV	rv;
668	ST_SESSION_T rSession;
669
670	if (API_Initialized() == FALSE) {
671		return (CKR_CRYPTOKI_NOT_INITIALIZED);
672	}
673	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
674		return (CKR_SESSION_HANDLE_INVALID);
675	}
676	if (!pEncryptedPart || !pulPartLen) {
677		return (CKR_ARGUMENTS_BAD);
678	}
679	if (FuncList.ST_DecryptUpdate) {
680		rv = FuncList.ST_DecryptUpdate(rSession, pEncryptedPart,
681		    ulEncryptedPartLen, pPart, pulPartLen);
682	} else {
683		rv = CKR_FUNCTION_NOT_SUPPORTED;
684	}
685	return (rv);
686}
687
688CK_RV
689C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
690	CK_BYTE_PTR	pEncryptedPart,
691	CK_ULONG	ulEncryptedPartLen,
692	CK_BYTE_PTR	pPart,
693	CK_ULONG_PTR	pulPartLen)
694{
695	CK_RV	rv;
696	ST_SESSION_T rSession;
697
698	if (API_Initialized() == FALSE) {
699		return (CKR_CRYPTOKI_NOT_INITIALIZED);
700	}
701	// Validate Session
702	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
703		return (CKR_SESSION_HANDLE_INVALID);
704	}
705	// May have to let these go through and let the STDLL handle them
706	if (! pEncryptedPart || ! pulPartLen) {
707		return (CKR_ARGUMENTS_BAD);
708	}
709	// Get local pointers to session
710	if (FuncList.ST_DecryptVerifyUpdate) {
711		// Map the Session to the slot session
712		rv = FuncList.ST_DecryptVerifyUpdate(rSession,
713		    pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
714	} else {
715		rv = CKR_FUNCTION_NOT_SUPPORTED;
716	}
717	return (rv);
718}
719
720CK_RV
721C_DeriveKey(CK_SESSION_HANDLE	hSession,
722	CK_MECHANISM_PTR	pMechanism,
723	CK_OBJECT_HANDLE	hBaseKey,
724	CK_ATTRIBUTE_PTR	pTemplate,
725	CK_ULONG		ulAttributeCount,
726	CK_OBJECT_HANDLE_PTR	phKey)
727{
728	CK_RV	rv;
729	ST_SESSION_T rSession;
730
731	if (API_Initialized() == FALSE) {
732		return (CKR_CRYPTOKI_NOT_INITIALIZED);
733	}
734	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
735		return (CKR_SESSION_HANDLE_INVALID);
736	}
737
738	if (!pMechanism) {
739		return (CKR_MECHANISM_INVALID);
740	}
741	if (!pTemplate && ulAttributeCount) {
742		return (CKR_ARGUMENTS_BAD);
743	}
744	if (FuncList.ST_DeriveKey) {
745		rv = FuncList.ST_DeriveKey(rSession, pMechanism,
746		    hBaseKey, pTemplate, ulAttributeCount, phKey);
747	} else {
748		rv = CKR_FUNCTION_NOT_SUPPORTED;
749	}
750	return (rv);
751}
752
753CK_RV
754C_DestroyObject(CK_SESSION_HANDLE hSession,
755	CK_OBJECT_HANDLE hObject)
756{
757	CK_RV rv;
758	ST_SESSION_T rSession;
759
760	if (API_Initialized() == FALSE) {
761		return (CKR_CRYPTOKI_NOT_INITIALIZED);
762	}
763	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
764		return (CKR_SESSION_HANDLE_INVALID);
765	}
766	if (FuncList.ST_DestroyObject) {
767		rv = FuncList.ST_DestroyObject(rSession, hObject);
768	} else {
769		rv = CKR_FUNCTION_NOT_SUPPORTED;
770	}
771	return (rv);
772}
773
774CK_RV
775C_Digest(CK_SESSION_HANDLE hSession,
776	CK_BYTE_PTR	pData,
777	CK_ULONG	ulDataLen,
778	CK_BYTE_PTR	pDigest,
779	CK_ULONG_PTR	pulDigestLen)
780{
781	CK_RV	rv;
782	ST_SESSION_T rSession;
783
784	if (API_Initialized() == FALSE) {
785		return (CKR_CRYPTOKI_NOT_INITIALIZED);
786	}
787	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
788		return (CKR_SESSION_HANDLE_INVALID);
789	}
790	if (FuncList.ST_Digest) {
791		rv = FuncList.ST_Digest(rSession, pData, ulDataLen,
792		    pDigest, pulDigestLen);
793	} else {
794		rv = CKR_FUNCTION_NOT_SUPPORTED;
795	}
796	return (rv);
797}
798
799CK_RV
800C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
801	CK_BYTE_PTR	pPart,
802	CK_ULONG	ulPartLen,
803	CK_BYTE_PTR	pEncryptedPart,
804	CK_ULONG_PTR	pulEncryptedPartLen)
805{
806	CK_RV rv;
807	ST_SESSION_T rSession;
808
809	if (API_Initialized() == FALSE) {
810		return (CKR_CRYPTOKI_NOT_INITIALIZED);
811	}
812	if (! pPart || ! pulEncryptedPartLen) {
813		return (CKR_ARGUMENTS_BAD);
814	}
815	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
816		return (CKR_SESSION_HANDLE_INVALID);
817	}
818	if (FuncList.ST_DigestEncryptUpdate) {
819		rv = FuncList.ST_DigestEncryptUpdate(rSession, pPart,
820		    ulPartLen, pEncryptedPart, pulEncryptedPartLen);
821	} else {
822		rv = CKR_FUNCTION_NOT_SUPPORTED;
823	}
824	return (rv);
825}
826
827CK_RV
828C_DigestFinal(CK_SESSION_HANDLE hSession,
829	CK_BYTE_PTR	pDigest,
830	CK_ULONG_PTR	pulDigestLen)
831{
832	CK_RV rv;
833	ST_SESSION_T rSession;
834
835	if (API_Initialized() == FALSE) {
836		return (CKR_CRYPTOKI_NOT_INITIALIZED);
837	}
838	if (! pulDigestLen) {
839		return (CKR_ARGUMENTS_BAD);
840	}
841	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
842		return (CKR_SESSION_HANDLE_INVALID);
843	}
844	if (FuncList.ST_DigestFinal) {
845		rv = FuncList.ST_DigestFinal(rSession, pDigest, pulDigestLen);
846	} else {
847		rv = CKR_FUNCTION_NOT_SUPPORTED;
848	}
849	return (rv);
850}
851
852CK_RV
853C_DigestInit(CK_SESSION_HANDLE hSession,
854	CK_MECHANISM_PTR pMechanism)
855{
856	CK_RV rv;
857	ST_SESSION_T rSession;
858
859	if (API_Initialized() == FALSE) {
860		return (CKR_CRYPTOKI_NOT_INITIALIZED);
861	}
862	if (! pMechanism) {
863		return (CKR_MECHANISM_INVALID);
864	}
865	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
866		return (CKR_SESSION_HANDLE_INVALID);
867	}
868	if (FuncList.ST_DigestInit) {
869		rv = FuncList.ST_DigestInit(rSession, pMechanism);
870	} else {
871		rv = CKR_FUNCTION_NOT_SUPPORTED;
872	}
873	return (rv);
874}
875
876CK_RV
877C_DigestKey(CK_SESSION_HANDLE hSession,
878	CK_OBJECT_HANDLE hKey)
879{
880	CK_RV rv;
881	ST_SESSION_T rSession;
882
883	if (API_Initialized() == FALSE) {
884		return (CKR_CRYPTOKI_NOT_INITIALIZED);
885	}
886	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
887		return (CKR_SESSION_HANDLE_INVALID);
888	}
889	if (FuncList.ST_DigestKey) {
890		rv = FuncList.ST_DigestKey(rSession, hKey);
891	} else {
892		rv = CKR_FUNCTION_NOT_SUPPORTED;
893	}
894	return (rv);
895}
896
897CK_RV
898C_DigestUpdate(CK_SESSION_HANDLE hSession,
899	CK_BYTE_PTR pPart,
900	CK_ULONG ulPartLen)
901{
902	CK_RV rv;
903	ST_SESSION_T rSession;
904	if (API_Initialized() == FALSE) {
905		return (CKR_CRYPTOKI_NOT_INITIALIZED);
906	}
907	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
908		return (CKR_SESSION_HANDLE_INVALID);
909	}
910	if (FuncList.ST_DigestUpdate) {
911		rv = FuncList.ST_DigestUpdate(rSession, pPart, ulPartLen);
912	} else {
913		rv = CKR_FUNCTION_NOT_SUPPORTED;
914	}
915	return (rv);
916}
917
918CK_RV
919C_Encrypt(CK_SESSION_HANDLE hSession,
920	CK_BYTE_PTR pData,
921	CK_ULONG ulDataLen,
922	CK_BYTE_PTR pEncryptedData,
923	CK_ULONG_PTR pulEncryptedDataLen)
924{
925	CK_RV rv;
926	ST_SESSION_T rSession;
927
928	if (API_Initialized() == FALSE) {
929		return (CKR_CRYPTOKI_NOT_INITIALIZED);
930	}
931	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
932		return (CKR_SESSION_HANDLE_INVALID);
933	}
934	// Get local pointers to session
935	if (FuncList.ST_Encrypt) {
936		// Map the Session to the slot session
937		rv = FuncList.ST_Encrypt(rSession, pData, ulDataLen,
938		    pEncryptedData, pulEncryptedDataLen);
939	} else {
940		rv = CKR_FUNCTION_NOT_SUPPORTED;
941	}
942	return (rv);
943}
944
945CK_RV
946C_EncryptFinal(CK_SESSION_HANDLE hSession,
947	CK_BYTE_PTR pLastEncryptedPart,
948	CK_ULONG_PTR pulLastEncryptedPartLen)
949{
950	CK_RV rv;
951	ST_SESSION_T rSession;
952
953	if (API_Initialized() == FALSE) {
954		return (CKR_CRYPTOKI_NOT_INITIALIZED);
955	}
956	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
957		return (CKR_SESSION_HANDLE_INVALID);
958	}
959	if (FuncList.ST_EncryptFinal) {
960		rv = FuncList.ST_EncryptFinal(rSession,
961		    pLastEncryptedPart, pulLastEncryptedPartLen);
962	} else {
963		rv = CKR_FUNCTION_NOT_SUPPORTED;
964	}
965	return (rv);
966}
967
968CK_RV
969C_EncryptInit(CK_SESSION_HANDLE hSession,
970	CK_MECHANISM_PTR pMechanism,
971	CK_OBJECT_HANDLE hKey)
972{
973	CK_RV rv;
974	ST_SESSION_T rSession;
975
976	if (API_Initialized() == FALSE) {
977		return (CKR_CRYPTOKI_NOT_INITIALIZED);
978	}
979	if (! pMechanism) {
980		return (CKR_MECHANISM_INVALID);
981	}
982	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
983		return (CKR_SESSION_HANDLE_INVALID);
984	}
985	if (FuncList.ST_EncryptInit) {
986		rv = FuncList.ST_EncryptInit(rSession, pMechanism, hKey);
987	} else {
988		rv = CKR_FUNCTION_NOT_SUPPORTED;
989	}
990	return (rv);
991}
992
993CK_RV
994C_EncryptUpdate(CK_SESSION_HANDLE hSession,
995	CK_BYTE_PTR pPart,
996	CK_ULONG ulPartLen,
997	CK_BYTE_PTR pEncryptedPart,
998	CK_ULONG_PTR pulEncryptedPartLen)
999{
1000	CK_RV rv;
1001	ST_SESSION_T rSession;
1002
1003	if (API_Initialized() == FALSE) {
1004		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1005	}
1006	if (!pPart || !pulEncryptedPartLen) {
1007		return (CKR_ARGUMENTS_BAD);
1008	}
1009	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1010		return (CKR_SESSION_HANDLE_INVALID);
1011	}
1012	if (FuncList.ST_EncryptUpdate) {
1013		rv = FuncList.ST_EncryptUpdate(rSession, pPart, ulPartLen,
1014		    pEncryptedPart, pulEncryptedPartLen);
1015	} else {
1016		rv = CKR_FUNCTION_NOT_SUPPORTED;
1017	}
1018	return (rv);
1019}
1020
1021CK_RV
1022do_finalize(CK_VOID_PTR pReserved)
1023{
1024	if (API_Initialized() == FALSE) {
1025		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1026	}
1027	if (pReserved != NULL) {
1028		return (CKR_ARGUMENTS_BAD);
1029	}
1030	(void) pthread_mutex_lock(&global_mutex);
1031	if (Anchor)
1032		Terminate_All_Process_Sessions();
1033
1034	if (FuncList.ST_Finalize)
1035		FuncList.ST_Finalize(0);
1036
1037	free(Anchor);
1038	Anchor = NULL;
1039
1040	(void) pthread_mutex_unlock(&global_mutex);
1041	return (CKR_OK);
1042}
1043
1044CK_RV
1045C_Finalize(CK_VOID_PTR pReserved) {
1046	return (do_finalize(pReserved));
1047}
1048
1049CK_RV
1050C_FindObjects(CK_SESSION_HANDLE    hSession,
1051	CK_OBJECT_HANDLE_PTR phObject,
1052	CK_ULONG ulMaxObjectCount,
1053	CK_ULONG_PTR pulObjectCount)
1054{
1055	CK_RV rv;
1056	ST_SESSION_T rSession;
1057
1058	if (API_Initialized() == FALSE) {
1059		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1060	}
1061	if (! phObject || ! pulObjectCount) {
1062		return (CKR_ARGUMENTS_BAD);
1063	}
1064	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1065		return (CKR_SESSION_HANDLE_INVALID);
1066	}
1067	if (FuncList.ST_FindObjects) {
1068		rv = FuncList.ST_FindObjects(rSession, phObject,
1069		    ulMaxObjectCount, pulObjectCount);
1070	} else {
1071		rv = CKR_FUNCTION_NOT_SUPPORTED;
1072	}
1073	return (rv);
1074}
1075
1076CK_RV
1077C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1078{
1079	CK_RV rv;
1080	ST_SESSION_T rSession;
1081
1082	if (API_Initialized() == FALSE) {
1083		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1084	}
1085	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1086		return (CKR_SESSION_HANDLE_INVALID);
1087	}
1088	if (FuncList.ST_FindObjectsFinal) {
1089		rv = FuncList.ST_FindObjectsFinal(rSession);
1090	} else {
1091		rv = CKR_FUNCTION_NOT_SUPPORTED;
1092	}
1093	return (rv);
1094}
1095
1096CK_RV
1097C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1098	CK_ATTRIBUTE_PTR pTemplate,
1099	CK_ULONG ulCount)
1100{
1101	CK_RV rv;
1102	ST_SESSION_T rSession;
1103
1104	if (API_Initialized() == FALSE) {
1105		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1106	}
1107	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1108		return (CKR_SESSION_HANDLE_INVALID);
1109	}
1110	if (FuncList.ST_FindObjectsInit) {
1111		rv = FuncList.ST_FindObjectsInit(rSession, pTemplate, ulCount);
1112	} else {
1113		rv = CKR_FUNCTION_NOT_SUPPORTED;
1114	}
1115	return (rv);
1116}
1117
1118CK_RV
1119C_GenerateKey(CK_SESSION_HANDLE    hSession,
1120	CK_MECHANISM_PTR pMechanism,
1121	CK_ATTRIBUTE_PTR pTemplate,
1122	CK_ULONG ulCount,
1123	CK_OBJECT_HANDLE_PTR phKey)
1124{
1125	CK_RV rv;
1126	ST_SESSION_T rSession;
1127
1128	if (API_Initialized() == FALSE) {
1129		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1130	}
1131	if (! pMechanism) {
1132		return (CKR_MECHANISM_INVALID);
1133	}
1134	if (! phKey) {
1135		return (CKR_ARGUMENTS_BAD);
1136	}
1137	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1138		return (CKR_SESSION_HANDLE_INVALID);
1139	}
1140	if (FuncList.ST_GenerateKey) {
1141		rv = FuncList.ST_GenerateKey(rSession, pMechanism,
1142		    pTemplate, ulCount, phKey);
1143	} else {
1144		rv = CKR_FUNCTION_NOT_SUPPORTED;
1145	}
1146	return (rv);
1147}
1148
1149CK_RV
1150C_GenerateKeyPair(CK_SESSION_HANDLE    hSession,
1151	CK_MECHANISM_PTR pMechanism,
1152	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
1153	CK_ULONG ulPublicKeyAttributeCount,
1154	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
1155	CK_ULONG ulPrivateKeyAttributeCount,
1156	CK_OBJECT_HANDLE_PTR phPublicKey,
1157	CK_OBJECT_HANDLE_PTR phPrivateKey)
1158{
1159	CK_RV rv;
1160	ST_SESSION_T rSession;
1161
1162	if (API_Initialized() == FALSE) {
1163		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1164	}
1165	if (! pMechanism) {
1166		return (CKR_MECHANISM_INVALID);
1167	}
1168	if (! phPublicKey || ! phPrivateKey) {
1169		return (CKR_ARGUMENTS_BAD);
1170	}
1171	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1172		return (CKR_SESSION_HANDLE_INVALID);
1173	}
1174	if (FuncList.ST_GenerateKeyPair) {
1175		rv = FuncList.ST_GenerateKeyPair(rSession,
1176		    pMechanism, pPublicKeyTemplate,
1177		    ulPublicKeyAttributeCount, pPrivateKeyTemplate,
1178		    ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey);
1179	} else {
1180		rv = CKR_FUNCTION_NOT_SUPPORTED;
1181	}
1182	return (rv);
1183}
1184
1185CK_RV
1186C_GenerateRandom(CK_SESSION_HANDLE hSession,
1187	CK_BYTE_PTR RandomData,
1188	CK_ULONG ulRandomLen)
1189{
1190	CK_RV rv;
1191	ST_SESSION_T rSession;
1192
1193	if (API_Initialized() == FALSE) {
1194		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1195	}
1196	if (! RandomData)
1197		return (CKR_ARGUMENTS_BAD);
1198
1199	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1200		return (CKR_SESSION_HANDLE_INVALID);
1201	}
1202	if (FuncList.ST_GenerateRandom) {
1203		rv = FuncList.ST_GenerateRandom(rSession, RandomData,
1204		    ulRandomLen);
1205	} else {
1206		rv = CKR_FUNCTION_NOT_SUPPORTED;
1207	}
1208	return (rv);
1209}
1210
1211CK_RV
1212C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1213	CK_OBJECT_HANDLE hObject,
1214	CK_ATTRIBUTE_PTR pTemplate,
1215	CK_ULONG ulCount)
1216{
1217	CK_RV rv;
1218	ST_SESSION_T rSession;
1219
1220	if (API_Initialized() == FALSE) {
1221		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1222	}
1223	if (! pTemplate) {
1224		return (CKR_TEMPLATE_INCOMPLETE);
1225	}
1226	if (ulCount == 0) {
1227		return (CKR_TEMPLATE_INCOMPLETE);
1228	}
1229	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1230		return (CKR_SESSION_HANDLE_INVALID);
1231	}
1232	if (FuncList.ST_GetAttributeValue) {
1233		rv = FuncList.ST_GetAttributeValue(rSession, hObject,
1234		    pTemplate, ulCount);
1235	} else {
1236		rv = CKR_FUNCTION_NOT_SUPPORTED;
1237	}
1238	return (rv);
1239}
1240
1241CK_RV
1242C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
1243{
1244	PK11_Functions.version.major = VERSION_MAJOR;
1245	PK11_Functions.version.minor = VERSION_MINOR;
1246	PK11_Functions.C_Initialize = C_Initialize;
1247	PK11_Functions.C_Finalize = C_Finalize;
1248	PK11_Functions.C_GetInfo = C_GetInfo;
1249	PK11_Functions.C_GetFunctionList = C_GetFunctionList;
1250	PK11_Functions.C_GetSlotList = C_GetSlotList;
1251	PK11_Functions.C_GetSlotInfo = C_GetSlotInfo;
1252	PK11_Functions.C_GetTokenInfo = C_GetTokenInfo;
1253	PK11_Functions.C_GetMechanismList = C_GetMechanismList;
1254	PK11_Functions.C_GetMechanismInfo = C_GetMechanismInfo;
1255	PK11_Functions.C_InitToken = C_InitToken;
1256	PK11_Functions.C_InitPIN = C_InitPIN;
1257	PK11_Functions.C_SetPIN = C_SetPIN;
1258	PK11_Functions.C_OpenSession = C_OpenSession;
1259	PK11_Functions.C_CloseSession = C_CloseSession;
1260	PK11_Functions.C_CloseAllSessions = C_CloseAllSessions;
1261	PK11_Functions.C_GetSessionInfo = C_GetSessionInfo;
1262	PK11_Functions.C_GetOperationState = C_GetOperationState;
1263	PK11_Functions.C_SetOperationState = C_SetOperationState;
1264	PK11_Functions.C_Login = C_Login;
1265	PK11_Functions.C_Logout = C_Logout;
1266	PK11_Functions.C_CreateObject = C_CreateObject;
1267	PK11_Functions.C_CopyObject = C_CopyObject;
1268	PK11_Functions.C_DestroyObject = C_DestroyObject;
1269	PK11_Functions.C_GetObjectSize = C_GetObjectSize;
1270	PK11_Functions.C_GetAttributeValue = C_GetAttributeValue;
1271	PK11_Functions.C_SetAttributeValue = C_SetAttributeValue;
1272	PK11_Functions.C_FindObjectsInit = C_FindObjectsInit;
1273	PK11_Functions.C_FindObjects = C_FindObjects;
1274	PK11_Functions.C_FindObjectsFinal = C_FindObjectsFinal;
1275	PK11_Functions.C_EncryptInit = C_EncryptInit;
1276	PK11_Functions.C_Encrypt = C_Encrypt;
1277	PK11_Functions.C_EncryptUpdate = C_EncryptUpdate;
1278	PK11_Functions.C_EncryptFinal = C_EncryptFinal;
1279	PK11_Functions.C_DecryptInit = C_DecryptInit;
1280	PK11_Functions.C_Decrypt = C_Decrypt;
1281	PK11_Functions.C_DecryptUpdate = C_DecryptUpdate;
1282	PK11_Functions.C_DecryptFinal = C_DecryptFinal;
1283	PK11_Functions.C_DigestInit = C_DigestInit;
1284	PK11_Functions.C_Digest = C_Digest;
1285	PK11_Functions.C_DigestUpdate = C_DigestUpdate;
1286	PK11_Functions.C_DigestKey = C_DigestKey;
1287	PK11_Functions.C_DigestFinal = C_DigestFinal;
1288	PK11_Functions.C_SignInit = C_SignInit;
1289	PK11_Functions.C_Sign = C_Sign;
1290	PK11_Functions.C_SignUpdate = C_SignUpdate;
1291	PK11_Functions.C_SignFinal = C_SignFinal;
1292	PK11_Functions.C_SignRecoverInit = C_SignRecoverInit;
1293	PK11_Functions.C_SignRecover = C_SignRecover;
1294	PK11_Functions.C_VerifyInit = C_VerifyInit;
1295	PK11_Functions.C_Verify = C_Verify;
1296	PK11_Functions.C_VerifyUpdate = C_VerifyUpdate;
1297	PK11_Functions.C_VerifyFinal = C_VerifyFinal;
1298	PK11_Functions.C_VerifyRecoverInit = C_VerifyRecoverInit;
1299	PK11_Functions.C_VerifyRecover = C_VerifyRecover;
1300	PK11_Functions.C_DigestEncryptUpdate = C_DigestEncryptUpdate;
1301	PK11_Functions.C_DecryptDigestUpdate = C_DecryptDigestUpdate;
1302	PK11_Functions.C_SignEncryptUpdate = C_SignEncryptUpdate;
1303	PK11_Functions.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate;
1304	PK11_Functions.C_GenerateKey = C_GenerateKey;
1305	PK11_Functions.C_GenerateKeyPair = C_GenerateKeyPair;
1306	PK11_Functions.C_WrapKey = C_WrapKey;
1307	PK11_Functions.C_UnwrapKey = C_UnwrapKey;
1308	PK11_Functions.C_DeriveKey = C_DeriveKey;
1309	PK11_Functions.C_SeedRandom = C_SeedRandom;
1310	PK11_Functions.C_GenerateRandom = C_GenerateRandom;
1311	PK11_Functions.C_GetFunctionStatus = C_GetFunctionStatus;
1312	PK11_Functions.C_CancelFunction = C_CancelFunction;
1313	PK11_Functions.C_WaitForSlotEvent = C_WaitForSlotEvent;
1314	if (ppFunctionList) {
1315		(*ppFunctionList) = &PK11_Functions;
1316		return (CKR_OK);
1317	} else {
1318		return (CKR_ARGUMENTS_BAD);
1319	}
1320}
1321
1322/*ARGSUSED*/
1323CK_RV
1324C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
1325{
1326	if (API_Initialized() == FALSE) {
1327		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1328	}
1329	return (CKR_FUNCTION_NOT_PARALLEL); // PER Specification PG 170
1330}
1331
1332CK_RV
1333C_GetInfo(CK_INFO_PTR pInfo)
1334{
1335	TOKEN_DATA td;
1336	TSS_HCONTEXT hContext;
1337
1338	if (! API_Initialized()) {
1339		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1340	}
1341	if (! pInfo) {
1342		return (CKR_FUNCTION_FAILED);
1343	}
1344	(void) memset(pInfo, 0, sizeof (*pInfo));
1345	pInfo->cryptokiVersion.major = 2;
1346	pInfo->cryptokiVersion.minor = 20;
1347
1348	if (open_tss_context(&hContext) == 0) {
1349		/*
1350		 * Only populate the TPM info if we can establish
1351		 * a context, but don't return failure because
1352		 * the framework needs to know some of the info.
1353		 */
1354		(void) token_get_tpm_info(hContext, &td);
1355
1356		(void) Tspi_Context_Close(hContext);
1357
1358		(void) memcpy(pInfo->manufacturerID,
1359		    &(td.token_info.manufacturerID),
1360		    sizeof (pInfo->manufacturerID) - 1);
1361
1362		pInfo->flags = td.token_info.flags;
1363	}
1364	(void) strcpy((char *)pInfo->libraryDescription,
1365	    "PKCS11 Interface for TPM");
1366
1367	pInfo->libraryVersion.major = 1;
1368	pInfo->libraryVersion.minor = 0;
1369
1370	return (CKR_OK);
1371}
1372
1373CK_RV
1374C_GetMechanismInfo(CK_SLOT_ID	slotID,
1375	CK_MECHANISM_TYPE	type,
1376	CK_MECHANISM_INFO_PTR	pInfo)
1377{
1378	CK_RV rv;
1379	if (API_Initialized() == FALSE)
1380		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1381
1382	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1383		return (CKR_SLOT_ID_INVALID);
1384
1385	if (FuncList.ST_GetMechanismInfo) {
1386		rv = FuncList.ST_GetMechanismInfo(slotID, type, pInfo);
1387	} else {
1388		rv = CKR_FUNCTION_NOT_SUPPORTED;
1389	}
1390	return (rv);
1391}
1392
1393CK_RV
1394C_GetMechanismList(CK_SLOT_ID slotID,
1395	CK_MECHANISM_TYPE_PTR pMechanismList,
1396	CK_ULONG_PTR pulCount)
1397{
1398	CK_RV rv;
1399
1400	if (API_Initialized() == FALSE)
1401		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1402
1403	if (! pulCount)
1404		return (CKR_ARGUMENTS_BAD);
1405
1406	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1407		return (CKR_SLOT_ID_INVALID);
1408
1409	if (FuncList.ST_GetMechanismList) {
1410		rv = FuncList.ST_GetMechanismList(slotID,
1411		    pMechanismList, pulCount);
1412	} else {
1413		rv = CKR_FUNCTION_NOT_SUPPORTED;
1414	}
1415	if (rv == CKR_OK) {
1416		if (pMechanismList) {
1417			unsigned long i;
1418			for (i = 0; i < *pulCount; i++) {
1419				logit(LOG_DEBUG, "Mechanism[%d] 0x%08X ",
1420				    i, pMechanismList[i]);
1421			}
1422		}
1423	}
1424	return (rv);
1425}
1426
1427CK_RV
1428C_GetObjectSize(CK_SESSION_HANDLE hSession,
1429	CK_OBJECT_HANDLE hObject,
1430	CK_ULONG_PTR pulSize)
1431{
1432	CK_RV rv;
1433	ST_SESSION_T rSession;
1434
1435	if (API_Initialized() == FALSE) {
1436		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1437	}
1438	if (! pulSize) {
1439		return (CKR_ARGUMENTS_BAD);
1440	}
1441	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1442		return (CKR_SESSION_HANDLE_INVALID);
1443	}
1444	if (FuncList.ST_GetObjectSize) {
1445		rv = FuncList.ST_GetObjectSize(rSession, hObject, pulSize);
1446	} else {
1447		rv = CKR_FUNCTION_NOT_SUPPORTED;
1448	}
1449	return (rv);
1450}
1451
1452CK_RV
1453C_GetOperationState(CK_SESSION_HANDLE hSession,
1454	CK_BYTE_PTR pOperationState,
1455	CK_ULONG_PTR pulOperationStateLen)
1456{
1457	CK_RV rv;
1458	ST_SESSION_T rSession;
1459
1460	if (API_Initialized() == FALSE) {
1461		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1462	}
1463	if (! pulOperationStateLen) {
1464		return (CKR_ARGUMENTS_BAD);
1465	}
1466	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1467		return (CKR_SESSION_HANDLE_INVALID);
1468	}
1469	if (FuncList.ST_GetOperationState) {
1470		rv = FuncList.ST_GetOperationState(rSession,
1471		    pOperationState, pulOperationStateLen);
1472	} else {
1473		rv = CKR_FUNCTION_NOT_SUPPORTED;
1474	}
1475	return (rv);
1476}
1477
1478CK_RV
1479C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1480	CK_SESSION_INFO_PTR pInfo)
1481{
1482	CK_RV rv;
1483	ST_SESSION_T rSession;
1484
1485	if (API_Initialized() == FALSE) {
1486		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1487	}
1488	if (! pInfo) {
1489		return (CKR_ARGUMENTS_BAD);
1490	}
1491	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1492		return (CKR_SESSION_HANDLE_INVALID);
1493	}
1494	if (FuncList.ST_GetSessionInfo) {
1495		rv = FuncList.ST_GetSessionInfo(rSession, pInfo);
1496	} else {
1497		rv = CKR_FUNCTION_NOT_SUPPORTED;
1498	}
1499	return (rv);
1500}
1501
1502CK_RV
1503C_GetSlotInfo(CK_SLOT_ID slotID,
1504	CK_SLOT_INFO_PTR pInfo)
1505{
1506	if (API_Initialized() == FALSE)
1507		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1508
1509	if (!pInfo)
1510		return (CKR_FUNCTION_FAILED);
1511
1512	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1513		return (CKR_SLOT_ID_INVALID);
1514
1515	copy_slot_info(slotID, pInfo);
1516	return (CKR_OK);
1517}
1518
1519/*ARGSUSED*/
1520CK_RV
1521C_GetSlotList(CK_BBOOL tokenPresent,
1522	CK_SLOT_ID_PTR pSlotList,
1523	CK_ULONG_PTR pulCount)
1524{
1525	CK_ULONG count;
1526	CK_SLOT_INFO slotInfo;
1527
1528	if (API_Initialized() == FALSE)
1529		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1530
1531	if (pulCount == NULL)
1532		return (CKR_FUNCTION_FAILED);
1533
1534	count = 0;
1535	/*
1536	 * If we can't talk to the TPM, present no slots
1537	 */
1538	if (!global_shm->token_available) {
1539		*pulCount = 0;
1540		return (CKR_OK);
1541	}
1542
1543	copy_slot_info(TPM_SLOTID, &slotInfo);
1544	if ((slotInfo.flags & CKF_TOKEN_PRESENT))
1545		count++;
1546
1547	*pulCount = count;
1548
1549	if (pSlotList == NULL) {
1550		return (CKR_OK);
1551	} else {
1552		if (*pulCount < count)
1553			return (CKR_BUFFER_TOO_SMALL);
1554		pSlotList[0] = TPM_SLOTID;
1555	}
1556	return (CKR_OK);
1557}
1558
1559CK_RV
1560C_GetTokenInfo(CK_SLOT_ID slotID,
1561	CK_TOKEN_INFO_PTR pInfo)
1562{
1563	CK_RV rv;
1564
1565	if (API_Initialized() == FALSE)
1566		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1567
1568	if (!pInfo)
1569		return (CKR_ARGUMENTS_BAD);
1570
1571	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1572		return (CKR_SLOT_ID_INVALID);
1573
1574	slotID = TPM_SLOTID;
1575	if (FuncList.ST_GetTokenInfo) {
1576		rv = FuncList.ST_GetTokenInfo(slotID, pInfo);
1577	} else {
1578		rv = CKR_FUNCTION_NOT_SUPPORTED;
1579	}
1580	return (rv);
1581}
1582
1583CK_RV
1584C_Initialize(CK_VOID_PTR pVoid)
1585{
1586	CK_RV rv = CKR_OK;
1587	CK_C_INITIALIZE_ARGS *pArg;
1588	extern CK_RV ST_Initialize(void *,
1589	    CK_SLOT_ID, unsigned char *);
1590
1591	(void) pthread_mutex_lock(&global_mutex);
1592	if (! Anchor) {
1593		Anchor = (API_Proc_Struct_t *)malloc(
1594		    sizeof (API_Proc_Struct_t));
1595		if (Anchor == NULL) {
1596			(void) pthread_mutex_unlock(&global_mutex);
1597			return (CKR_HOST_MEMORY);
1598		}
1599	} else {
1600		(void) pthread_mutex_unlock(&global_mutex);
1601		return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
1602	}
1603	/*
1604	 * if pVoid is NULL, then everything is OK.  The applicaiton
1605	 * will not be doing multi thread accesses.  We can use the OS
1606	 * locks anyhow.
1607	 */
1608	if (pVoid != NULL) {
1609		int supplied_ok;
1610		pArg = (CK_C_INITIALIZE_ARGS *)pVoid;
1611
1612		/*
1613		 * ALL supplied function pointers need to have the value
1614		 * either NULL or no - NULL.
1615		 */
1616		supplied_ok = (pArg->CreateMutex == NULL &&
1617		    pArg->DestroyMutex == NULL &&
1618		    pArg->LockMutex == NULL &&
1619		    pArg->UnlockMutex == NULL) ||
1620		    (pArg->CreateMutex != NULL &&
1621		    pArg->DestroyMutex != NULL &&
1622		    pArg->LockMutex != NULL &&
1623		    pArg->UnlockMutex != NULL);
1624
1625		if (!supplied_ok) {
1626			(void) pthread_mutex_unlock(&global_mutex);
1627			return (CKR_ARGUMENTS_BAD);
1628		}
1629		/* Check for a pReserved set */
1630		if (pArg->pReserved != NULL) {
1631			free(Anchor);
1632			Anchor = NULL;
1633			(void) pthread_mutex_unlock(&global_mutex);
1634			return (CKR_ARGUMENTS_BAD);
1635		}
1636		/*
1637		 * When the CKF_OS_LOCKING_OK flag isn't set and mutex
1638		 * function pointers are supplied by an application,
1639		 * return (an error.  We must be able to use our own primitives.
1640		 */
1641		if (!(pArg->flags & CKF_OS_LOCKING_OK) &&
1642		    (pArg->CreateMutex != NULL)) {
1643			(void) pthread_mutex_unlock(&global_mutex);
1644			return (CKR_CANT_LOCK);
1645		}
1646	}
1647	(void) memset((char *)Anchor, 0, sizeof (API_Proc_Struct_t));
1648	(void) pthread_mutex_init(&(Anchor->ProcMutex), NULL);
1649	(void) pthread_mutex_init(&(Anchor->SessListMutex), NULL);
1650	Anchor->Pid = getpid();
1651
1652	rv = ST_Initialize((void *)&FuncList, 0, NULL);
1653	(void) pthread_mutex_unlock(&global_mutex);
1654	return (rv);
1655}
1656
1657CK_RV
1658C_InitPIN(CK_SESSION_HANDLE hSession,
1659	CK_CHAR_PTR pPin,
1660	CK_ULONG ulPinLen)
1661{
1662	CK_RV rv;
1663	ST_SESSION_T rSession;
1664
1665	if (API_Initialized() == FALSE)
1666		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1667
1668	if (! pPin && ulPinLen)
1669		return (CKR_ARGUMENTS_BAD);
1670
1671	if (! Valid_Session((Session_Struct_t *)hSession, &rSession))
1672		return (CKR_SESSION_HANDLE_INVALID);
1673
1674	if (rSession.slotID > NUMBER_SLOTS_MANAGED)
1675		return (CKR_SLOT_ID_INVALID);
1676
1677	if (FuncList.ST_InitPIN)
1678		rv = FuncList.ST_InitPIN(rSession, pPin, ulPinLen);
1679	else
1680		rv = CKR_FUNCTION_NOT_SUPPORTED;
1681
1682	return (rv);
1683}
1684
1685CK_RV
1686C_InitToken(CK_SLOT_ID  slotID,
1687	CK_CHAR_PTR pPin,
1688	CK_ULONG    ulPinLen,
1689	CK_CHAR_PTR pLabel)
1690{
1691	CK_RV rv;
1692
1693	if (API_Initialized() == FALSE)
1694		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1695
1696	if (! pPin && ulPinLen)
1697		return (CKR_ARGUMENTS_BAD);
1698
1699	if (! pLabel)
1700		return (CKR_ARGUMENTS_BAD);
1701
1702	if (!global_shm->token_available)
1703		return (CKR_SLOT_ID_INVALID);
1704
1705	if (FuncList.ST_InitToken)
1706		rv = FuncList.ST_InitToken(slotID, pPin, ulPinLen, pLabel);
1707	else
1708		rv = CKR_FUNCTION_NOT_SUPPORTED;
1709
1710	return (rv);
1711}
1712
1713CK_RV
1714C_Login(CK_SESSION_HANDLE hSession,
1715	CK_USER_TYPE userType,
1716	CK_CHAR_PTR pPin,
1717	CK_ULONG ulPinLen)
1718{
1719	CK_RV rv;
1720	ST_SESSION_T rSession;
1721
1722	if (API_Initialized() == FALSE) {
1723		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1724	}
1725	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1726		return (CKR_SESSION_HANDLE_INVALID);
1727	}
1728	if (FuncList.ST_Login) {
1729		rv = FuncList.ST_Login(rSession, userType, pPin, ulPinLen);
1730	} else {
1731		rv = CKR_FUNCTION_NOT_SUPPORTED;
1732	}
1733	return (rv);
1734}
1735
1736CK_RV
1737C_Logout(CK_SESSION_HANDLE hSession)
1738{
1739	CK_RV rv;
1740	ST_SESSION_T rSession;
1741
1742	if (API_Initialized() == FALSE) {
1743		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1744	}
1745	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1746		return (CKR_SESSION_HANDLE_INVALID);
1747	}
1748	if (FuncList.ST_Logout) {
1749		rv = FuncList.ST_Logout(rSession);
1750	} else {
1751		rv = CKR_FUNCTION_NOT_SUPPORTED;
1752	}
1753	return (rv);
1754}
1755
1756/*ARGSUSED*/
1757CK_RV
1758C_OpenSession(
1759	CK_SLOT_ID slotID,
1760	CK_FLAGS flags,
1761	CK_VOID_PTR pApplication,
1762	CK_NOTIFY Notify,
1763	CK_SESSION_HANDLE_PTR phSession)
1764{
1765	CK_RV rv;
1766	Session_Struct_t  *apiSessp;
1767
1768	if (API_Initialized() == FALSE)
1769		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1770
1771	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1772		return (CKR_SLOT_ID_INVALID);
1773
1774	if (! phSession)
1775		return (CKR_FUNCTION_FAILED);
1776
1777	if ((flags & CKF_SERIAL_SESSION) == 0)
1778		return (CKR_SESSION_PARALLEL_NOT_SUPPORTED);
1779
1780	if ((apiSessp = (Session_Struct_t *)malloc(
1781	    sizeof (Session_Struct_t))) == NULL)
1782		return (CKR_HOST_MEMORY);
1783
1784	if (FuncList.ST_OpenSession) {
1785		rv = FuncList.ST_OpenSession(slotID, flags,
1786		    &(apiSessp->RealHandle));
1787
1788		if (rv == CKR_OK) {
1789			*phSession = (CK_SESSION_HANDLE)apiSessp;
1790			apiSessp->SltId = slotID;
1791
1792			AddToSessionList(apiSessp);
1793		} else {
1794			free(apiSessp);
1795		}
1796	} else {
1797		rv = CKR_FUNCTION_NOT_SUPPORTED;
1798	}
1799	return (rv);
1800}
1801
1802CK_RV
1803C_SeedRandom(CK_SESSION_HANDLE hSession,
1804	CK_BYTE_PTR pSeed,
1805	CK_ULONG ulSeedLen)
1806{
1807	CK_RV rv;
1808	ST_SESSION_T rSession;
1809
1810	if (API_Initialized() == FALSE) {
1811		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1812	}
1813	if (! pSeed && ulSeedLen) {
1814		return (CKR_ARGUMENTS_BAD);
1815	}
1816	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1817		return (CKR_SESSION_HANDLE_INVALID);
1818	}
1819	if (FuncList.ST_SeedRandom) {
1820		rv = FuncList.ST_SeedRandom(rSession, pSeed, ulSeedLen);
1821	} else {
1822		rv = CKR_FUNCTION_NOT_SUPPORTED;
1823	}
1824	return (rv);
1825}
1826
1827CK_RV
1828C_SetAttributeValue(CK_SESSION_HANDLE hSession,
1829	CK_OBJECT_HANDLE hObject,
1830	CK_ATTRIBUTE_PTR pTemplate,
1831	CK_ULONG ulCount)
1832{
1833	CK_RV rv;
1834	ST_SESSION_T rSession;
1835
1836	if (API_Initialized() == FALSE) {
1837		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1838	}
1839	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1840		return (CKR_SESSION_HANDLE_INVALID);
1841	}
1842	if (! pTemplate) {
1843		return (CKR_TEMPLATE_INCOMPLETE);
1844	}
1845	if (! ulCount) {
1846		return (CKR_TEMPLATE_INCOMPLETE);
1847	}
1848	// Get local pointers to session
1849	if (FuncList.ST_SetAttributeValue) {
1850		rv = FuncList.ST_SetAttributeValue(rSession, hObject,
1851		    pTemplate, ulCount);
1852	} else {
1853		rv = CKR_FUNCTION_NOT_SUPPORTED;
1854	}
1855	return (rv);
1856}
1857
1858CK_RV
1859C_SetOperationState(CK_SESSION_HANDLE hSession,
1860	CK_BYTE_PTR pOperationState,
1861	CK_ULONG ulOperationStateLen,
1862	CK_OBJECT_HANDLE hEncryptionKey,
1863	CK_OBJECT_HANDLE hAuthenticationKey)
1864{
1865	CK_RV rv;
1866	ST_SESSION_T rSession;
1867
1868	if (API_Initialized() == FALSE) {
1869		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1870	}
1871	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1872		return (CKR_SESSION_HANDLE_INVALID);
1873	}
1874	if (! pOperationState || ulOperationStateLen == 0) {
1875		return (CKR_ARGUMENTS_BAD);
1876	}
1877	if (FuncList.ST_SetOperationState) {
1878		rv = FuncList.ST_SetOperationState(rSession, pOperationState,
1879		    ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
1880	} else {
1881		rv = CKR_FUNCTION_NOT_SUPPORTED;
1882	}
1883	return (rv);
1884}
1885
1886CK_RV
1887C_SetPIN(CK_SESSION_HANDLE hSession,
1888	CK_CHAR_PTR pOldPin,
1889	CK_ULONG ulOldLen,
1890	CK_CHAR_PTR pNewPin,
1891	CK_ULONG ulNewLen)
1892{
1893	CK_RV rv;
1894	ST_SESSION_T rSession;
1895
1896	if (API_Initialized() == FALSE) {
1897		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1898	}
1899	if (! pOldPin || ! pNewPin)
1900		return (CKR_PIN_INVALID);
1901	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1902		return (CKR_SESSION_HANDLE_INVALID);
1903	}
1904	if (FuncList.ST_SetPIN) {
1905		rv = FuncList.ST_SetPIN(rSession, pOldPin, ulOldLen,
1906		    pNewPin, ulNewLen);
1907	} else {
1908		rv = CKR_FUNCTION_NOT_SUPPORTED;
1909	}
1910	return (rv);
1911}
1912
1913CK_RV
1914C_Sign(CK_SESSION_HANDLE hSession,
1915	CK_BYTE_PTR pData,
1916	CK_ULONG ulDataLen,
1917	CK_BYTE_PTR pSignature,
1918	CK_ULONG_PTR pulSignatureLen)
1919{
1920	CK_RV rv;
1921	ST_SESSION_T rSession;
1922
1923	if (API_Initialized() == FALSE) {
1924		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1925	}
1926	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1927		return (CKR_SESSION_HANDLE_INVALID);
1928	}
1929	if (FuncList.ST_Sign) {
1930		rv = FuncList.ST_Sign(rSession, pData, ulDataLen,
1931		    pSignature, pulSignatureLen);
1932	} else {
1933		rv = CKR_FUNCTION_NOT_SUPPORTED;
1934	}
1935	return (rv);
1936}
1937
1938CK_RV
1939C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
1940	CK_BYTE_PTR pPart,
1941	CK_ULONG ulPartLen,
1942	CK_BYTE_PTR pEncryptedPart,
1943	CK_ULONG_PTR pulEncryptedPartLen)
1944{
1945	CK_RV rv;
1946	ST_SESSION_T rSession;
1947	if (API_Initialized() == FALSE) {
1948		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1949	}
1950	if (! pPart || ! pulEncryptedPartLen) {
1951		return (CKR_ARGUMENTS_BAD);
1952	}
1953	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1954		return (CKR_SESSION_HANDLE_INVALID);
1955	}
1956	if (FuncList.ST_SignEncryptUpdate) {
1957		rv = FuncList.ST_SignEncryptUpdate(rSession, pPart,
1958		    ulPartLen, pEncryptedPart, pulEncryptedPartLen);
1959	} else {
1960		rv = CKR_FUNCTION_NOT_SUPPORTED;
1961	}
1962	return (rv);
1963}
1964
1965CK_RV
1966C_SignFinal(CK_SESSION_HANDLE hSession,
1967	CK_BYTE_PTR pSignature,
1968	CK_ULONG_PTR pulSignatureLen)
1969{
1970	CK_RV rv;
1971	ST_SESSION_T rSession;
1972
1973	if (API_Initialized() == FALSE) {
1974		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1975	}
1976	if (! pulSignatureLen) {
1977		return (CKR_ARGUMENTS_BAD);
1978	}
1979	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1980		return (CKR_SESSION_HANDLE_INVALID);
1981	}
1982	if (FuncList.ST_SignFinal) {
1983		rv = FuncList.ST_SignFinal(rSession, pSignature,
1984		    pulSignatureLen);
1985	} else {
1986		rv = CKR_FUNCTION_NOT_SUPPORTED;
1987	}
1988	return (rv);
1989}
1990
1991CK_RV
1992C_SignInit(CK_SESSION_HANDLE hSession,
1993	CK_MECHANISM_PTR pMechanism,
1994	CK_OBJECT_HANDLE hKey)
1995{
1996	CK_RV rv;
1997	ST_SESSION_T rSession;
1998
1999	if (API_Initialized() == FALSE) {
2000		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2001	}
2002	if (! pMechanism) {
2003		return (CKR_MECHANISM_INVALID);
2004	}
2005	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2006		return (CKR_SESSION_HANDLE_INVALID);
2007	}
2008	if (FuncList.ST_SignInit) {
2009		rv = FuncList.ST_SignInit(rSession, pMechanism, hKey);
2010	} else {
2011		rv = CKR_FUNCTION_NOT_SUPPORTED;
2012	}
2013	return (rv);
2014}
2015
2016CK_RV
2017C_SignRecover(CK_SESSION_HANDLE hSession,
2018	CK_BYTE_PTR pData,
2019	CK_ULONG ulDataLen,
2020	CK_BYTE_PTR pSignature,
2021	CK_ULONG_PTR pulSignatureLen)
2022{
2023	CK_RV rv;
2024	ST_SESSION_T rSession;
2025
2026	if (API_Initialized() == FALSE) {
2027		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2028	}
2029	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2030		return (CKR_SESSION_HANDLE_INVALID);
2031	}
2032	if (FuncList.ST_SignRecover) {
2033		rv = FuncList.ST_SignRecover(rSession, pData,
2034		    ulDataLen, pSignature, pulSignatureLen);
2035	} else {
2036		rv = CKR_FUNCTION_NOT_SUPPORTED;
2037	}
2038	return (rv);
2039}
2040
2041CK_RV
2042C_SignRecoverInit(CK_SESSION_HANDLE hSession,
2043	CK_MECHANISM_PTR pMechanism,
2044	CK_OBJECT_HANDLE hKey)
2045{
2046	CK_RV rv;
2047	ST_SESSION_T rSession;
2048
2049	if (API_Initialized() == FALSE) {
2050		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2051	}
2052	if (! pMechanism) {
2053		return (CKR_MECHANISM_INVALID);
2054	}
2055	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2056		return (CKR_SESSION_HANDLE_INVALID);
2057	}
2058	if (FuncList.ST_SignRecoverInit) {
2059		rv = FuncList.ST_SignRecoverInit(rSession, pMechanism, hKey);
2060	} else {
2061		rv = CKR_FUNCTION_NOT_SUPPORTED;
2062	}
2063	return (rv);
2064}
2065
2066CK_RV
2067C_SignUpdate(CK_SESSION_HANDLE hSession,
2068	CK_BYTE_PTR pPart,
2069	CK_ULONG ulPartLen)
2070{
2071	CK_RV rv;
2072	ST_SESSION_T rSession;
2073
2074	if (API_Initialized() == FALSE) {
2075		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2076	}
2077	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2078		return (CKR_SESSION_HANDLE_INVALID);
2079	}
2080	if (FuncList.ST_SignUpdate) {
2081		rv = FuncList.ST_SignUpdate(rSession, pPart, ulPartLen);
2082	} else {
2083		rv = CKR_FUNCTION_NOT_SUPPORTED;
2084	}
2085	return (rv);
2086}
2087
2088CK_RV
2089C_UnwrapKey(CK_SESSION_HANDLE hSession,
2090	CK_MECHANISM_PTR pMechanism,
2091	CK_OBJECT_HANDLE hUnwrappingKey,
2092	CK_BYTE_PTR pWrappedKey,
2093	CK_ULONG ulWrappedKeyLen,
2094	CK_ATTRIBUTE_PTR pTemplate,
2095	CK_ULONG ulAttributeCount,
2096	CK_OBJECT_HANDLE_PTR phKey)
2097{
2098	CK_RV rv;
2099	ST_SESSION_T rSession;
2100
2101	if (API_Initialized() == FALSE) {
2102		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2103	}
2104	if (!pMechanism) {
2105		return (CKR_MECHANISM_INVALID);
2106	}
2107	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2108		return (CKR_SESSION_HANDLE_INVALID);
2109	}
2110	if (FuncList.ST_UnwrapKey) {
2111		rv = FuncList.ST_UnwrapKey(rSession, pMechanism,
2112		    hUnwrappingKey, pWrappedKey, ulWrappedKeyLen,
2113		    pTemplate, ulAttributeCount, phKey);
2114	} else {
2115		rv = CKR_FUNCTION_NOT_SUPPORTED;
2116	}
2117	return (rv);
2118}
2119
2120CK_RV
2121C_Verify(CK_SESSION_HANDLE hSession,
2122	CK_BYTE_PTR pData,
2123	CK_ULONG ulDataLen,
2124	CK_BYTE_PTR pSignature,
2125	CK_ULONG ulSignatureLen)
2126{
2127	CK_RV rv;
2128	ST_SESSION_T rSession;
2129
2130	if (API_Initialized() == FALSE) {
2131		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2132	}
2133	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2134		return (CKR_SESSION_HANDLE_INVALID);
2135	}
2136	if (FuncList.ST_Verify) {
2137		rv = FuncList.ST_Verify(rSession, pData, ulDataLen,
2138		    pSignature, ulSignatureLen);
2139	} else {
2140		rv = CKR_FUNCTION_NOT_SUPPORTED;
2141	}
2142	return (rv);
2143}
2144
2145CK_RV
2146C_VerifyFinal(CK_SESSION_HANDLE hSession,
2147	CK_BYTE_PTR pSignature,
2148	CK_ULONG ulSignatureLen)
2149{
2150	CK_RV rv;
2151	ST_SESSION_T rSession;
2152
2153	if (API_Initialized() == FALSE) {
2154		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2155	}
2156	if (! pSignature) {
2157		return (CKR_ARGUMENTS_BAD);
2158	}
2159
2160	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2161		return (CKR_SESSION_HANDLE_INVALID);
2162	}
2163	if (FuncList.ST_VerifyFinal) {
2164		rv = FuncList.ST_VerifyFinal(rSession, pSignature,
2165		    ulSignatureLen);
2166	} else {
2167		rv = CKR_FUNCTION_NOT_SUPPORTED;
2168	}
2169	return (rv);
2170}
2171
2172CK_RV
2173C_VerifyInit(CK_SESSION_HANDLE hSession,
2174	CK_MECHANISM_PTR pMechanism,
2175	CK_OBJECT_HANDLE hKey)
2176{
2177	CK_RV rv;
2178	ST_SESSION_T rSession;
2179
2180	if (API_Initialized() == FALSE) {
2181		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2182	}
2183	if (! pMechanism) {
2184		return (CKR_MECHANISM_INVALID);
2185	}
2186	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2187		return (CKR_SESSION_HANDLE_INVALID);
2188	}
2189
2190	if (FuncList.ST_VerifyInit) {
2191		rv = FuncList.ST_VerifyInit(rSession, pMechanism, hKey);
2192	} else {
2193		rv = CKR_FUNCTION_NOT_SUPPORTED;
2194	}
2195	return (rv);
2196}
2197
2198CK_RV
2199C_VerifyRecover(CK_SESSION_HANDLE hSession,
2200	CK_BYTE_PTR pSignature,
2201	CK_ULONG ulSignatureLen,
2202	CK_BYTE_PTR pData,
2203	CK_ULONG_PTR pulDataLen)
2204{
2205	CK_RV rv;
2206	ST_SESSION_T rSession;
2207
2208	if (API_Initialized() == FALSE) {
2209		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2210	}
2211	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2212		return (CKR_SESSION_HANDLE_INVALID);
2213	}
2214	if (FuncList.ST_VerifyRecover) {
2215		rv = FuncList.ST_VerifyRecover(rSession, pSignature,
2216		    ulSignatureLen, pData, pulDataLen);
2217	} else {
2218		rv = CKR_FUNCTION_NOT_SUPPORTED;
2219	}
2220	return (rv);
2221}
2222
2223CK_RV
2224C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
2225	CK_MECHANISM_PTR pMechanism,
2226	CK_OBJECT_HANDLE hKey)
2227{
2228	CK_RV rv;
2229	ST_SESSION_T rSession;
2230
2231	if (API_Initialized() == FALSE) {
2232		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2233	}
2234	if (! pMechanism) {
2235		return (CKR_MECHANISM_INVALID);
2236	}
2237	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2238		return (CKR_SESSION_HANDLE_INVALID);
2239	}
2240	if (FuncList.ST_VerifyRecoverInit) {
2241		rv = FuncList.ST_VerifyRecoverInit(rSession, pMechanism, hKey);
2242	} else {
2243		rv = CKR_FUNCTION_NOT_SUPPORTED;
2244	}
2245	return (rv);
2246}
2247
2248CK_RV
2249C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2250	CK_BYTE_PTR pPart,
2251	CK_ULONG ulPartLen)
2252{
2253	CK_RV rv;
2254	ST_SESSION_T rSession;
2255
2256	if (API_Initialized() == FALSE) {
2257		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2258	}
2259	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2260		return (CKR_SESSION_HANDLE_INVALID);
2261	}
2262	if (FuncList.ST_VerifyUpdate) {
2263		rv = FuncList.ST_VerifyUpdate(rSession, pPart, ulPartLen);
2264	} else {
2265		rv = CKR_FUNCTION_NOT_SUPPORTED;
2266	}
2267	return (rv);
2268}
2269
2270/*ARGSUSED*/
2271CK_RV
2272C_WaitForSlotEvent(CK_FLAGS flags,
2273	CK_SLOT_ID_PTR pSlot,
2274	CK_VOID_PTR pReserved)
2275{
2276	if (API_Initialized() == FALSE) {
2277		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2278	}
2279	return (CKR_FUNCTION_NOT_SUPPORTED);
2280}
2281
2282CK_RV
2283C_WrapKey(CK_SESSION_HANDLE hSession,
2284	CK_MECHANISM_PTR pMechanism,
2285	CK_OBJECT_HANDLE hWrappingKey,
2286	CK_OBJECT_HANDLE hKey,
2287	CK_BYTE_PTR pWrappedKey,
2288	CK_ULONG_PTR pulWrappedKeyLen)
2289{
2290	CK_RV rv;
2291	ST_SESSION_T rSession;
2292
2293	if (API_Initialized() == FALSE) {
2294		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2295	}
2296	if (! pMechanism) {
2297		return (CKR_MECHANISM_INVALID);
2298	}
2299	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2300		return (CKR_SESSION_HANDLE_INVALID);
2301	}
2302	if (FuncList.ST_WrapKey) {
2303		rv = FuncList.ST_WrapKey(rSession, pMechanism, hWrappingKey,
2304		    hKey, pWrappedKey, pulWrappedKeyLen);
2305	} else {
2306		rv = CKR_FUNCTION_NOT_SUPPORTED;
2307	}
2308	return (rv);
2309}
2310
2311#pragma init(api_init)
2312#pragma fini(api_fini)
2313
2314static void
2315api_init(void)
2316{
2317	loginit();
2318	if (! Initialized) {
2319		(void) pthread_atfork(tpmtoken_fork_prepare,
2320		    tpmtoken_fork_parent, tpmtoken_fork_child);
2321		Initialized = 1;
2322	}
2323}
2324
2325static void
2326api_fini()
2327{
2328	logterm();
2329	if (API_Initialized() == TRUE) {
2330		(void) do_finalize(NULL);
2331	}
2332}
2333