xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/api_interface.c (revision efd4c9b63ad77503c101fc6c2ed8ba96c9d52964)
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 	_init();
1245 
1246 	PK11_Functions.version.major = VERSION_MAJOR;
1247 	PK11_Functions.version.minor = VERSION_MINOR;
1248 	PK11_Functions.C_Initialize = C_Initialize;
1249 	PK11_Functions.C_Finalize = C_Finalize;
1250 	PK11_Functions.C_GetInfo = C_GetInfo;
1251 	PK11_Functions.C_GetFunctionList = C_GetFunctionList;
1252 	PK11_Functions.C_GetSlotList = C_GetSlotList;
1253 	PK11_Functions.C_GetSlotInfo = C_GetSlotInfo;
1254 	PK11_Functions.C_GetTokenInfo = C_GetTokenInfo;
1255 	PK11_Functions.C_GetMechanismList = C_GetMechanismList;
1256 	PK11_Functions.C_GetMechanismInfo = C_GetMechanismInfo;
1257 	PK11_Functions.C_InitToken = C_InitToken;
1258 	PK11_Functions.C_InitPIN = C_InitPIN;
1259 	PK11_Functions.C_SetPIN = C_SetPIN;
1260 	PK11_Functions.C_OpenSession = C_OpenSession;
1261 	PK11_Functions.C_CloseSession = C_CloseSession;
1262 	PK11_Functions.C_CloseAllSessions = C_CloseAllSessions;
1263 	PK11_Functions.C_GetSessionInfo = C_GetSessionInfo;
1264 	PK11_Functions.C_GetOperationState = C_GetOperationState;
1265 	PK11_Functions.C_SetOperationState = C_SetOperationState;
1266 	PK11_Functions.C_Login = C_Login;
1267 	PK11_Functions.C_Logout = C_Logout;
1268 	PK11_Functions.C_CreateObject = C_CreateObject;
1269 	PK11_Functions.C_CopyObject = C_CopyObject;
1270 	PK11_Functions.C_DestroyObject = C_DestroyObject;
1271 	PK11_Functions.C_GetObjectSize = C_GetObjectSize;
1272 	PK11_Functions.C_GetAttributeValue = C_GetAttributeValue;
1273 	PK11_Functions.C_SetAttributeValue = C_SetAttributeValue;
1274 	PK11_Functions.C_FindObjectsInit = C_FindObjectsInit;
1275 	PK11_Functions.C_FindObjects = C_FindObjects;
1276 	PK11_Functions.C_FindObjectsFinal = C_FindObjectsFinal;
1277 	PK11_Functions.C_EncryptInit = C_EncryptInit;
1278 	PK11_Functions.C_Encrypt = C_Encrypt;
1279 	PK11_Functions.C_EncryptUpdate = C_EncryptUpdate;
1280 	PK11_Functions.C_EncryptFinal = C_EncryptFinal;
1281 	PK11_Functions.C_DecryptInit = C_DecryptInit;
1282 	PK11_Functions.C_Decrypt = C_Decrypt;
1283 	PK11_Functions.C_DecryptUpdate = C_DecryptUpdate;
1284 	PK11_Functions.C_DecryptFinal = C_DecryptFinal;
1285 	PK11_Functions.C_DigestInit = C_DigestInit;
1286 	PK11_Functions.C_Digest = C_Digest;
1287 	PK11_Functions.C_DigestUpdate = C_DigestUpdate;
1288 	PK11_Functions.C_DigestKey = C_DigestKey;
1289 	PK11_Functions.C_DigestFinal = C_DigestFinal;
1290 	PK11_Functions.C_SignInit = C_SignInit;
1291 	PK11_Functions.C_Sign = C_Sign;
1292 	PK11_Functions.C_SignUpdate = C_SignUpdate;
1293 	PK11_Functions.C_SignFinal = C_SignFinal;
1294 	PK11_Functions.C_SignRecoverInit = C_SignRecoverInit;
1295 	PK11_Functions.C_SignRecover = C_SignRecover;
1296 	PK11_Functions.C_VerifyInit = C_VerifyInit;
1297 	PK11_Functions.C_Verify = C_Verify;
1298 	PK11_Functions.C_VerifyUpdate = C_VerifyUpdate;
1299 	PK11_Functions.C_VerifyFinal = C_VerifyFinal;
1300 	PK11_Functions.C_VerifyRecoverInit = C_VerifyRecoverInit;
1301 	PK11_Functions.C_VerifyRecover = C_VerifyRecover;
1302 	PK11_Functions.C_DigestEncryptUpdate = C_DigestEncryptUpdate;
1303 	PK11_Functions.C_DecryptDigestUpdate = C_DecryptDigestUpdate;
1304 	PK11_Functions.C_SignEncryptUpdate = C_SignEncryptUpdate;
1305 	PK11_Functions.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate;
1306 	PK11_Functions.C_GenerateKey = C_GenerateKey;
1307 	PK11_Functions.C_GenerateKeyPair = C_GenerateKeyPair;
1308 	PK11_Functions.C_WrapKey = C_WrapKey;
1309 	PK11_Functions.C_UnwrapKey = C_UnwrapKey;
1310 	PK11_Functions.C_DeriveKey = C_DeriveKey;
1311 	PK11_Functions.C_SeedRandom = C_SeedRandom;
1312 	PK11_Functions.C_GenerateRandom = C_GenerateRandom;
1313 	PK11_Functions.C_GetFunctionStatus = C_GetFunctionStatus;
1314 	PK11_Functions.C_CancelFunction = C_CancelFunction;
1315 	PK11_Functions.C_WaitForSlotEvent = C_WaitForSlotEvent;
1316 	if (ppFunctionList) {
1317 		(*ppFunctionList) = &PK11_Functions;
1318 		return (CKR_OK);
1319 	} else {
1320 		return (CKR_ARGUMENTS_BAD);
1321 	}
1322 }
1323 
1324 /*ARGSUSED*/
1325 CK_RV
1326 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
1327 {
1328 	if (API_Initialized() == FALSE) {
1329 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1330 	}
1331 	return (CKR_FUNCTION_NOT_PARALLEL); // PER Specification PG 170
1332 }
1333 
1334 CK_RV
1335 C_GetInfo(CK_INFO_PTR pInfo)
1336 {
1337 	TOKEN_DATA td;
1338 	TSS_HCONTEXT hContext;
1339 
1340 	if (! API_Initialized()) {
1341 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1342 	}
1343 	if (! pInfo) {
1344 		return (CKR_FUNCTION_FAILED);
1345 	}
1346 	(void) memset(pInfo, 0, sizeof (*pInfo));
1347 	pInfo->cryptokiVersion.major = 2;
1348 	pInfo->cryptokiVersion.minor = 20;
1349 
1350 	if (open_tss_context(&hContext) == 0) {
1351 		/*
1352 		 * Only populate the TPM info if we can establish
1353 		 * a context, but don't return failure because
1354 		 * the framework needs to know some of the info.
1355 		 */
1356 		(void) token_get_tpm_info(hContext, &td);
1357 
1358 		(void) Tspi_Context_Close(hContext);
1359 
1360 		(void) memcpy(pInfo->manufacturerID,
1361 		    &(td.token_info.manufacturerID),
1362 		    sizeof (pInfo->manufacturerID) - 1);
1363 
1364 		pInfo->flags = td.token_info.flags;
1365 	}
1366 	(void) strcpy((char *)pInfo->libraryDescription,
1367 	    "PKCS11 Interface for TPM");
1368 
1369 	pInfo->libraryVersion.major = 1;
1370 	pInfo->libraryVersion.minor = 0;
1371 
1372 	return (CKR_OK);
1373 }
1374 
1375 CK_RV
1376 C_GetMechanismInfo(CK_SLOT_ID	slotID,
1377 	CK_MECHANISM_TYPE	type,
1378 	CK_MECHANISM_INFO_PTR	pInfo)
1379 {
1380 	CK_RV rv;
1381 	if (API_Initialized() == FALSE)
1382 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1383 
1384 	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1385 		return (CKR_SLOT_ID_INVALID);
1386 
1387 	if (FuncList.ST_GetMechanismInfo) {
1388 		rv = FuncList.ST_GetMechanismInfo(slotID, type, pInfo);
1389 	} else {
1390 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1391 	}
1392 	return (rv);
1393 }
1394 
1395 CK_RV
1396 C_GetMechanismList(CK_SLOT_ID slotID,
1397 	CK_MECHANISM_TYPE_PTR pMechanismList,
1398 	CK_ULONG_PTR pulCount)
1399 {
1400 	CK_RV rv;
1401 
1402 	if (API_Initialized() == FALSE)
1403 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1404 
1405 	if (! pulCount)
1406 		return (CKR_ARGUMENTS_BAD);
1407 
1408 	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1409 		return (CKR_SLOT_ID_INVALID);
1410 
1411 	if (FuncList.ST_GetMechanismList) {
1412 		rv = FuncList.ST_GetMechanismList(slotID,
1413 		    pMechanismList, pulCount);
1414 	} else {
1415 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1416 	}
1417 	if (rv == CKR_OK) {
1418 		if (pMechanismList) {
1419 			unsigned long i;
1420 			for (i = 0; i < *pulCount; i++) {
1421 				logit(LOG_DEBUG, "Mechanism[%d] 0x%08X ",
1422 				    i, pMechanismList[i]);
1423 			}
1424 		}
1425 	}
1426 	return (rv);
1427 }
1428 
1429 CK_RV
1430 C_GetObjectSize(CK_SESSION_HANDLE hSession,
1431 	CK_OBJECT_HANDLE hObject,
1432 	CK_ULONG_PTR pulSize)
1433 {
1434 	CK_RV rv;
1435 	ST_SESSION_T rSession;
1436 
1437 	if (API_Initialized() == FALSE) {
1438 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1439 	}
1440 	if (! pulSize) {
1441 		return (CKR_ARGUMENTS_BAD);
1442 	}
1443 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1444 		return (CKR_SESSION_HANDLE_INVALID);
1445 	}
1446 	if (FuncList.ST_GetObjectSize) {
1447 		rv = FuncList.ST_GetObjectSize(rSession, hObject, pulSize);
1448 	} else {
1449 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1450 	}
1451 	return (rv);
1452 }
1453 
1454 CK_RV
1455 C_GetOperationState(CK_SESSION_HANDLE hSession,
1456 	CK_BYTE_PTR pOperationState,
1457 	CK_ULONG_PTR pulOperationStateLen)
1458 {
1459 	CK_RV rv;
1460 	ST_SESSION_T rSession;
1461 
1462 	if (API_Initialized() == FALSE) {
1463 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1464 	}
1465 	if (! pulOperationStateLen) {
1466 		return (CKR_ARGUMENTS_BAD);
1467 	}
1468 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1469 		return (CKR_SESSION_HANDLE_INVALID);
1470 	}
1471 	if (FuncList.ST_GetOperationState) {
1472 		rv = FuncList.ST_GetOperationState(rSession,
1473 		    pOperationState, pulOperationStateLen);
1474 	} else {
1475 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1476 	}
1477 	return (rv);
1478 }
1479 
1480 CK_RV
1481 C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1482 	CK_SESSION_INFO_PTR pInfo)
1483 {
1484 	CK_RV rv;
1485 	ST_SESSION_T rSession;
1486 
1487 	if (API_Initialized() == FALSE) {
1488 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1489 	}
1490 	if (! pInfo) {
1491 		return (CKR_ARGUMENTS_BAD);
1492 	}
1493 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1494 		return (CKR_SESSION_HANDLE_INVALID);
1495 	}
1496 	if (FuncList.ST_GetSessionInfo) {
1497 		rv = FuncList.ST_GetSessionInfo(rSession, pInfo);
1498 	} else {
1499 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1500 	}
1501 	return (rv);
1502 }
1503 
1504 CK_RV
1505 C_GetSlotInfo(CK_SLOT_ID slotID,
1506 	CK_SLOT_INFO_PTR pInfo)
1507 {
1508 	if (API_Initialized() == FALSE)
1509 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1510 
1511 	if (!pInfo)
1512 		return (CKR_FUNCTION_FAILED);
1513 
1514 	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1515 		return (CKR_SLOT_ID_INVALID);
1516 
1517 	copy_slot_info(slotID, pInfo);
1518 	return (CKR_OK);
1519 }
1520 
1521 /*ARGSUSED*/
1522 CK_RV
1523 C_GetSlotList(CK_BBOOL tokenPresent,
1524 	CK_SLOT_ID_PTR pSlotList,
1525 	CK_ULONG_PTR pulCount)
1526 {
1527 	CK_ULONG count;
1528 	CK_SLOT_INFO slotInfo;
1529 
1530 	if (API_Initialized() == FALSE)
1531 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1532 
1533 	if (pulCount == NULL)
1534 		return (CKR_FUNCTION_FAILED);
1535 
1536 	count = 0;
1537 	/*
1538 	 * If we can't talk to the TPM, present no slots
1539 	 */
1540 	if (!global_shm->token_available) {
1541 		*pulCount = 0;
1542 		return (CKR_OK);
1543 	}
1544 
1545 	copy_slot_info(TPM_SLOTID, &slotInfo);
1546 	if ((slotInfo.flags & CKF_TOKEN_PRESENT))
1547 		count++;
1548 
1549 	*pulCount = count;
1550 
1551 	if (pSlotList == NULL) {
1552 		return (CKR_OK);
1553 	} else {
1554 		if (*pulCount < count)
1555 			return (CKR_BUFFER_TOO_SMALL);
1556 		pSlotList[0] = TPM_SLOTID;
1557 	}
1558 	return (CKR_OK);
1559 }
1560 
1561 CK_RV
1562 C_GetTokenInfo(CK_SLOT_ID slotID,
1563 	CK_TOKEN_INFO_PTR pInfo)
1564 {
1565 	CK_RV rv;
1566 
1567 	if (API_Initialized() == FALSE)
1568 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1569 
1570 	if (!pInfo)
1571 		return (CKR_ARGUMENTS_BAD);
1572 
1573 	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1574 		return (CKR_SLOT_ID_INVALID);
1575 
1576 	slotID = TPM_SLOTID;
1577 	if (FuncList.ST_GetTokenInfo) {
1578 		rv = FuncList.ST_GetTokenInfo(slotID, pInfo);
1579 	} else {
1580 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1581 	}
1582 	return (rv);
1583 }
1584 
1585 CK_RV
1586 C_Initialize(CK_VOID_PTR pVoid)
1587 {
1588 	CK_RV rv = CKR_OK;
1589 	CK_C_INITIALIZE_ARGS *pArg;
1590 	extern CK_RV ST_Initialize(void *,
1591 	    CK_SLOT_ID, unsigned char *);
1592 
1593 	(void) pthread_mutex_lock(&global_mutex);
1594 	if (! Anchor) {
1595 		Anchor = (API_Proc_Struct_t *)malloc(
1596 		    sizeof (API_Proc_Struct_t));
1597 		if (Anchor == NULL) {
1598 			(void) pthread_mutex_unlock(&global_mutex);
1599 			return (CKR_HOST_MEMORY);
1600 		}
1601 	} else {
1602 		(void) pthread_mutex_unlock(&global_mutex);
1603 		return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
1604 	}
1605 	/*
1606 	 * if pVoid is NULL, then everything is OK.  The applicaiton
1607 	 * will not be doing multi thread accesses.  We can use the OS
1608 	 * locks anyhow.
1609 	 */
1610 	if (pVoid != NULL) {
1611 		int supplied_ok;
1612 		pArg = (CK_C_INITIALIZE_ARGS *)pVoid;
1613 
1614 		/*
1615 		 * ALL supplied function pointers need to have the value
1616 		 * either NULL or no - NULL.
1617 		 */
1618 		supplied_ok = (pArg->CreateMutex == NULL &&
1619 		    pArg->DestroyMutex == NULL &&
1620 		    pArg->LockMutex == NULL &&
1621 		    pArg->UnlockMutex == NULL) ||
1622 		    (pArg->CreateMutex != NULL &&
1623 		    pArg->DestroyMutex != NULL &&
1624 		    pArg->LockMutex != NULL &&
1625 		    pArg->UnlockMutex != NULL);
1626 
1627 		if (!supplied_ok) {
1628 			(void) pthread_mutex_unlock(&global_mutex);
1629 			return (CKR_ARGUMENTS_BAD);
1630 		}
1631 		/* Check for a pReserved set */
1632 		if (pArg->pReserved != NULL) {
1633 			free(Anchor);
1634 			Anchor = NULL;
1635 			(void) pthread_mutex_unlock(&global_mutex);
1636 			return (CKR_ARGUMENTS_BAD);
1637 		}
1638 		/*
1639 		 * When the CKF_OS_LOCKING_OK flag isn't set and mutex
1640 		 * function pointers are supplied by an application,
1641 		 * return (an error.  We must be able to use our own primitives.
1642 		 */
1643 		if (!(pArg->flags & CKF_OS_LOCKING_OK) &&
1644 		    (pArg->CreateMutex != NULL)) {
1645 			(void) pthread_mutex_unlock(&global_mutex);
1646 			return (CKR_CANT_LOCK);
1647 		}
1648 	}
1649 	(void) memset((char *)Anchor, 0, sizeof (API_Proc_Struct_t));
1650 	(void) pthread_mutex_init(&(Anchor->ProcMutex), NULL);
1651 	(void) pthread_mutex_init(&(Anchor->SessListMutex), NULL);
1652 	Anchor->Pid = getpid();
1653 
1654 	rv = ST_Initialize((void *)&FuncList, 0, NULL);
1655 	(void) pthread_mutex_unlock(&global_mutex);
1656 	return (rv);
1657 }
1658 
1659 CK_RV
1660 C_InitPIN(CK_SESSION_HANDLE hSession,
1661 	CK_CHAR_PTR pPin,
1662 	CK_ULONG ulPinLen)
1663 {
1664 	CK_RV rv;
1665 	ST_SESSION_T rSession;
1666 
1667 	if (API_Initialized() == FALSE)
1668 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1669 
1670 	if (! pPin && ulPinLen)
1671 		return (CKR_ARGUMENTS_BAD);
1672 
1673 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession))
1674 		return (CKR_SESSION_HANDLE_INVALID);
1675 
1676 	if (rSession.slotID > NUMBER_SLOTS_MANAGED)
1677 		return (CKR_SLOT_ID_INVALID);
1678 
1679 	if (FuncList.ST_InitPIN)
1680 		rv = FuncList.ST_InitPIN(rSession, pPin, ulPinLen);
1681 	else
1682 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1683 
1684 	return (rv);
1685 }
1686 
1687 CK_RV
1688 C_InitToken(CK_SLOT_ID  slotID,
1689 	CK_CHAR_PTR pPin,
1690 	CK_ULONG    ulPinLen,
1691 	CK_CHAR_PTR pLabel)
1692 {
1693 	CK_RV rv;
1694 
1695 	if (API_Initialized() == FALSE)
1696 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1697 
1698 	if (! pPin && ulPinLen)
1699 		return (CKR_ARGUMENTS_BAD);
1700 
1701 	if (! pLabel)
1702 		return (CKR_ARGUMENTS_BAD);
1703 
1704 	if (!global_shm->token_available)
1705 		return (CKR_SLOT_ID_INVALID);
1706 
1707 	if (FuncList.ST_InitToken)
1708 		rv = FuncList.ST_InitToken(slotID, pPin, ulPinLen, pLabel);
1709 	else
1710 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1711 
1712 	return (rv);
1713 }
1714 
1715 CK_RV
1716 C_Login(CK_SESSION_HANDLE hSession,
1717 	CK_USER_TYPE userType,
1718 	CK_CHAR_PTR pPin,
1719 	CK_ULONG ulPinLen)
1720 {
1721 	CK_RV rv;
1722 	ST_SESSION_T rSession;
1723 
1724 	if (API_Initialized() == FALSE) {
1725 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1726 	}
1727 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1728 		return (CKR_SESSION_HANDLE_INVALID);
1729 	}
1730 	if (FuncList.ST_Login) {
1731 		rv = FuncList.ST_Login(rSession, userType, pPin, ulPinLen);
1732 	} else {
1733 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1734 	}
1735 	return (rv);
1736 }
1737 
1738 CK_RV
1739 C_Logout(CK_SESSION_HANDLE hSession)
1740 {
1741 	CK_RV rv;
1742 	ST_SESSION_T rSession;
1743 
1744 	if (API_Initialized() == FALSE) {
1745 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1746 	}
1747 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1748 		return (CKR_SESSION_HANDLE_INVALID);
1749 	}
1750 	if (FuncList.ST_Logout) {
1751 		rv = FuncList.ST_Logout(rSession);
1752 	} else {
1753 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1754 	}
1755 	return (rv);
1756 }
1757 
1758 /*ARGSUSED*/
1759 CK_RV
1760 C_OpenSession(
1761 	CK_SLOT_ID slotID,
1762 	CK_FLAGS flags,
1763 	CK_VOID_PTR pApplication,
1764 	CK_NOTIFY Notify,
1765 	CK_SESSION_HANDLE_PTR phSession)
1766 {
1767 	CK_RV rv;
1768 	Session_Struct_t  *apiSessp;
1769 
1770 	if (API_Initialized() == FALSE)
1771 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1772 
1773 	if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1774 		return (CKR_SLOT_ID_INVALID);
1775 
1776 	if (! phSession)
1777 		return (CKR_FUNCTION_FAILED);
1778 
1779 	if ((flags & CKF_SERIAL_SESSION) == 0)
1780 		return (CKR_SESSION_PARALLEL_NOT_SUPPORTED);
1781 
1782 	if ((apiSessp = (Session_Struct_t *)malloc(
1783 	    sizeof (Session_Struct_t))) == NULL)
1784 		return (CKR_HOST_MEMORY);
1785 
1786 	if (FuncList.ST_OpenSession) {
1787 		rv = FuncList.ST_OpenSession(slotID, flags,
1788 		    &(apiSessp->RealHandle));
1789 
1790 		if (rv == CKR_OK) {
1791 			*phSession = (CK_SESSION_HANDLE)apiSessp;
1792 			apiSessp->SltId = slotID;
1793 
1794 			AddToSessionList(apiSessp);
1795 		} else {
1796 			free(apiSessp);
1797 		}
1798 	} else {
1799 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1800 	}
1801 	return (rv);
1802 }
1803 
1804 CK_RV
1805 C_SeedRandom(CK_SESSION_HANDLE hSession,
1806 	CK_BYTE_PTR pSeed,
1807 	CK_ULONG ulSeedLen)
1808 {
1809 	CK_RV rv;
1810 	ST_SESSION_T rSession;
1811 
1812 	if (API_Initialized() == FALSE) {
1813 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1814 	}
1815 	if (! pSeed && ulSeedLen) {
1816 		return (CKR_ARGUMENTS_BAD);
1817 	}
1818 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1819 		return (CKR_SESSION_HANDLE_INVALID);
1820 	}
1821 	if (FuncList.ST_SeedRandom) {
1822 		rv = FuncList.ST_SeedRandom(rSession, pSeed, ulSeedLen);
1823 	} else {
1824 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1825 	}
1826 	return (rv);
1827 }
1828 
1829 CK_RV
1830 C_SetAttributeValue(CK_SESSION_HANDLE hSession,
1831 	CK_OBJECT_HANDLE hObject,
1832 	CK_ATTRIBUTE_PTR pTemplate,
1833 	CK_ULONG ulCount)
1834 {
1835 	CK_RV rv;
1836 	ST_SESSION_T rSession;
1837 
1838 	if (API_Initialized() == FALSE) {
1839 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1840 	}
1841 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1842 		return (CKR_SESSION_HANDLE_INVALID);
1843 	}
1844 	if (! pTemplate) {
1845 		return (CKR_TEMPLATE_INCOMPLETE);
1846 	}
1847 	if (! ulCount) {
1848 		return (CKR_TEMPLATE_INCOMPLETE);
1849 	}
1850 	// Get local pointers to session
1851 	if (FuncList.ST_SetAttributeValue) {
1852 		rv = FuncList.ST_SetAttributeValue(rSession, hObject,
1853 		    pTemplate, ulCount);
1854 	} else {
1855 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1856 	}
1857 	return (rv);
1858 }
1859 
1860 CK_RV
1861 C_SetOperationState(CK_SESSION_HANDLE hSession,
1862 	CK_BYTE_PTR pOperationState,
1863 	CK_ULONG ulOperationStateLen,
1864 	CK_OBJECT_HANDLE hEncryptionKey,
1865 	CK_OBJECT_HANDLE hAuthenticationKey)
1866 {
1867 	CK_RV rv;
1868 	ST_SESSION_T rSession;
1869 
1870 	if (API_Initialized() == FALSE) {
1871 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1872 	}
1873 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1874 		return (CKR_SESSION_HANDLE_INVALID);
1875 	}
1876 	if (! pOperationState || ulOperationStateLen == 0) {
1877 		return (CKR_ARGUMENTS_BAD);
1878 	}
1879 	if (FuncList.ST_SetOperationState) {
1880 		rv = FuncList.ST_SetOperationState(rSession, pOperationState,
1881 		    ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
1882 	} else {
1883 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1884 	}
1885 	return (rv);
1886 }
1887 
1888 CK_RV
1889 C_SetPIN(CK_SESSION_HANDLE hSession,
1890 	CK_CHAR_PTR pOldPin,
1891 	CK_ULONG ulOldLen,
1892 	CK_CHAR_PTR pNewPin,
1893 	CK_ULONG ulNewLen)
1894 {
1895 	CK_RV rv;
1896 	ST_SESSION_T rSession;
1897 
1898 	if (API_Initialized() == FALSE) {
1899 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1900 	}
1901 	if (! pOldPin || ! pNewPin)
1902 		return (CKR_PIN_INVALID);
1903 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1904 		return (CKR_SESSION_HANDLE_INVALID);
1905 	}
1906 	if (FuncList.ST_SetPIN) {
1907 		rv = FuncList.ST_SetPIN(rSession, pOldPin, ulOldLen,
1908 		    pNewPin, ulNewLen);
1909 	} else {
1910 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1911 	}
1912 	return (rv);
1913 }
1914 
1915 CK_RV
1916 C_Sign(CK_SESSION_HANDLE hSession,
1917 	CK_BYTE_PTR pData,
1918 	CK_ULONG ulDataLen,
1919 	CK_BYTE_PTR pSignature,
1920 	CK_ULONG_PTR pulSignatureLen)
1921 {
1922 	CK_RV rv;
1923 	ST_SESSION_T rSession;
1924 
1925 	if (API_Initialized() == FALSE) {
1926 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1927 	}
1928 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1929 		return (CKR_SESSION_HANDLE_INVALID);
1930 	}
1931 	if (FuncList.ST_Sign) {
1932 		rv = FuncList.ST_Sign(rSession, pData, ulDataLen,
1933 		    pSignature, pulSignatureLen);
1934 	} else {
1935 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1936 	}
1937 	return (rv);
1938 }
1939 
1940 CK_RV
1941 C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
1942 	CK_BYTE_PTR pPart,
1943 	CK_ULONG ulPartLen,
1944 	CK_BYTE_PTR pEncryptedPart,
1945 	CK_ULONG_PTR pulEncryptedPartLen)
1946 {
1947 	CK_RV rv;
1948 	ST_SESSION_T rSession;
1949 	if (API_Initialized() == FALSE) {
1950 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1951 	}
1952 	if (! pPart || ! pulEncryptedPartLen) {
1953 		return (CKR_ARGUMENTS_BAD);
1954 	}
1955 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1956 		return (CKR_SESSION_HANDLE_INVALID);
1957 	}
1958 	if (FuncList.ST_SignEncryptUpdate) {
1959 		rv = FuncList.ST_SignEncryptUpdate(rSession, pPart,
1960 		    ulPartLen, pEncryptedPart, pulEncryptedPartLen);
1961 	} else {
1962 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1963 	}
1964 	return (rv);
1965 }
1966 
1967 CK_RV
1968 C_SignFinal(CK_SESSION_HANDLE hSession,
1969 	CK_BYTE_PTR pSignature,
1970 	CK_ULONG_PTR pulSignatureLen)
1971 {
1972 	CK_RV rv;
1973 	ST_SESSION_T rSession;
1974 
1975 	if (API_Initialized() == FALSE) {
1976 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1977 	}
1978 	if (! pulSignatureLen) {
1979 		return (CKR_ARGUMENTS_BAD);
1980 	}
1981 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1982 		return (CKR_SESSION_HANDLE_INVALID);
1983 	}
1984 	if (FuncList.ST_SignFinal) {
1985 		rv = FuncList.ST_SignFinal(rSession, pSignature,
1986 		    pulSignatureLen);
1987 	} else {
1988 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1989 	}
1990 	return (rv);
1991 }
1992 
1993 CK_RV
1994 C_SignInit(CK_SESSION_HANDLE hSession,
1995 	CK_MECHANISM_PTR pMechanism,
1996 	CK_OBJECT_HANDLE hKey)
1997 {
1998 	CK_RV rv;
1999 	ST_SESSION_T rSession;
2000 
2001 	if (API_Initialized() == FALSE) {
2002 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2003 	}
2004 	if (! pMechanism) {
2005 		return (CKR_MECHANISM_INVALID);
2006 	}
2007 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2008 		return (CKR_SESSION_HANDLE_INVALID);
2009 	}
2010 	if (FuncList.ST_SignInit) {
2011 		rv = FuncList.ST_SignInit(rSession, pMechanism, hKey);
2012 	} else {
2013 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2014 	}
2015 	return (rv);
2016 }
2017 
2018 CK_RV
2019 C_SignRecover(CK_SESSION_HANDLE hSession,
2020 	CK_BYTE_PTR pData,
2021 	CK_ULONG ulDataLen,
2022 	CK_BYTE_PTR pSignature,
2023 	CK_ULONG_PTR pulSignatureLen)
2024 {
2025 	CK_RV rv;
2026 	ST_SESSION_T rSession;
2027 
2028 	if (API_Initialized() == FALSE) {
2029 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2030 	}
2031 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2032 		return (CKR_SESSION_HANDLE_INVALID);
2033 	}
2034 	if (FuncList.ST_SignRecover) {
2035 		rv = FuncList.ST_SignRecover(rSession, pData,
2036 		    ulDataLen, pSignature, pulSignatureLen);
2037 	} else {
2038 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2039 	}
2040 	return (rv);
2041 }
2042 
2043 CK_RV
2044 C_SignRecoverInit(CK_SESSION_HANDLE hSession,
2045 	CK_MECHANISM_PTR pMechanism,
2046 	CK_OBJECT_HANDLE hKey)
2047 {
2048 	CK_RV rv;
2049 	ST_SESSION_T rSession;
2050 
2051 	if (API_Initialized() == FALSE) {
2052 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2053 	}
2054 	if (! pMechanism) {
2055 		return (CKR_MECHANISM_INVALID);
2056 	}
2057 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2058 		return (CKR_SESSION_HANDLE_INVALID);
2059 	}
2060 	if (FuncList.ST_SignRecoverInit) {
2061 		rv = FuncList.ST_SignRecoverInit(rSession, pMechanism, hKey);
2062 	} else {
2063 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2064 	}
2065 	return (rv);
2066 }
2067 
2068 CK_RV
2069 C_SignUpdate(CK_SESSION_HANDLE hSession,
2070 	CK_BYTE_PTR pPart,
2071 	CK_ULONG ulPartLen)
2072 {
2073 	CK_RV rv;
2074 	ST_SESSION_T rSession;
2075 
2076 	if (API_Initialized() == FALSE) {
2077 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2078 	}
2079 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2080 		return (CKR_SESSION_HANDLE_INVALID);
2081 	}
2082 	if (FuncList.ST_SignUpdate) {
2083 		rv = FuncList.ST_SignUpdate(rSession, pPart, ulPartLen);
2084 	} else {
2085 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2086 	}
2087 	return (rv);
2088 }
2089 
2090 CK_RV
2091 C_UnwrapKey(CK_SESSION_HANDLE hSession,
2092 	CK_MECHANISM_PTR pMechanism,
2093 	CK_OBJECT_HANDLE hUnwrappingKey,
2094 	CK_BYTE_PTR pWrappedKey,
2095 	CK_ULONG ulWrappedKeyLen,
2096 	CK_ATTRIBUTE_PTR pTemplate,
2097 	CK_ULONG ulAttributeCount,
2098 	CK_OBJECT_HANDLE_PTR phKey)
2099 {
2100 	CK_RV rv;
2101 	ST_SESSION_T rSession;
2102 
2103 	if (API_Initialized() == FALSE) {
2104 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2105 	}
2106 	if (!pMechanism) {
2107 		return (CKR_MECHANISM_INVALID);
2108 	}
2109 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2110 		return (CKR_SESSION_HANDLE_INVALID);
2111 	}
2112 	if (FuncList.ST_UnwrapKey) {
2113 		rv = FuncList.ST_UnwrapKey(rSession, pMechanism,
2114 		    hUnwrappingKey, pWrappedKey, ulWrappedKeyLen,
2115 		    pTemplate, ulAttributeCount, phKey);
2116 	} else {
2117 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2118 	}
2119 	return (rv);
2120 }
2121 
2122 CK_RV
2123 C_Verify(CK_SESSION_HANDLE hSession,
2124 	CK_BYTE_PTR pData,
2125 	CK_ULONG ulDataLen,
2126 	CK_BYTE_PTR pSignature,
2127 	CK_ULONG ulSignatureLen)
2128 {
2129 	CK_RV rv;
2130 	ST_SESSION_T rSession;
2131 
2132 	if (API_Initialized() == FALSE) {
2133 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2134 	}
2135 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2136 		return (CKR_SESSION_HANDLE_INVALID);
2137 	}
2138 	if (FuncList.ST_Verify) {
2139 		rv = FuncList.ST_Verify(rSession, pData, ulDataLen,
2140 		    pSignature, ulSignatureLen);
2141 	} else {
2142 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2143 	}
2144 	return (rv);
2145 }
2146 
2147 CK_RV
2148 C_VerifyFinal(CK_SESSION_HANDLE hSession,
2149 	CK_BYTE_PTR pSignature,
2150 	CK_ULONG ulSignatureLen)
2151 {
2152 	CK_RV rv;
2153 	ST_SESSION_T rSession;
2154 
2155 	if (API_Initialized() == FALSE) {
2156 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2157 	}
2158 	if (! pSignature) {
2159 		return (CKR_ARGUMENTS_BAD);
2160 	}
2161 
2162 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2163 		return (CKR_SESSION_HANDLE_INVALID);
2164 	}
2165 	if (FuncList.ST_VerifyFinal) {
2166 		rv = FuncList.ST_VerifyFinal(rSession, pSignature,
2167 		    ulSignatureLen);
2168 	} else {
2169 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2170 	}
2171 	return (rv);
2172 }
2173 
2174 CK_RV
2175 C_VerifyInit(CK_SESSION_HANDLE hSession,
2176 	CK_MECHANISM_PTR pMechanism,
2177 	CK_OBJECT_HANDLE hKey)
2178 {
2179 	CK_RV rv;
2180 	ST_SESSION_T rSession;
2181 
2182 	if (API_Initialized() == FALSE) {
2183 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2184 	}
2185 	if (! pMechanism) {
2186 		return (CKR_MECHANISM_INVALID);
2187 	}
2188 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2189 		return (CKR_SESSION_HANDLE_INVALID);
2190 	}
2191 
2192 	if (FuncList.ST_VerifyInit) {
2193 		rv = FuncList.ST_VerifyInit(rSession, pMechanism, hKey);
2194 	} else {
2195 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2196 	}
2197 	return (rv);
2198 }
2199 
2200 CK_RV
2201 C_VerifyRecover(CK_SESSION_HANDLE hSession,
2202 	CK_BYTE_PTR pSignature,
2203 	CK_ULONG ulSignatureLen,
2204 	CK_BYTE_PTR pData,
2205 	CK_ULONG_PTR pulDataLen)
2206 {
2207 	CK_RV rv;
2208 	ST_SESSION_T rSession;
2209 
2210 	if (API_Initialized() == FALSE) {
2211 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2212 	}
2213 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2214 		return (CKR_SESSION_HANDLE_INVALID);
2215 	}
2216 	if (FuncList.ST_VerifyRecover) {
2217 		rv = FuncList.ST_VerifyRecover(rSession, pSignature,
2218 		    ulSignatureLen, pData, pulDataLen);
2219 	} else {
2220 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2221 	}
2222 	return (rv);
2223 }
2224 
2225 CK_RV
2226 C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
2227 	CK_MECHANISM_PTR pMechanism,
2228 	CK_OBJECT_HANDLE hKey)
2229 {
2230 	CK_RV rv;
2231 	ST_SESSION_T rSession;
2232 
2233 	if (API_Initialized() == FALSE) {
2234 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2235 	}
2236 	if (! pMechanism) {
2237 		return (CKR_MECHANISM_INVALID);
2238 	}
2239 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2240 		return (CKR_SESSION_HANDLE_INVALID);
2241 	}
2242 	if (FuncList.ST_VerifyRecoverInit) {
2243 		rv = FuncList.ST_VerifyRecoverInit(rSession, pMechanism, hKey);
2244 	} else {
2245 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2246 	}
2247 	return (rv);
2248 }
2249 
2250 CK_RV
2251 C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2252 	CK_BYTE_PTR pPart,
2253 	CK_ULONG ulPartLen)
2254 {
2255 	CK_RV rv;
2256 	ST_SESSION_T rSession;
2257 
2258 	if (API_Initialized() == FALSE) {
2259 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2260 	}
2261 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2262 		return (CKR_SESSION_HANDLE_INVALID);
2263 	}
2264 	if (FuncList.ST_VerifyUpdate) {
2265 		rv = FuncList.ST_VerifyUpdate(rSession, pPart, ulPartLen);
2266 	} else {
2267 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2268 	}
2269 	return (rv);
2270 }
2271 
2272 /*ARGSUSED*/
2273 CK_RV
2274 C_WaitForSlotEvent(CK_FLAGS flags,
2275 	CK_SLOT_ID_PTR pSlot,
2276 	CK_VOID_PTR pReserved)
2277 {
2278 	if (API_Initialized() == FALSE) {
2279 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2280 	}
2281 	return (CKR_FUNCTION_NOT_SUPPORTED);
2282 }
2283 
2284 CK_RV
2285 C_WrapKey(CK_SESSION_HANDLE hSession,
2286 	CK_MECHANISM_PTR pMechanism,
2287 	CK_OBJECT_HANDLE hWrappingKey,
2288 	CK_OBJECT_HANDLE hKey,
2289 	CK_BYTE_PTR pWrappedKey,
2290 	CK_ULONG_PTR pulWrappedKeyLen)
2291 {
2292 	CK_RV rv;
2293 	ST_SESSION_T rSession;
2294 
2295 	if (API_Initialized() == FALSE) {
2296 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2297 	}
2298 	if (! pMechanism) {
2299 		return (CKR_MECHANISM_INVALID);
2300 	}
2301 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2302 		return (CKR_SESSION_HANDLE_INVALID);
2303 	}
2304 	if (FuncList.ST_WrapKey) {
2305 		rv = FuncList.ST_WrapKey(rSession, pMechanism, hWrappingKey,
2306 		    hKey, pWrappedKey, pulWrappedKeyLen);
2307 	} else {
2308 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2309 	}
2310 	return (rv);
2311 }
2312 
2313 #pragma init(api_init)
2314 #pragma fini(api_fini)
2315 
2316 static void
2317 api_init(void)
2318 {
2319 	loginit();
2320 	if (! Initialized) {
2321 		(void) pthread_atfork(tpmtoken_fork_prepare,
2322 		    tpmtoken_fork_parent, tpmtoken_fork_child);
2323 		Initialized = 1;
2324 	}
2325 }
2326 
2327 static void
2328 api_fini()
2329 {
2330 	logterm();
2331 	if (API_Initialized() == TRUE) {
2332 		(void) do_finalize(NULL);
2333 	}
2334 }
2335