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