xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/api_interface.c (revision 2bbdd445a21f9d61f4a0ca0faf05d5ceb2bd91f3)
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  */
316 API_Proc_Struct_t  *Anchor = NULL;
317 static unsigned int   Initialized = 0;
318 static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
319 struct ST_FCN_LIST FuncList;
320 CK_FUNCTION_LIST PK11_Functions;
321 extern pthread_rwlock_t obj_list_rw_mutex;
322 
323 
324 static void
325 tpmtoken_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 
339 static void
340 tpmtoken_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 
354 static void
355 tpmtoken_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*/
382 CK_RV
383 C_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 
392 CK_RV
393 C_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 }
448 CK_RV
449 C_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 
477 CK_RV
478 C_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 
514 CK_RV
515 C_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 
549 CK_RV
550 C_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 
574 CK_RV
575 C_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 
603 CK_RV
604 C_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 
635 CK_RV
636 C_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 
660 CK_RV
661 C_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 
688 CK_RV
689 C_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 
720 CK_RV
721 C_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 
753 CK_RV
754 C_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 
774 CK_RV
775 C_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 
799 CK_RV
800 C_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 
827 CK_RV
828 C_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 
852 CK_RV
853 C_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 
876 CK_RV
877 C_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 
897 CK_RV
898 C_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 
918 CK_RV
919 C_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 
945 CK_RV
946 C_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 
968 CK_RV
969 C_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 
993 CK_RV
994 C_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 
1021 CK_RV
1022 do_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 
1044 CK_RV
1045 C_Finalize(CK_VOID_PTR pReserved) {
1046 	return (do_finalize(pReserved));
1047 }
1048 
1049 CK_RV
1050 C_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 
1076 CK_RV
1077 C_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 
1096 CK_RV
1097 C_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 
1118 CK_RV
1119 C_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 
1149 CK_RV
1150 C_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 
1185 CK_RV
1186 C_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 
1211 CK_RV
1212 C_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 
1241 CK_RV
1242 C_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*/
1323 CK_RV
1324 C_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 
1332 CK_RV
1333 C_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 
1373 CK_RV
1374 C_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 
1393 CK_RV
1394 C_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 
1427 CK_RV
1428 C_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 
1452 CK_RV
1453 C_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 
1478 CK_RV
1479 C_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 
1502 CK_RV
1503 C_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*/
1520 CK_RV
1521 C_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 
1559 CK_RV
1560 C_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 
1583 CK_RV
1584 C_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 
1657 CK_RV
1658 C_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 
1685 CK_RV
1686 C_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 
1713 CK_RV
1714 C_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 
1736 CK_RV
1737 C_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*/
1757 CK_RV
1758 C_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 
1802 CK_RV
1803 C_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 
1827 CK_RV
1828 C_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 
1858 CK_RV
1859 C_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 
1886 CK_RV
1887 C_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 
1913 CK_RV
1914 C_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 
1938 CK_RV
1939 C_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 
1965 CK_RV
1966 C_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 
1991 CK_RV
1992 C_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 
2016 CK_RV
2017 C_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 
2041 CK_RV
2042 C_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 
2066 CK_RV
2067 C_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 
2088 CK_RV
2089 C_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 
2120 CK_RV
2121 C_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 
2145 CK_RV
2146 C_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 
2172 CK_RV
2173 C_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 
2198 CK_RV
2199 C_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 
2223 CK_RV
2224 C_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 
2248 CK_RV
2249 C_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*/
2271 CK_RV
2272 C_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 
2282 CK_RV
2283 C_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 
2314 static void
2315 api_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 
2325 static void
2326 api_fini()
2327 {
2328 	logterm();
2329 	if (API_Initialized() == TRUE) {
2330 		(void) do_finalize(NULL);
2331 	}
2332 }
2333