xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/api_interface.c (revision 07a48826732249fcd3aa8dd53c8389595e9f1fbc)
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 	if (slotID > NUMBER_SLOTS_MANAGED)
406 		return (CKR_SLOT_ID_INVALID);
407 	/*
408 	 * Proc Mutex is locked when we remove from the seesion list in
409 	 * Close SEssion.  Therefore we don't need to do any locking
410 	 * the atomic operations are controled when we use the linked list
411 	 */
412 	pCur = (Anchor ? Anchor->SessListBeg : NULL);
413 	while (pCur) {
414 		/*
415 		 * Session owned by the slot we are working on
416 		 * There is a basic problem here.  We are using th pCur
417 		 * to point to the current one, however we delete it from
418 		 * the linked list and can no longer go Forward.  So we
419 		 * have to use the fact that this is a doubly linked list
420 		 * and get the previous pointer.  After deletion, the next
421 		 * pointer of this block will point to the next one in the
422 		 * list.
423 		 * If the value is Null, then this was the first one in
424 		 * the list and we just set pCur to the SessListBeg.
425 		 */
426 		if (pCur->SltId == slotID) {
427 			pPrev = pCur->Previous;
428 			rv = C_CloseSession((CK_SESSION_HANDLE)pCur);
429 			if (rv == CKR_OK ||
430 			    rv == CKR_SESSION_CLOSED ||
431 			    rv == CKR_SESSION_HANDLE_INVALID) {
432 				if (pPrev == NULL) {
433 					pCur = Anchor->SessListBeg;
434 				} else {
435 					pCur = pPrev->Next;
436 				}
437 			} else {
438 				return (rv);
439 			}
440 		} else {
441 			pCur = pCur->Next;
442 		}
443 	}
444 	LOG("CloseAllSessions OK");
445 	return (CKR_OK);
446 }
447 CK_RV
448 C_CloseSession(CK_SESSION_HANDLE hSession)
449 {
450 	CK_RV rv;
451 	Session_Struct_t *sessp;
452 	ST_SESSION_T rSession;
453 	LOG("C_CloseSession");
454 	if (API_Initialized() == FALSE) {
455 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
456 	}
457 	/* Validate Session */
458 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
459 		return (CKR_SESSION_HANDLE_INVALID);
460 	}
461 
462 	if (FuncList.ST_CloseSession) {
463 		/* Map the Session to the slot session */
464 		rv = FuncList.ST_CloseSession(rSession);
465 
466 		if (rv == CKR_OK) {
467 			sessp = (Session_Struct_t *)hSession;
468 			RemoveFromSessionList(sessp);
469 		}
470 	} else {
471 		rv = CKR_FUNCTION_NOT_SUPPORTED;
472 	}
473 	return (rv);
474 }
475 
476 CK_RV
477 C_CopyObject(
478 	CK_SESSION_HANDLE	hSession,
479 	CK_OBJECT_HANDLE	hObject,
480 	CK_ATTRIBUTE_PTR	pTemplate,
481 	CK_ULONG		ulCount,
482 	CK_OBJECT_HANDLE_PTR	phNewObject)
483 {
484 	CK_RV rv;
485 	ST_SESSION_T rSession;
486 	LOG("C_CopyObject");
487 	if (API_Initialized() == FALSE) {
488 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
489 	}
490 	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
491 		return (CKR_SESSION_HANDLE_INVALID);
492 	}
493 	if (!phNewObject) {
494 		return (CKR_ARGUMENTS_BAD);
495 	}
496 	/*
497 	 * A null template with a count will cause the lower layer
498 	 * to have problems.
499 	 * Template with 0 count is not a problem.
500 	 */
501 	if (!pTemplate && ulCount) {
502 		return (CKR_ARGUMENTS_BAD);
503 	}
504 	if (FuncList.ST_CopyObject) {
505 		rv = FuncList.ST_CopyObject(rSession, hObject, pTemplate,
506 		    ulCount, phNewObject);
507 	} else {
508 		rv = CKR_FUNCTION_NOT_SUPPORTED;
509 	}
510 	return (rv);
511 }
512 
513 CK_RV
514 C_CreateObject(
515 	CK_SESSION_HANDLE	hSession,
516 	CK_ATTRIBUTE_PTR	pTemplate,
517 	CK_ULONG		ulCount,
518 	CK_OBJECT_HANDLE_PTR	phObject)
519 {
520 	CK_RV	rv;
521 	ST_SESSION_T rSession;
522 
523 	if (API_Initialized() == FALSE) {
524 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
525 	}
526 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
527 		return (CKR_SESSION_HANDLE_INVALID);
528 	}
529 	if (! pTemplate) {
530 		return (CKR_TEMPLATE_INCOMPLETE);
531 	}
532 	if (ulCount == 0) {
533 		return (CKR_TEMPLATE_INCOMPLETE);
534 	}
535 	if (! phObject) {
536 		return (CKR_ARGUMENTS_BAD);
537 	}
538 	if (FuncList.ST_CreateObject) {
539 		// Map the Session to the slot session
540 		rv = FuncList.ST_CreateObject(rSession, pTemplate,
541 		    ulCount, phObject);
542 	} else {
543 		rv = CKR_FUNCTION_NOT_SUPPORTED;
544 	}
545 	return (rv);
546 }
547 
548 CK_RV
549 C_Decrypt(CK_SESSION_HANDLE hSession,
550 	CK_BYTE_PTR	pEncryptedData,
551 	CK_ULONG	ulEncryptedDataLen,
552 	CK_BYTE_PTR	pData,
553 	CK_ULONG_PTR	pulDataLen)
554 {
555 	CK_RV	rv;
556 	ST_SESSION_T rSession;
557 
558 	if (API_Initialized() == FALSE) {
559 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
560 	}
561 	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
562 		return (CKR_SESSION_HANDLE_INVALID);
563 	}
564 	if (FuncList.ST_Decrypt) {
565 		rv = FuncList.ST_Decrypt(rSession, pEncryptedData,
566 		    ulEncryptedDataLen, pData, pulDataLen);
567 	} else {
568 		rv = CKR_FUNCTION_NOT_SUPPORTED;
569 	}
570 	return (rv);
571 }
572 
573 CK_RV
574 C_DecryptDigestUpdate(
575 	CK_SESSION_HANDLE hSession,
576 	CK_BYTE_PTR	pEncryptedPart,
577 	CK_ULONG	ulEncryptedPartLen,
578 	CK_BYTE_PTR	pPart,
579 	CK_ULONG_PTR	pulPartLen)
580 {
581 	CK_RV	rv;
582 	ST_SESSION_T rSession;
583 
584 	if (API_Initialized() == FALSE) {
585 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
586 	}
587 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
588 		return (CKR_SESSION_HANDLE_INVALID);
589 	}
590 	if (! pEncryptedPart || ! pulPartLen) {
591 		return (CKR_ARGUMENTS_BAD);
592 	}
593 	if (FuncList.ST_DecryptDigestUpdate) {
594 		rv = FuncList.ST_DecryptDigestUpdate(rSession, pEncryptedPart,
595 		    ulEncryptedPartLen, pPart, pulPartLen);
596 	} else {
597 		rv = CKR_FUNCTION_NOT_SUPPORTED;
598 	}
599 	return (rv);
600 }
601 
602 CK_RV
603 C_DecryptFinal(CK_SESSION_HANDLE hSession,
604 	CK_BYTE_PTR	pLastPart,
605 	CK_ULONG_PTR	pulLastPartLen)
606 {
607 	CK_RV	rv;
608 	ST_SESSION_T rSession;
609 
610 	if (API_Initialized() == FALSE) {
611 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
612 	}
613 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
614 		return (CKR_SESSION_HANDLE_INVALID);
615 	}
616 	/*
617 	 * It is acceptable to have a Null pointer for the data since
618 	 * it is trying to get the length of the last part....
619 	 * The spec is unclear if a second call to Final is needed
620 	 * if there is no data in the last part.
621 	 */
622 	if (! pulLastPartLen) {
623 		return (CKR_ARGUMENTS_BAD);
624 	}
625 	if (FuncList.ST_DecryptFinal) {
626 		rv = FuncList.ST_DecryptFinal(rSession, pLastPart,
627 		    pulLastPartLen);
628 	} else {
629 		rv = CKR_FUNCTION_NOT_SUPPORTED;
630 	}
631 	return (rv);
632 }
633 
634 CK_RV
635 C_DecryptInit(CK_SESSION_HANDLE hSession,
636 	CK_MECHANISM_PTR pMechanism,
637 	CK_OBJECT_HANDLE hKey)
638 {
639 	CK_RV rv;
640 	ST_SESSION_T rSession;
641 
642 	if (API_Initialized() == FALSE) {
643 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
644 	}
645 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
646 		return (CKR_SESSION_HANDLE_INVALID);
647 	}
648 	if (! pMechanism) {
649 		return (CKR_MECHANISM_INVALID);
650 	}
651 	if (FuncList.ST_DecryptInit) {
652 		rv = FuncList.ST_DecryptInit(rSession, pMechanism, hKey);
653 	} else {
654 		rv = CKR_FUNCTION_NOT_SUPPORTED;
655 	}
656 	return (rv);
657 }
658 
659 CK_RV
660 C_DecryptUpdate(CK_SESSION_HANDLE hSession,
661 	CK_BYTE_PTR	pEncryptedPart,
662 	CK_ULONG	ulEncryptedPartLen,
663 	CK_BYTE_PTR	pPart,
664 	CK_ULONG_PTR	pulPartLen)
665 {
666 	CK_RV	rv;
667 	ST_SESSION_T rSession;
668 
669 	if (API_Initialized() == FALSE) {
670 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
671 	}
672 	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
673 		return (CKR_SESSION_HANDLE_INVALID);
674 	}
675 	if (!pEncryptedPart || !pulPartLen) {
676 		return (CKR_ARGUMENTS_BAD);
677 	}
678 	if (FuncList.ST_DecryptUpdate) {
679 		rv = FuncList.ST_DecryptUpdate(rSession, pEncryptedPart,
680 		    ulEncryptedPartLen, pPart, pulPartLen);
681 	} else {
682 		rv = CKR_FUNCTION_NOT_SUPPORTED;
683 	}
684 	return (rv);
685 }
686 
687 CK_RV
688 C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
689 	CK_BYTE_PTR	pEncryptedPart,
690 	CK_ULONG	ulEncryptedPartLen,
691 	CK_BYTE_PTR	pPart,
692 	CK_ULONG_PTR	pulPartLen)
693 {
694 	CK_RV	rv;
695 	ST_SESSION_T rSession;
696 
697 	if (API_Initialized() == FALSE) {
698 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
699 	}
700 	// Validate Session
701 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
702 		return (CKR_SESSION_HANDLE_INVALID);
703 	}
704 	// May have to let these go through and let the STDLL handle them
705 	if (! pEncryptedPart || ! pulPartLen) {
706 		return (CKR_ARGUMENTS_BAD);
707 	}
708 	// Get local pointers to session
709 	if (FuncList.ST_DecryptVerifyUpdate) {
710 		// Map the Session to the slot session
711 		rv = FuncList.ST_DecryptVerifyUpdate(rSession,
712 		    pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
713 	} else {
714 		rv = CKR_FUNCTION_NOT_SUPPORTED;
715 	}
716 	return (rv);
717 }
718 
719 CK_RV
720 C_DeriveKey(CK_SESSION_HANDLE	hSession,
721 	CK_MECHANISM_PTR	pMechanism,
722 	CK_OBJECT_HANDLE	hBaseKey,
723 	CK_ATTRIBUTE_PTR	pTemplate,
724 	CK_ULONG		ulAttributeCount,
725 	CK_OBJECT_HANDLE_PTR	phKey)
726 {
727 	CK_RV	rv;
728 	ST_SESSION_T rSession;
729 
730 	if (API_Initialized() == FALSE) {
731 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
732 	}
733 	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
734 		return (CKR_SESSION_HANDLE_INVALID);
735 	}
736 
737 	if (!pMechanism) {
738 		return (CKR_MECHANISM_INVALID);
739 	}
740 	if (!pTemplate && ulAttributeCount) {
741 		return (CKR_ARGUMENTS_BAD);
742 	}
743 	if (FuncList.ST_DeriveKey) {
744 		rv = FuncList.ST_DeriveKey(rSession, pMechanism,
745 		    hBaseKey, pTemplate, ulAttributeCount, phKey);
746 	} else {
747 		rv = CKR_FUNCTION_NOT_SUPPORTED;
748 	}
749 	return (rv);
750 }
751 
752 CK_RV
753 C_DestroyObject(CK_SESSION_HANDLE hSession,
754 	CK_OBJECT_HANDLE hObject)
755 {
756 	CK_RV rv;
757 	ST_SESSION_T rSession;
758 
759 	if (API_Initialized() == FALSE) {
760 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
761 	}
762 	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
763 		return (CKR_SESSION_HANDLE_INVALID);
764 	}
765 	if (FuncList.ST_DestroyObject) {
766 		rv = FuncList.ST_DestroyObject(rSession, hObject);
767 	} else {
768 		rv = CKR_FUNCTION_NOT_SUPPORTED;
769 	}
770 	return (rv);
771 }
772 
773 CK_RV
774 C_Digest(CK_SESSION_HANDLE hSession,
775 	CK_BYTE_PTR	pData,
776 	CK_ULONG	ulDataLen,
777 	CK_BYTE_PTR	pDigest,
778 	CK_ULONG_PTR	pulDigestLen)
779 {
780 	CK_RV	rv;
781 	ST_SESSION_T rSession;
782 
783 	if (API_Initialized() == FALSE) {
784 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
785 	}
786 	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
787 		return (CKR_SESSION_HANDLE_INVALID);
788 	}
789 	if (FuncList.ST_Digest) {
790 		rv = FuncList.ST_Digest(rSession, pData, ulDataLen,
791 		    pDigest, pulDigestLen);
792 	} else {
793 		rv = CKR_FUNCTION_NOT_SUPPORTED;
794 	}
795 	return (rv);
796 }
797 
798 CK_RV
799 C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
800 	CK_BYTE_PTR	pPart,
801 	CK_ULONG	ulPartLen,
802 	CK_BYTE_PTR	pEncryptedPart,
803 	CK_ULONG_PTR	pulEncryptedPartLen)
804 {
805 	CK_RV rv;
806 	ST_SESSION_T rSession;
807 
808 	if (API_Initialized() == FALSE) {
809 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
810 	}
811 	if (! pPart || ! pulEncryptedPartLen) {
812 		return (CKR_ARGUMENTS_BAD);
813 	}
814 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
815 		return (CKR_SESSION_HANDLE_INVALID);
816 	}
817 	if (FuncList.ST_DigestEncryptUpdate) {
818 		rv = FuncList.ST_DigestEncryptUpdate(rSession, pPart,
819 		    ulPartLen, pEncryptedPart, pulEncryptedPartLen);
820 	} else {
821 		rv = CKR_FUNCTION_NOT_SUPPORTED;
822 	}
823 	return (rv);
824 }
825 
826 CK_RV
827 C_DigestFinal(CK_SESSION_HANDLE hSession,
828 	CK_BYTE_PTR	pDigest,
829 	CK_ULONG_PTR	pulDigestLen)
830 {
831 	CK_RV rv;
832 	ST_SESSION_T rSession;
833 
834 	if (API_Initialized() == FALSE) {
835 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
836 	}
837 	if (! pulDigestLen) {
838 		return (CKR_ARGUMENTS_BAD);
839 	}
840 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
841 		return (CKR_SESSION_HANDLE_INVALID);
842 	}
843 	if (FuncList.ST_DigestFinal) {
844 		rv = FuncList.ST_DigestFinal(rSession, pDigest, pulDigestLen);
845 	} else {
846 		rv = CKR_FUNCTION_NOT_SUPPORTED;
847 	}
848 	return (rv);
849 }
850 
851 CK_RV
852 C_DigestInit(CK_SESSION_HANDLE hSession,
853 	CK_MECHANISM_PTR pMechanism)
854 {
855 	CK_RV rv;
856 	ST_SESSION_T rSession;
857 
858 	if (API_Initialized() == FALSE) {
859 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
860 	}
861 	if (! pMechanism) {
862 		return (CKR_MECHANISM_INVALID);
863 	}
864 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
865 		return (CKR_SESSION_HANDLE_INVALID);
866 	}
867 	if (FuncList.ST_DigestInit) {
868 		rv = FuncList.ST_DigestInit(rSession, pMechanism);
869 	} else {
870 		rv = CKR_FUNCTION_NOT_SUPPORTED;
871 	}
872 	return (rv);
873 }
874 
875 CK_RV
876 C_DigestKey(CK_SESSION_HANDLE hSession,
877 	CK_OBJECT_HANDLE hKey)
878 {
879 	CK_RV rv;
880 	ST_SESSION_T rSession;
881 
882 	if (API_Initialized() == FALSE) {
883 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
884 	}
885 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
886 		return (CKR_SESSION_HANDLE_INVALID);
887 	}
888 	if (FuncList.ST_DigestKey) {
889 		rv = FuncList.ST_DigestKey(rSession, hKey);
890 	} else {
891 		rv = CKR_FUNCTION_NOT_SUPPORTED;
892 	}
893 	return (rv);
894 }
895 
896 CK_RV
897 C_DigestUpdate(CK_SESSION_HANDLE hSession,
898 	CK_BYTE_PTR pPart,
899 	CK_ULONG ulPartLen)
900 {
901 	CK_RV rv;
902 	ST_SESSION_T rSession;
903 	if (API_Initialized() == FALSE) {
904 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
905 	}
906 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
907 		return (CKR_SESSION_HANDLE_INVALID);
908 	}
909 	if (FuncList.ST_DigestUpdate) {
910 		rv = FuncList.ST_DigestUpdate(rSession, pPart, ulPartLen);
911 	} else {
912 		rv = CKR_FUNCTION_NOT_SUPPORTED;
913 	}
914 	return (rv);
915 }
916 
917 CK_RV
918 C_Encrypt(CK_SESSION_HANDLE hSession,
919 	CK_BYTE_PTR pData,
920 	CK_ULONG ulDataLen,
921 	CK_BYTE_PTR pEncryptedData,
922 	CK_ULONG_PTR pulEncryptedDataLen)
923 {
924 	CK_RV rv;
925 	ST_SESSION_T rSession;
926 
927 	if (API_Initialized() == FALSE) {
928 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
929 	}
930 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
931 		return (CKR_SESSION_HANDLE_INVALID);
932 	}
933 	// Get local pointers to session
934 	if (FuncList.ST_Encrypt) {
935 		// Map the Session to the slot session
936 		rv = FuncList.ST_Encrypt(rSession, pData, ulDataLen,
937 		    pEncryptedData, pulEncryptedDataLen);
938 	} else {
939 		rv = CKR_FUNCTION_NOT_SUPPORTED;
940 	}
941 	return (rv);
942 }
943 
944 CK_RV
945 C_EncryptFinal(CK_SESSION_HANDLE hSession,
946 	CK_BYTE_PTR pLastEncryptedPart,
947 	CK_ULONG_PTR pulLastEncryptedPartLen)
948 {
949 	CK_RV rv;
950 	ST_SESSION_T rSession;
951 
952 	if (API_Initialized() == FALSE) {
953 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
954 	}
955 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
956 		return (CKR_SESSION_HANDLE_INVALID);
957 	}
958 	if (FuncList.ST_EncryptFinal) {
959 		rv = FuncList.ST_EncryptFinal(rSession,
960 		    pLastEncryptedPart, pulLastEncryptedPartLen);
961 	} else {
962 		rv = CKR_FUNCTION_NOT_SUPPORTED;
963 	}
964 	return (rv);
965 }
966 
967 CK_RV
968 C_EncryptInit(CK_SESSION_HANDLE hSession,
969 	CK_MECHANISM_PTR pMechanism,
970 	CK_OBJECT_HANDLE hKey)
971 {
972 	CK_RV rv;
973 	ST_SESSION_T rSession;
974 
975 	if (API_Initialized() == FALSE) {
976 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
977 	}
978 	if (! pMechanism) {
979 		return (CKR_MECHANISM_INVALID);
980 	}
981 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
982 		return (CKR_SESSION_HANDLE_INVALID);
983 	}
984 	if (FuncList.ST_EncryptInit) {
985 		rv = FuncList.ST_EncryptInit(rSession, pMechanism, hKey);
986 	} else {
987 		rv = CKR_FUNCTION_NOT_SUPPORTED;
988 	}
989 	return (rv);
990 }
991 
992 CK_RV
993 C_EncryptUpdate(CK_SESSION_HANDLE hSession,
994 	CK_BYTE_PTR pPart,
995 	CK_ULONG ulPartLen,
996 	CK_BYTE_PTR pEncryptedPart,
997 	CK_ULONG_PTR pulEncryptedPartLen)
998 {
999 	CK_RV rv;
1000 	ST_SESSION_T rSession;
1001 
1002 	if (API_Initialized() == FALSE) {
1003 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1004 	}
1005 	if (!pPart || !pulEncryptedPartLen) {
1006 		return (CKR_ARGUMENTS_BAD);
1007 	}
1008 	if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1009 		return (CKR_SESSION_HANDLE_INVALID);
1010 	}
1011 	if (FuncList.ST_EncryptUpdate) {
1012 		rv = FuncList.ST_EncryptUpdate(rSession, pPart, ulPartLen,
1013 		    pEncryptedPart, pulEncryptedPartLen);
1014 	} else {
1015 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1016 	}
1017 	return (rv);
1018 }
1019 
1020 CK_RV
1021 do_finalize(CK_VOID_PTR pReserved)
1022 {
1023 	if (API_Initialized() == FALSE) {
1024 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1025 	}
1026 	if (pReserved != NULL) {
1027 		return (CKR_ARGUMENTS_BAD);
1028 	}
1029 	(void) pthread_mutex_lock(&global_mutex);
1030 	if (Anchor)
1031 		Terminate_All_Process_Sessions();
1032 
1033 	if (FuncList.ST_Finalize)
1034 		FuncList.ST_Finalize(0);
1035 
1036 	free(Anchor);
1037 	Anchor = NULL;
1038 
1039 	(void) pthread_mutex_unlock(&global_mutex);
1040 	return (CKR_OK);
1041 }
1042 
1043 CK_RV
1044 C_Finalize(CK_VOID_PTR pReserved) {
1045 	return (do_finalize(pReserved));
1046 }
1047 
1048 CK_RV
1049 C_FindObjects(CK_SESSION_HANDLE    hSession,
1050 	CK_OBJECT_HANDLE_PTR phObject,
1051 	CK_ULONG ulMaxObjectCount,
1052 	CK_ULONG_PTR pulObjectCount)
1053 {
1054 	CK_RV rv;
1055 	ST_SESSION_T rSession;
1056 
1057 	if (API_Initialized() == FALSE) {
1058 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1059 	}
1060 	if (! phObject || ! pulObjectCount) {
1061 		return (CKR_ARGUMENTS_BAD);
1062 	}
1063 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1064 		return (CKR_SESSION_HANDLE_INVALID);
1065 	}
1066 	if (FuncList.ST_FindObjects) {
1067 		rv = FuncList.ST_FindObjects(rSession, phObject,
1068 		    ulMaxObjectCount, pulObjectCount);
1069 	} else {
1070 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1071 	}
1072 	return (rv);
1073 }
1074 
1075 CK_RV
1076 C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1077 {
1078 	CK_RV rv;
1079 	ST_SESSION_T rSession;
1080 
1081 	if (API_Initialized() == FALSE) {
1082 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1083 	}
1084 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1085 		return (CKR_SESSION_HANDLE_INVALID);
1086 	}
1087 	if (FuncList.ST_FindObjectsFinal) {
1088 		rv = FuncList.ST_FindObjectsFinal(rSession);
1089 	} else {
1090 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1091 	}
1092 	return (rv);
1093 }
1094 
1095 CK_RV
1096 C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1097 	CK_ATTRIBUTE_PTR pTemplate,
1098 	CK_ULONG ulCount)
1099 {
1100 	CK_RV rv;
1101 	ST_SESSION_T rSession;
1102 
1103 	if (API_Initialized() == FALSE) {
1104 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1105 	}
1106 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1107 		return (CKR_SESSION_HANDLE_INVALID);
1108 	}
1109 	if (FuncList.ST_FindObjectsInit) {
1110 		rv = FuncList.ST_FindObjectsInit(rSession, pTemplate, ulCount);
1111 	} else {
1112 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1113 	}
1114 	return (rv);
1115 }
1116 
1117 CK_RV
1118 C_GenerateKey(CK_SESSION_HANDLE    hSession,
1119 	CK_MECHANISM_PTR pMechanism,
1120 	CK_ATTRIBUTE_PTR pTemplate,
1121 	CK_ULONG ulCount,
1122 	CK_OBJECT_HANDLE_PTR phKey)
1123 {
1124 	CK_RV rv;
1125 	ST_SESSION_T rSession;
1126 
1127 	if (API_Initialized() == FALSE) {
1128 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1129 	}
1130 	if (! pMechanism) {
1131 		return (CKR_MECHANISM_INVALID);
1132 	}
1133 	if (! phKey) {
1134 		return (CKR_ARGUMENTS_BAD);
1135 	}
1136 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1137 		return (CKR_SESSION_HANDLE_INVALID);
1138 	}
1139 	if (FuncList.ST_GenerateKey) {
1140 		rv = FuncList.ST_GenerateKey(rSession, pMechanism,
1141 		    pTemplate, ulCount, phKey);
1142 	} else {
1143 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1144 	}
1145 	return (rv);
1146 }
1147 
1148 CK_RV
1149 C_GenerateKeyPair(CK_SESSION_HANDLE    hSession,
1150 	CK_MECHANISM_PTR pMechanism,
1151 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
1152 	CK_ULONG ulPublicKeyAttributeCount,
1153 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
1154 	CK_ULONG ulPrivateKeyAttributeCount,
1155 	CK_OBJECT_HANDLE_PTR phPublicKey,
1156 	CK_OBJECT_HANDLE_PTR phPrivateKey)
1157 {
1158 	CK_RV rv;
1159 	ST_SESSION_T rSession;
1160 
1161 	if (API_Initialized() == FALSE) {
1162 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1163 	}
1164 	if (! pMechanism) {
1165 		return (CKR_MECHANISM_INVALID);
1166 	}
1167 	if (! phPublicKey || ! phPrivateKey) {
1168 		return (CKR_ARGUMENTS_BAD);
1169 	}
1170 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1171 		return (CKR_SESSION_HANDLE_INVALID);
1172 	}
1173 	if (FuncList.ST_GenerateKeyPair) {
1174 		rv = FuncList.ST_GenerateKeyPair(rSession,
1175 		    pMechanism, pPublicKeyTemplate,
1176 		    ulPublicKeyAttributeCount, pPrivateKeyTemplate,
1177 		    ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey);
1178 	} else {
1179 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1180 	}
1181 	return (rv);
1182 }
1183 
1184 CK_RV
1185 C_GenerateRandom(CK_SESSION_HANDLE hSession,
1186 	CK_BYTE_PTR RandomData,
1187 	CK_ULONG ulRandomLen)
1188 {
1189 	CK_RV rv;
1190 	ST_SESSION_T rSession;
1191 
1192 	if (API_Initialized() == FALSE) {
1193 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1194 	}
1195 	if (! RandomData)
1196 		return (CKR_ARGUMENTS_BAD);
1197 
1198 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1199 		return (CKR_SESSION_HANDLE_INVALID);
1200 	}
1201 	if (FuncList.ST_GenerateRandom) {
1202 		rv = FuncList.ST_GenerateRandom(rSession, RandomData,
1203 		    ulRandomLen);
1204 	} else {
1205 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1206 	}
1207 	return (rv);
1208 }
1209 
1210 CK_RV
1211 C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1212 	CK_OBJECT_HANDLE hObject,
1213 	CK_ATTRIBUTE_PTR pTemplate,
1214 	CK_ULONG ulCount)
1215 {
1216 	CK_RV rv;
1217 	ST_SESSION_T rSession;
1218 
1219 	if (API_Initialized() == FALSE) {
1220 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1221 	}
1222 	if (! pTemplate) {
1223 		return (CKR_TEMPLATE_INCOMPLETE);
1224 	}
1225 	if (ulCount == 0) {
1226 		return (CKR_TEMPLATE_INCOMPLETE);
1227 	}
1228 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1229 		return (CKR_SESSION_HANDLE_INVALID);
1230 	}
1231 	if (FuncList.ST_GetAttributeValue) {
1232 		rv = FuncList.ST_GetAttributeValue(rSession, hObject,
1233 		    pTemplate, ulCount);
1234 	} else {
1235 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1236 	}
1237 	return (rv);
1238 }
1239 
1240 CK_RV
1241 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
1242 {
1243 	_init();
1244 
1245 	PK11_Functions.version.major = VERSION_MAJOR;
1246 	PK11_Functions.version.minor = VERSION_MINOR;
1247 	PK11_Functions.C_Initialize = C_Initialize;
1248 	PK11_Functions.C_Finalize = C_Finalize;
1249 	PK11_Functions.C_GetInfo = C_GetInfo;
1250 	PK11_Functions.C_GetFunctionList = C_GetFunctionList;
1251 	PK11_Functions.C_GetSlotList = C_GetSlotList;
1252 	PK11_Functions.C_GetSlotInfo = C_GetSlotInfo;
1253 	PK11_Functions.C_GetTokenInfo = C_GetTokenInfo;
1254 	PK11_Functions.C_GetMechanismList = C_GetMechanismList;
1255 	PK11_Functions.C_GetMechanismInfo = C_GetMechanismInfo;
1256 	PK11_Functions.C_InitToken = C_InitToken;
1257 	PK11_Functions.C_InitPIN = C_InitPIN;
1258 	PK11_Functions.C_SetPIN = C_SetPIN;
1259 	PK11_Functions.C_OpenSession = C_OpenSession;
1260 	PK11_Functions.C_CloseSession = C_CloseSession;
1261 	PK11_Functions.C_CloseAllSessions = C_CloseAllSessions;
1262 	PK11_Functions.C_GetSessionInfo = C_GetSessionInfo;
1263 	PK11_Functions.C_GetOperationState = C_GetOperationState;
1264 	PK11_Functions.C_SetOperationState = C_SetOperationState;
1265 	PK11_Functions.C_Login = C_Login;
1266 	PK11_Functions.C_Logout = C_Logout;
1267 	PK11_Functions.C_CreateObject = C_CreateObject;
1268 	PK11_Functions.C_CopyObject = C_CopyObject;
1269 	PK11_Functions.C_DestroyObject = C_DestroyObject;
1270 	PK11_Functions.C_GetObjectSize = C_GetObjectSize;
1271 	PK11_Functions.C_GetAttributeValue = C_GetAttributeValue;
1272 	PK11_Functions.C_SetAttributeValue = C_SetAttributeValue;
1273 	PK11_Functions.C_FindObjectsInit = C_FindObjectsInit;
1274 	PK11_Functions.C_FindObjects = C_FindObjects;
1275 	PK11_Functions.C_FindObjectsFinal = C_FindObjectsFinal;
1276 	PK11_Functions.C_EncryptInit = C_EncryptInit;
1277 	PK11_Functions.C_Encrypt = C_Encrypt;
1278 	PK11_Functions.C_EncryptUpdate = C_EncryptUpdate;
1279 	PK11_Functions.C_EncryptFinal = C_EncryptFinal;
1280 	PK11_Functions.C_DecryptInit = C_DecryptInit;
1281 	PK11_Functions.C_Decrypt = C_Decrypt;
1282 	PK11_Functions.C_DecryptUpdate = C_DecryptUpdate;
1283 	PK11_Functions.C_DecryptFinal = C_DecryptFinal;
1284 	PK11_Functions.C_DigestInit = C_DigestInit;
1285 	PK11_Functions.C_Digest = C_Digest;
1286 	PK11_Functions.C_DigestUpdate = C_DigestUpdate;
1287 	PK11_Functions.C_DigestKey = C_DigestKey;
1288 	PK11_Functions.C_DigestFinal = C_DigestFinal;
1289 	PK11_Functions.C_SignInit = C_SignInit;
1290 	PK11_Functions.C_Sign = C_Sign;
1291 	PK11_Functions.C_SignUpdate = C_SignUpdate;
1292 	PK11_Functions.C_SignFinal = C_SignFinal;
1293 	PK11_Functions.C_SignRecoverInit = C_SignRecoverInit;
1294 	PK11_Functions.C_SignRecover = C_SignRecover;
1295 	PK11_Functions.C_VerifyInit = C_VerifyInit;
1296 	PK11_Functions.C_Verify = C_Verify;
1297 	PK11_Functions.C_VerifyUpdate = C_VerifyUpdate;
1298 	PK11_Functions.C_VerifyFinal = C_VerifyFinal;
1299 	PK11_Functions.C_VerifyRecoverInit = C_VerifyRecoverInit;
1300 	PK11_Functions.C_VerifyRecover = C_VerifyRecover;
1301 	PK11_Functions.C_DigestEncryptUpdate = C_DigestEncryptUpdate;
1302 	PK11_Functions.C_DecryptDigestUpdate = C_DecryptDigestUpdate;
1303 	PK11_Functions.C_SignEncryptUpdate = C_SignEncryptUpdate;
1304 	PK11_Functions.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate;
1305 	PK11_Functions.C_GenerateKey = C_GenerateKey;
1306 	PK11_Functions.C_GenerateKeyPair = C_GenerateKeyPair;
1307 	PK11_Functions.C_WrapKey = C_WrapKey;
1308 	PK11_Functions.C_UnwrapKey = C_UnwrapKey;
1309 	PK11_Functions.C_DeriveKey = C_DeriveKey;
1310 	PK11_Functions.C_SeedRandom = C_SeedRandom;
1311 	PK11_Functions.C_GenerateRandom = C_GenerateRandom;
1312 	PK11_Functions.C_GetFunctionStatus = C_GetFunctionStatus;
1313 	PK11_Functions.C_CancelFunction = C_CancelFunction;
1314 	PK11_Functions.C_WaitForSlotEvent = C_WaitForSlotEvent;
1315 	if (ppFunctionList) {
1316 		(*ppFunctionList) = &PK11_Functions;
1317 		return (CKR_OK);
1318 	} else {
1319 		return (CKR_ARGUMENTS_BAD);
1320 	}
1321 }
1322 
1323 /*ARGSUSED*/
1324 CK_RV
1325 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
1326 {
1327 	if (API_Initialized() == FALSE) {
1328 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1329 	}
1330 	return (CKR_FUNCTION_NOT_PARALLEL); // PER Specification PG 170
1331 }
1332 
1333 CK_RV
1334 C_GetInfo(CK_INFO_PTR pInfo)
1335 {
1336 	TOKEN_DATA td;
1337 	TSS_HCONTEXT hContext;
1338 
1339 	if (! API_Initialized()) {
1340 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1341 	}
1342 	if (! pInfo) {
1343 		return (CKR_FUNCTION_FAILED);
1344 	}
1345 	(void) memset(pInfo, 0, sizeof (*pInfo));
1346 	pInfo->cryptokiVersion.major = 2;
1347 	pInfo->cryptokiVersion.minor = 20;
1348 
1349 	if (open_tss_context(&hContext))
1350 		return (CKR_FUNCTION_FAILED);
1351 
1352 	(void) token_get_tpm_info(hContext, &td);
1353 
1354 	(void) Tspi_Context_Close(hContext);
1355 
1356 	(void) memcpy(pInfo->manufacturerID, &(td.token_info.manufacturerID),
1357 	    sizeof (pInfo->manufacturerID) - 1);
1358 
1359 	pInfo->flags = td.token_info.flags;
1360 	(void) strcpy((char *)pInfo->libraryDescription,
1361 	    "PKCS11 Interface for TPM");
1362 
1363 	pInfo->libraryVersion.major = 1;
1364 	pInfo->libraryVersion.minor = 0;
1365 
1366 	return (CKR_OK);
1367 }
1368 
1369 CK_RV
1370 C_GetMechanismInfo(CK_SLOT_ID	slotID,
1371 	CK_MECHANISM_TYPE	type,
1372 	CK_MECHANISM_INFO_PTR	pInfo)
1373 {
1374 	CK_RV rv;
1375 	if (API_Initialized() == FALSE) {
1376 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1377 	}
1378 	if (slotID > NUMBER_SLOTS_MANAGED) {
1379 		return (CKR_SLOT_ID_INVALID);
1380 	}
1381 	if (FuncList.ST_GetMechanismInfo) {
1382 		rv = FuncList.ST_GetMechanismInfo(slotID, type, pInfo);
1383 	} else {
1384 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1385 	}
1386 	return (rv);
1387 }
1388 
1389 CK_RV
1390 C_GetMechanismList(CK_SLOT_ID slotID,
1391 	CK_MECHANISM_TYPE_PTR pMechanismList,
1392 	CK_ULONG_PTR pulCount)
1393 {
1394 	CK_RV rv;
1395 
1396 	if (API_Initialized() == FALSE) {
1397 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1398 	}
1399 	if (! pulCount)
1400 		return (CKR_ARGUMENTS_BAD);
1401 
1402 	if (slotID > NUMBER_SLOTS_MANAGED)
1403 		return (CKR_SLOT_ID_INVALID);
1404 
1405 	if (FuncList.ST_GetMechanismList) {
1406 		rv = FuncList.ST_GetMechanismList(slotID,
1407 		    pMechanismList, pulCount);
1408 	} else {
1409 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1410 	}
1411 	if (rv == CKR_OK) {
1412 		if (pMechanismList) {
1413 			unsigned long i;
1414 			for (i = 0; i < *pulCount; i++) {
1415 				logit(LOG_DEBUG, "Mechanism[%d] 0x%08X ",
1416 				    i, pMechanismList[i]);
1417 			}
1418 		}
1419 	}
1420 	return (rv);
1421 }
1422 
1423 CK_RV
1424 C_GetObjectSize(CK_SESSION_HANDLE hSession,
1425 	CK_OBJECT_HANDLE hObject,
1426 	CK_ULONG_PTR pulSize)
1427 {
1428 	CK_RV rv;
1429 	ST_SESSION_T rSession;
1430 
1431 	if (API_Initialized() == FALSE) {
1432 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1433 	}
1434 	if (! pulSize) {
1435 		return (CKR_ARGUMENTS_BAD);
1436 	}
1437 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1438 		return (CKR_SESSION_HANDLE_INVALID);
1439 	}
1440 	if (FuncList.ST_GetObjectSize) {
1441 		rv = FuncList.ST_GetObjectSize(rSession, hObject, pulSize);
1442 	} else {
1443 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1444 	}
1445 	return (rv);
1446 }
1447 
1448 CK_RV
1449 C_GetOperationState(CK_SESSION_HANDLE hSession,
1450 	CK_BYTE_PTR pOperationState,
1451 	CK_ULONG_PTR pulOperationStateLen)
1452 {
1453 	CK_RV rv;
1454 	ST_SESSION_T rSession;
1455 
1456 	if (API_Initialized() == FALSE) {
1457 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1458 	}
1459 	if (! pulOperationStateLen) {
1460 		return (CKR_ARGUMENTS_BAD);
1461 	}
1462 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1463 		return (CKR_SESSION_HANDLE_INVALID);
1464 	}
1465 	if (FuncList.ST_GetOperationState) {
1466 		rv = FuncList.ST_GetOperationState(rSession,
1467 		    pOperationState, pulOperationStateLen);
1468 	} else {
1469 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1470 	}
1471 	return (rv);
1472 }
1473 
1474 CK_RV
1475 C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1476 	CK_SESSION_INFO_PTR pInfo)
1477 {
1478 	CK_RV rv;
1479 	ST_SESSION_T rSession;
1480 
1481 	if (API_Initialized() == FALSE) {
1482 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1483 	}
1484 	if (! pInfo) {
1485 		return (CKR_ARGUMENTS_BAD);
1486 	}
1487 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1488 		return (CKR_SESSION_HANDLE_INVALID);
1489 	}
1490 	if (FuncList.ST_GetSessionInfo) {
1491 		rv = FuncList.ST_GetSessionInfo(rSession, pInfo);
1492 	} else {
1493 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1494 	}
1495 	return (rv);
1496 }
1497 
1498 CK_RV
1499 C_GetSlotInfo(CK_SLOT_ID slotID,
1500 	CK_SLOT_INFO_PTR pInfo)
1501 {
1502 	if (API_Initialized() == FALSE) {
1503 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1504 	}
1505 	if (!pInfo) {
1506 		return (CKR_FUNCTION_FAILED);
1507 	}
1508 	if (slotID != TPM_SLOTID)
1509 		return (CKR_SLOT_ID_INVALID);
1510 
1511 	copy_slot_info(slotID, pInfo);
1512 	return (CKR_OK);
1513 }
1514 
1515 /*ARGSUSED*/
1516 CK_RV
1517 C_GetSlotList(CK_BBOOL tokenPresent,
1518 	CK_SLOT_ID_PTR pSlotList,
1519 	CK_ULONG_PTR pulCount)
1520 {
1521 	CK_ULONG count;
1522 	CK_SLOT_INFO slotInfo;
1523 
1524 	if (API_Initialized() == FALSE)
1525 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1526 
1527 	if (pulCount == NULL)
1528 		return (CKR_FUNCTION_FAILED);
1529 
1530 	count = 0;
1531 
1532 	copy_slot_info(TPM_SLOTID, &slotInfo);
1533 	if ((slotInfo.flags & CKF_TOKEN_PRESENT))
1534 		count++;
1535 
1536 	*pulCount = count;
1537 
1538 	if (pSlotList == NULL) {
1539 		return (CKR_OK);
1540 	} else {
1541 		if (*pulCount < count)
1542 			return (CKR_BUFFER_TOO_SMALL);
1543 		pSlotList[0] = TPM_SLOTID;
1544 	}
1545 	return (CKR_OK);
1546 }
1547 
1548 CK_RV
1549 C_GetTokenInfo(CK_SLOT_ID slotID,
1550 	CK_TOKEN_INFO_PTR pInfo)
1551 {
1552 	CK_RV rv;
1553 
1554 	if (API_Initialized() == FALSE) {
1555 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1556 	}
1557 	if (! pInfo) {
1558 		return (CKR_ARGUMENTS_BAD);
1559 	}
1560 	if (slotID > NUMBER_SLOTS_MANAGED) {
1561 		return (CKR_SLOT_ID_INVALID);
1562 	}
1563 	slotID = TPM_SLOTID;
1564 	if (FuncList.ST_GetTokenInfo) {
1565 		rv = FuncList.ST_GetTokenInfo(slotID, pInfo);
1566 	} else {
1567 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1568 	}
1569 	return (rv);
1570 }
1571 
1572 CK_RV
1573 C_Initialize(CK_VOID_PTR pVoid)
1574 {
1575 	CK_RV rv = CKR_OK;
1576 	CK_C_INITIALIZE_ARGS *pArg;
1577 	extern CK_RV ST_Initialize(void *,
1578 	    CK_SLOT_ID, unsigned char *);
1579 
1580 	(void) pthread_mutex_lock(&global_mutex);
1581 	if (! Anchor) {
1582 		Anchor = (API_Proc_Struct_t *)malloc(
1583 		    sizeof (API_Proc_Struct_t));
1584 		if (Anchor == NULL) {
1585 			(void) pthread_mutex_unlock(&global_mutex);
1586 			return (CKR_HOST_MEMORY);
1587 		}
1588 	} else {
1589 		(void) pthread_mutex_unlock(&global_mutex);
1590 		return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
1591 	}
1592 	/*
1593 	 * if pVoid is NULL, then everything is OK.  The applicaiton
1594 	 * will not be doing multi thread accesses.  We can use the OS
1595 	 * locks anyhow.
1596 	 */
1597 	if (pVoid != NULL) {
1598 		int supplied_ok;
1599 		pArg = (CK_C_INITIALIZE_ARGS *)pVoid;
1600 
1601 		/*
1602 		 * ALL supplied function pointers need to have the value
1603 		 * either NULL or no - NULL.
1604 		 */
1605 		supplied_ok = (pArg->CreateMutex == NULL &&
1606 		    pArg->DestroyMutex == NULL &&
1607 		    pArg->LockMutex == NULL &&
1608 		    pArg->UnlockMutex == NULL) ||
1609 		    (pArg->CreateMutex != NULL &&
1610 		    pArg->DestroyMutex != NULL &&
1611 		    pArg->LockMutex != NULL &&
1612 		    pArg->UnlockMutex != NULL);
1613 
1614 		if (!supplied_ok) {
1615 			(void) pthread_mutex_unlock(&global_mutex);
1616 			return (CKR_ARGUMENTS_BAD);
1617 		}
1618 		/* Check for a pReserved set */
1619 		if (pArg->pReserved != NULL) {
1620 			free(Anchor);
1621 			Anchor = NULL;
1622 			(void) pthread_mutex_unlock(&global_mutex);
1623 			return (CKR_ARGUMENTS_BAD);
1624 		}
1625 		/*
1626 		 * When the CKF_OS_LOCKING_OK flag isn't set and mutex
1627 		 * function pointers are supplied by an application,
1628 		 * return (an error.  We must be able to use our own primitives.
1629 		 */
1630 		if (!(pArg->flags & CKF_OS_LOCKING_OK) &&
1631 		    (pArg->CreateMutex != NULL)) {
1632 			(void) pthread_mutex_unlock(&global_mutex);
1633 			return (CKR_CANT_LOCK);
1634 		}
1635 	}
1636 	(void) memset((char *)Anchor, 0, sizeof (API_Proc_Struct_t));
1637 	(void) pthread_mutex_init(&(Anchor->ProcMutex), NULL);
1638 	(void) pthread_mutex_init(&(Anchor->SessListMutex), NULL);
1639 	Anchor->Pid = getpid();
1640 
1641 	rv = ST_Initialize((void *)&FuncList, 0, NULL);
1642 	(void) pthread_mutex_unlock(&global_mutex);
1643 	return (rv);
1644 }
1645 
1646 CK_RV
1647 C_InitPIN(CK_SESSION_HANDLE hSession,
1648 	CK_CHAR_PTR pPin,
1649 	CK_ULONG ulPinLen)
1650 {
1651 	CK_RV rv;
1652 	ST_SESSION_T rSession;
1653 
1654 	if (API_Initialized() == FALSE) {
1655 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1656 	}
1657 	if (! pPin && ulPinLen) {
1658 		return (CKR_ARGUMENTS_BAD);
1659 	}
1660 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1661 		return (CKR_SESSION_HANDLE_INVALID);
1662 	}
1663 
1664 	if (rSession.slotID > NUMBER_SLOTS_MANAGED) {
1665 		return (CKR_SLOT_ID_INVALID);
1666 	}
1667 	if (FuncList.ST_InitPIN) {
1668 		rv = FuncList.ST_InitPIN(rSession, pPin, ulPinLen);
1669 	} else {
1670 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1671 	}
1672 	return (rv);
1673 }
1674 
1675 CK_RV
1676 C_InitToken(CK_SLOT_ID  slotID,
1677 	CK_CHAR_PTR pPin,
1678 	CK_ULONG    ulPinLen,
1679 	CK_CHAR_PTR pLabel)
1680 {
1681 	CK_RV rv;
1682 
1683 	if (API_Initialized() == FALSE) {
1684 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1685 	}
1686 	if (! pPin && ulPinLen) {
1687 		return (CKR_ARGUMENTS_BAD);
1688 	}
1689 	if (! pLabel) {
1690 		return (CKR_ARGUMENTS_BAD);
1691 	}
1692 	if (FuncList.ST_InitToken) {
1693 		rv = FuncList.ST_InitToken(slotID, pPin, ulPinLen, pLabel);
1694 	} else {
1695 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1696 	}
1697 	return (rv);
1698 }
1699 
1700 CK_RV
1701 C_Login(CK_SESSION_HANDLE hSession,
1702 	CK_USER_TYPE userType,
1703 	CK_CHAR_PTR pPin,
1704 	CK_ULONG ulPinLen)
1705 {
1706 	CK_RV rv;
1707 	ST_SESSION_T rSession;
1708 
1709 	if (API_Initialized() == FALSE) {
1710 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1711 	}
1712 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1713 		return (CKR_SESSION_HANDLE_INVALID);
1714 	}
1715 	if (FuncList.ST_Login) {
1716 		rv = FuncList.ST_Login(rSession, userType, pPin, ulPinLen);
1717 	} else {
1718 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1719 	}
1720 	return (rv);
1721 }
1722 
1723 CK_RV
1724 C_Logout(CK_SESSION_HANDLE hSession)
1725 {
1726 	CK_RV rv;
1727 	ST_SESSION_T rSession;
1728 
1729 	if (API_Initialized() == FALSE) {
1730 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1731 	}
1732 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1733 		return (CKR_SESSION_HANDLE_INVALID);
1734 	}
1735 	if (FuncList.ST_Logout) {
1736 		rv = FuncList.ST_Logout(rSession);
1737 	} else {
1738 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1739 	}
1740 	return (rv);
1741 }
1742 
1743 /*ARGSUSED*/
1744 CK_RV
1745 C_OpenSession(
1746 	CK_SLOT_ID slotID,
1747 	CK_FLAGS flags,
1748 	CK_VOID_PTR pApplication,
1749 	CK_NOTIFY Notify,
1750 	CK_SESSION_HANDLE_PTR phSession)
1751 {
1752 	CK_RV rv;
1753 	Session_Struct_t  *apiSessp;
1754 
1755 	if (API_Initialized() == FALSE) {
1756 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1757 	}
1758 	if (slotID > NUMBER_SLOTS_MANAGED) {
1759 		return (CKR_SLOT_ID_INVALID);
1760 	}
1761 	if (! phSession) {
1762 		return (CKR_FUNCTION_FAILED);
1763 	}
1764 	if ((flags & CKF_SERIAL_SESSION) == 0) {
1765 		return (CKR_SESSION_PARALLEL_NOT_SUPPORTED);
1766 	}
1767 	if ((apiSessp = (Session_Struct_t *)malloc(
1768 	    sizeof (Session_Struct_t))) == NULL) {
1769 		return (CKR_HOST_MEMORY);
1770 	}
1771 	if (FuncList.ST_OpenSession) {
1772 		rv = FuncList.ST_OpenSession(slotID, flags,
1773 		    &(apiSessp->RealHandle));
1774 
1775 		if (rv == CKR_OK) {
1776 			*phSession = (CK_SESSION_HANDLE)apiSessp;
1777 			apiSessp->SltId = slotID;
1778 
1779 			AddToSessionList(apiSessp);
1780 		} else {
1781 			free(apiSessp);
1782 		}
1783 	} else {
1784 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1785 	}
1786 	return (rv);
1787 }
1788 
1789 CK_RV
1790 C_SeedRandom(CK_SESSION_HANDLE hSession,
1791 	CK_BYTE_PTR pSeed,
1792 	CK_ULONG ulSeedLen)
1793 {
1794 	CK_RV rv;
1795 	ST_SESSION_T rSession;
1796 
1797 	if (API_Initialized() == FALSE) {
1798 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1799 	}
1800 	if (! pSeed && ulSeedLen) {
1801 		return (CKR_ARGUMENTS_BAD);
1802 	}
1803 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1804 		return (CKR_SESSION_HANDLE_INVALID);
1805 	}
1806 	if (FuncList.ST_SeedRandom) {
1807 		rv = FuncList.ST_SeedRandom(rSession, pSeed, ulSeedLen);
1808 	} else {
1809 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1810 	}
1811 	return (rv);
1812 }
1813 
1814 CK_RV
1815 C_SetAttributeValue(CK_SESSION_HANDLE hSession,
1816 	CK_OBJECT_HANDLE hObject,
1817 	CK_ATTRIBUTE_PTR pTemplate,
1818 	CK_ULONG ulCount)
1819 {
1820 	CK_RV rv;
1821 	ST_SESSION_T rSession;
1822 
1823 	if (API_Initialized() == FALSE) {
1824 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1825 	}
1826 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1827 		return (CKR_SESSION_HANDLE_INVALID);
1828 	}
1829 	if (! pTemplate) {
1830 		return (CKR_TEMPLATE_INCOMPLETE);
1831 	}
1832 	if (! ulCount) {
1833 		return (CKR_TEMPLATE_INCOMPLETE);
1834 	}
1835 	// Get local pointers to session
1836 	if (FuncList.ST_SetAttributeValue) {
1837 		rv = FuncList.ST_SetAttributeValue(rSession, hObject,
1838 		    pTemplate, ulCount);
1839 	} else {
1840 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1841 	}
1842 	return (rv);
1843 }
1844 
1845 CK_RV
1846 C_SetOperationState(CK_SESSION_HANDLE hSession,
1847 	CK_BYTE_PTR pOperationState,
1848 	CK_ULONG ulOperationStateLen,
1849 	CK_OBJECT_HANDLE hEncryptionKey,
1850 	CK_OBJECT_HANDLE hAuthenticationKey)
1851 {
1852 	CK_RV rv;
1853 	ST_SESSION_T rSession;
1854 
1855 	if (API_Initialized() == FALSE) {
1856 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1857 	}
1858 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1859 		return (CKR_SESSION_HANDLE_INVALID);
1860 	}
1861 	if (! pOperationState || ulOperationStateLen == 0) {
1862 		return (CKR_ARGUMENTS_BAD);
1863 	}
1864 	if (FuncList.ST_SetOperationState) {
1865 		rv = FuncList.ST_SetOperationState(rSession, pOperationState,
1866 		    ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
1867 	} else {
1868 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1869 	}
1870 	return (rv);
1871 }
1872 
1873 CK_RV
1874 C_SetPIN(CK_SESSION_HANDLE hSession,
1875 	CK_CHAR_PTR pOldPin,
1876 	CK_ULONG ulOldLen,
1877 	CK_CHAR_PTR pNewPin,
1878 	CK_ULONG ulNewLen)
1879 {
1880 	CK_RV rv;
1881 	ST_SESSION_T rSession;
1882 
1883 	if (API_Initialized() == FALSE) {
1884 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1885 	}
1886 	if (! pOldPin || ! pNewPin)
1887 		return (CKR_PIN_INVALID);
1888 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1889 		return (CKR_SESSION_HANDLE_INVALID);
1890 	}
1891 	if (FuncList.ST_SetPIN) {
1892 		rv = FuncList.ST_SetPIN(rSession, pOldPin, ulOldLen,
1893 		    pNewPin, ulNewLen);
1894 	} else {
1895 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1896 	}
1897 	return (rv);
1898 }
1899 
1900 CK_RV
1901 C_Sign(CK_SESSION_HANDLE hSession,
1902 	CK_BYTE_PTR pData,
1903 	CK_ULONG ulDataLen,
1904 	CK_BYTE_PTR pSignature,
1905 	CK_ULONG_PTR pulSignatureLen)
1906 {
1907 	CK_RV rv;
1908 	ST_SESSION_T rSession;
1909 
1910 	if (API_Initialized() == FALSE) {
1911 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1912 	}
1913 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1914 		return (CKR_SESSION_HANDLE_INVALID);
1915 	}
1916 	if (FuncList.ST_Sign) {
1917 		rv = FuncList.ST_Sign(rSession, pData, ulDataLen,
1918 		    pSignature, pulSignatureLen);
1919 	} else {
1920 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1921 	}
1922 	return (rv);
1923 }
1924 
1925 CK_RV
1926 C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
1927 	CK_BYTE_PTR pPart,
1928 	CK_ULONG ulPartLen,
1929 	CK_BYTE_PTR pEncryptedPart,
1930 	CK_ULONG_PTR pulEncryptedPartLen)
1931 {
1932 	CK_RV rv;
1933 	ST_SESSION_T rSession;
1934 	if (API_Initialized() == FALSE) {
1935 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1936 	}
1937 	if (! pPart || ! pulEncryptedPartLen) {
1938 		return (CKR_ARGUMENTS_BAD);
1939 	}
1940 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1941 		return (CKR_SESSION_HANDLE_INVALID);
1942 	}
1943 	if (FuncList.ST_SignEncryptUpdate) {
1944 		rv = FuncList.ST_SignEncryptUpdate(rSession, pPart,
1945 		    ulPartLen, pEncryptedPart, pulEncryptedPartLen);
1946 	} else {
1947 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1948 	}
1949 	return (rv);
1950 }
1951 
1952 CK_RV
1953 C_SignFinal(CK_SESSION_HANDLE hSession,
1954 	CK_BYTE_PTR pSignature,
1955 	CK_ULONG_PTR pulSignatureLen)
1956 {
1957 	CK_RV rv;
1958 	ST_SESSION_T rSession;
1959 
1960 	if (API_Initialized() == FALSE) {
1961 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1962 	}
1963 	if (! pulSignatureLen) {
1964 		return (CKR_ARGUMENTS_BAD);
1965 	}
1966 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1967 		return (CKR_SESSION_HANDLE_INVALID);
1968 	}
1969 	if (FuncList.ST_SignFinal) {
1970 		rv = FuncList.ST_SignFinal(rSession, pSignature,
1971 		    pulSignatureLen);
1972 	} else {
1973 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1974 	}
1975 	return (rv);
1976 }
1977 
1978 CK_RV
1979 C_SignInit(CK_SESSION_HANDLE hSession,
1980 	CK_MECHANISM_PTR pMechanism,
1981 	CK_OBJECT_HANDLE hKey)
1982 {
1983 	CK_RV rv;
1984 	ST_SESSION_T rSession;
1985 
1986 	if (API_Initialized() == FALSE) {
1987 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
1988 	}
1989 	if (! pMechanism) {
1990 		return (CKR_MECHANISM_INVALID);
1991 	}
1992 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1993 		return (CKR_SESSION_HANDLE_INVALID);
1994 	}
1995 	if (FuncList.ST_SignInit) {
1996 		rv = FuncList.ST_SignInit(rSession, pMechanism, hKey);
1997 	} else {
1998 		rv = CKR_FUNCTION_NOT_SUPPORTED;
1999 	}
2000 	return (rv);
2001 }
2002 
2003 CK_RV
2004 C_SignRecover(CK_SESSION_HANDLE hSession,
2005 	CK_BYTE_PTR pData,
2006 	CK_ULONG ulDataLen,
2007 	CK_BYTE_PTR pSignature,
2008 	CK_ULONG_PTR pulSignatureLen)
2009 {
2010 	CK_RV rv;
2011 	ST_SESSION_T rSession;
2012 
2013 	if (API_Initialized() == FALSE) {
2014 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2015 	}
2016 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2017 		return (CKR_SESSION_HANDLE_INVALID);
2018 	}
2019 	if (FuncList.ST_SignRecover) {
2020 		rv = FuncList.ST_SignRecover(rSession, pData,
2021 		    ulDataLen, pSignature, pulSignatureLen);
2022 	} else {
2023 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2024 	}
2025 	return (rv);
2026 }
2027 
2028 CK_RV
2029 C_SignRecoverInit(CK_SESSION_HANDLE hSession,
2030 	CK_MECHANISM_PTR pMechanism,
2031 	CK_OBJECT_HANDLE hKey)
2032 {
2033 	CK_RV rv;
2034 	ST_SESSION_T rSession;
2035 
2036 	if (API_Initialized() == FALSE) {
2037 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2038 	}
2039 	if (! pMechanism) {
2040 		return (CKR_MECHANISM_INVALID);
2041 	}
2042 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2043 		return (CKR_SESSION_HANDLE_INVALID);
2044 	}
2045 	if (FuncList.ST_SignRecoverInit) {
2046 		rv = FuncList.ST_SignRecoverInit(rSession, pMechanism, hKey);
2047 	} else {
2048 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2049 	}
2050 	return (rv);
2051 }
2052 
2053 CK_RV
2054 C_SignUpdate(CK_SESSION_HANDLE hSession,
2055 	CK_BYTE_PTR pPart,
2056 	CK_ULONG ulPartLen)
2057 {
2058 	CK_RV rv;
2059 	ST_SESSION_T rSession;
2060 
2061 	if (API_Initialized() == FALSE) {
2062 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2063 	}
2064 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2065 		return (CKR_SESSION_HANDLE_INVALID);
2066 	}
2067 	if (FuncList.ST_SignUpdate) {
2068 		rv = FuncList.ST_SignUpdate(rSession, pPart, ulPartLen);
2069 	} else {
2070 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2071 	}
2072 	return (rv);
2073 }
2074 
2075 CK_RV
2076 C_UnwrapKey(CK_SESSION_HANDLE hSession,
2077 	CK_MECHANISM_PTR pMechanism,
2078 	CK_OBJECT_HANDLE hUnwrappingKey,
2079 	CK_BYTE_PTR pWrappedKey,
2080 	CK_ULONG ulWrappedKeyLen,
2081 	CK_ATTRIBUTE_PTR pTemplate,
2082 	CK_ULONG ulAttributeCount,
2083 	CK_OBJECT_HANDLE_PTR phKey)
2084 {
2085 	CK_RV rv;
2086 	ST_SESSION_T rSession;
2087 
2088 	if (API_Initialized() == FALSE) {
2089 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2090 	}
2091 	if (!pMechanism) {
2092 		return (CKR_MECHANISM_INVALID);
2093 	}
2094 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2095 		return (CKR_SESSION_HANDLE_INVALID);
2096 	}
2097 	if (FuncList.ST_UnwrapKey) {
2098 		rv = FuncList.ST_UnwrapKey(rSession, pMechanism,
2099 		    hUnwrappingKey, pWrappedKey, ulWrappedKeyLen,
2100 		    pTemplate, ulAttributeCount, phKey);
2101 	} else {
2102 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2103 	}
2104 	return (rv);
2105 }
2106 
2107 CK_RV
2108 C_Verify(CK_SESSION_HANDLE hSession,
2109 	CK_BYTE_PTR pData,
2110 	CK_ULONG ulDataLen,
2111 	CK_BYTE_PTR pSignature,
2112 	CK_ULONG ulSignatureLen)
2113 {
2114 	CK_RV rv;
2115 	ST_SESSION_T rSession;
2116 
2117 	if (API_Initialized() == FALSE) {
2118 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2119 	}
2120 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2121 		return (CKR_SESSION_HANDLE_INVALID);
2122 	}
2123 	if (FuncList.ST_Verify) {
2124 		rv = FuncList.ST_Verify(rSession, pData, ulDataLen,
2125 		    pSignature, ulSignatureLen);
2126 	} else {
2127 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2128 	}
2129 	return (rv);
2130 }
2131 
2132 CK_RV
2133 C_VerifyFinal(CK_SESSION_HANDLE hSession,
2134 	CK_BYTE_PTR pSignature,
2135 	CK_ULONG ulSignatureLen)
2136 {
2137 	CK_RV rv;
2138 	ST_SESSION_T rSession;
2139 
2140 	if (API_Initialized() == FALSE) {
2141 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2142 	}
2143 	if (! pSignature) {
2144 		return (CKR_ARGUMENTS_BAD);
2145 	}
2146 
2147 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2148 		return (CKR_SESSION_HANDLE_INVALID);
2149 	}
2150 	if (FuncList.ST_VerifyFinal) {
2151 		rv = FuncList.ST_VerifyFinal(rSession, pSignature,
2152 		    ulSignatureLen);
2153 	} else {
2154 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2155 	}
2156 	return (rv);
2157 }
2158 
2159 CK_RV
2160 C_VerifyInit(CK_SESSION_HANDLE hSession,
2161 	CK_MECHANISM_PTR pMechanism,
2162 	CK_OBJECT_HANDLE hKey)
2163 {
2164 	CK_RV rv;
2165 	ST_SESSION_T rSession;
2166 
2167 	if (API_Initialized() == FALSE) {
2168 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2169 	}
2170 	if (! pMechanism) {
2171 		return (CKR_MECHANISM_INVALID);
2172 	}
2173 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2174 		return (CKR_SESSION_HANDLE_INVALID);
2175 	}
2176 
2177 	if (FuncList.ST_VerifyInit) {
2178 		rv = FuncList.ST_VerifyInit(rSession, pMechanism, hKey);
2179 	} else {
2180 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2181 	}
2182 	return (rv);
2183 }
2184 
2185 CK_RV
2186 C_VerifyRecover(CK_SESSION_HANDLE hSession,
2187 	CK_BYTE_PTR pSignature,
2188 	CK_ULONG ulSignatureLen,
2189 	CK_BYTE_PTR pData,
2190 	CK_ULONG_PTR pulDataLen)
2191 {
2192 	CK_RV rv;
2193 	ST_SESSION_T rSession;
2194 
2195 	if (API_Initialized() == FALSE) {
2196 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2197 	}
2198 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2199 		return (CKR_SESSION_HANDLE_INVALID);
2200 	}
2201 	if (FuncList.ST_VerifyRecover) {
2202 		rv = FuncList.ST_VerifyRecover(rSession, pSignature,
2203 		    ulSignatureLen, pData, pulDataLen);
2204 	} else {
2205 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2206 	}
2207 	return (rv);
2208 }
2209 
2210 CK_RV
2211 C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
2212 	CK_MECHANISM_PTR pMechanism,
2213 	CK_OBJECT_HANDLE hKey)
2214 {
2215 	CK_RV rv;
2216 	ST_SESSION_T rSession;
2217 
2218 	if (API_Initialized() == FALSE) {
2219 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2220 	}
2221 	if (! pMechanism) {
2222 		return (CKR_MECHANISM_INVALID);
2223 	}
2224 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2225 		return (CKR_SESSION_HANDLE_INVALID);
2226 	}
2227 	if (FuncList.ST_VerifyRecoverInit) {
2228 		rv = FuncList.ST_VerifyRecoverInit(rSession, pMechanism, hKey);
2229 	} else {
2230 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2231 	}
2232 	return (rv);
2233 }
2234 
2235 CK_RV
2236 C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2237 	CK_BYTE_PTR pPart,
2238 	CK_ULONG ulPartLen)
2239 {
2240 	CK_RV rv;
2241 	ST_SESSION_T rSession;
2242 
2243 	if (API_Initialized() == FALSE) {
2244 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2245 	}
2246 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2247 		return (CKR_SESSION_HANDLE_INVALID);
2248 	}
2249 	if (FuncList.ST_VerifyUpdate) {
2250 		rv = FuncList.ST_VerifyUpdate(rSession, pPart, ulPartLen);
2251 	} else {
2252 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2253 	}
2254 	return (rv);
2255 }
2256 
2257 /*ARGSUSED*/
2258 CK_RV
2259 C_WaitForSlotEvent(CK_FLAGS flags,
2260 	CK_SLOT_ID_PTR pSlot,
2261 	CK_VOID_PTR pReserved)
2262 {
2263 	if (API_Initialized() == FALSE) {
2264 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2265 	}
2266 	return (CKR_FUNCTION_NOT_SUPPORTED);
2267 }
2268 
2269 CK_RV
2270 C_WrapKey(CK_SESSION_HANDLE hSession,
2271 	CK_MECHANISM_PTR pMechanism,
2272 	CK_OBJECT_HANDLE hWrappingKey,
2273 	CK_OBJECT_HANDLE hKey,
2274 	CK_BYTE_PTR pWrappedKey,
2275 	CK_ULONG_PTR pulWrappedKeyLen)
2276 {
2277 	CK_RV rv;
2278 	ST_SESSION_T rSession;
2279 
2280 	if (API_Initialized() == FALSE) {
2281 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
2282 	}
2283 	if (! pMechanism) {
2284 		return (CKR_MECHANISM_INVALID);
2285 	}
2286 	if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2287 		return (CKR_SESSION_HANDLE_INVALID);
2288 	}
2289 	if (FuncList.ST_WrapKey) {
2290 		rv = FuncList.ST_WrapKey(rSession, pMechanism, hWrappingKey,
2291 		    hKey, pWrappedKey, pulWrappedKeyLen);
2292 	} else {
2293 		rv = CKR_FUNCTION_NOT_SUPPORTED;
2294 	}
2295 	return (rv);
2296 }
2297 
2298 #pragma init(api_init)
2299 #pragma fini(api_fini)
2300 
2301 static void
2302 api_init(void)
2303 {
2304 	loginit();
2305 	if (! Initialized) {
2306 		(void) pthread_atfork(tpmtoken_fork_prepare,
2307 		    tpmtoken_fork_parent, tpmtoken_fork_child);
2308 		Initialized = 1;
2309 	}
2310 }
2311 
2312 static void
2313 api_fini()
2314 {
2315 	logterm();
2316 	if (API_Initialized() == TRUE) {
2317 		(void) do_finalize(NULL);
2318 	}
2319 }
2320