Imported Upstream version 3.13.6
[platform/upstream/nss.git] / mozilla / security / nss / lib / ckfw / wrap.c
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is the Netscape security libraries.
15  *
16  * The Initial Developer of the Original Code is
17  * Netscape Communications Corporation.
18  * Portions created by the Initial Developer are Copyright (C) 1994-2000
19  * the Initial Developer. All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */
36
37 #ifdef DEBUG
38 static const char CVS_ID[] = "@(#) $RCSfile: wrap.c,v $ $Revision: 1.20 $ $Date: 2010/04/03 18:27:29 $";
39 #endif /* DEBUG */
40
41 /*
42  * wrap.c
43  *
44  * This file contains the routines that actually implement the cryptoki
45  * API, using the internal APIs of the NSS Cryptoki Framework.  There is
46  * one routine here for every cryptoki routine.  For linking reasons
47  * the actual entry points passed back with C_GetFunctionList have to
48  * exist in one of the Module's source files; however, those are merely
49  * simple wrappers that call these routines.  The intelligence of the
50  * implementations is here.
51  */
52
53 #ifndef CK_T
54 #include "ck.h"
55 #endif /* CK_T */
56
57 /*
58  * NSSCKFWC_Initialize
59  * NSSCKFWC_Finalize
60  * NSSCKFWC_GetInfo
61  * -- NSSCKFWC_GetFunctionList -- see the API insert file
62  * NSSCKFWC_GetSlotList
63  * NSSCKFWC_GetSlotInfo
64  * NSSCKFWC_GetTokenInfo
65  * NSSCKFWC_WaitForSlotEvent
66  * NSSCKFWC_GetMechanismList
67  * NSSCKFWC_GetMechanismInfo
68  * NSSCKFWC_InitToken
69  * NSSCKFWC_InitPIN
70  * NSSCKFWC_SetPIN
71  * NSSCKFWC_OpenSession
72  * NSSCKFWC_CloseSession
73  * NSSCKFWC_CloseAllSessions
74  * NSSCKFWC_GetSessionInfo
75  * NSSCKFWC_GetOperationState
76  * NSSCKFWC_SetOperationState
77  * NSSCKFWC_Login
78  * NSSCKFWC_Logout
79  * NSSCKFWC_CreateObject
80  * NSSCKFWC_CopyObject
81  * NSSCKFWC_DestroyObject
82  * NSSCKFWC_GetObjectSize
83  * NSSCKFWC_GetAttributeValue
84  * NSSCKFWC_SetAttributeValue
85  * NSSCKFWC_FindObjectsInit
86  * NSSCKFWC_FindObjects
87  * NSSCKFWC_FindObjectsFinal
88  * NSSCKFWC_EncryptInit
89  * NSSCKFWC_Encrypt
90  * NSSCKFWC_EncryptUpdate
91  * NSSCKFWC_EncryptFinal
92  * NSSCKFWC_DecryptInit
93  * NSSCKFWC_Decrypt
94  * NSSCKFWC_DecryptUpdate
95  * NSSCKFWC_DecryptFinal
96  * NSSCKFWC_DigestInit
97  * NSSCKFWC_Digest
98  * NSSCKFWC_DigestUpdate
99  * NSSCKFWC_DigestKey
100  * NSSCKFWC_DigestFinal
101  * NSSCKFWC_SignInit
102  * NSSCKFWC_Sign
103  * NSSCKFWC_SignUpdate
104  * NSSCKFWC_SignFinal
105  * NSSCKFWC_SignRecoverInit
106  * NSSCKFWC_SignRecover
107  * NSSCKFWC_VerifyInit
108  * NSSCKFWC_Verify
109  * NSSCKFWC_VerifyUpdate
110  * NSSCKFWC_VerifyFinal
111  * NSSCKFWC_VerifyRecoverInit
112  * NSSCKFWC_VerifyRecover
113  * NSSCKFWC_DigestEncryptUpdate
114  * NSSCKFWC_DecryptDigestUpdate
115  * NSSCKFWC_SignEncryptUpdate
116  * NSSCKFWC_DecryptVerifyUpdate
117  * NSSCKFWC_GenerateKey
118  * NSSCKFWC_GenerateKeyPair
119  * NSSCKFWC_WrapKey
120  * NSSCKFWC_UnwrapKey
121  * NSSCKFWC_DeriveKey
122  * NSSCKFWC_SeedRandom
123  * NSSCKFWC_GenerateRandom
124  * NSSCKFWC_GetFunctionStatus
125  * NSSCKFWC_CancelFunction
126  */
127
128 /* figure out out locking semantics */
129 static CK_RV
130 nssCKFW_GetThreadSafeState(CK_C_INITIALIZE_ARGS_PTR pInitArgs,
131                            CryptokiLockingState *pLocking_state) {
132   int functionCount = 0;
133
134   /* parsed according to (PKCS #11 Section 11.4) */
135   /* no args, the degenerate version of case 1 */
136   if (!pInitArgs) {
137     *pLocking_state = SingleThreaded;
138     return CKR_OK;
139   } 
140
141   /* CKF_OS_LOCKING_OK set, Cases 2 and 4 */
142   if (pInitArgs->flags & CKF_OS_LOCKING_OK) {
143     *pLocking_state = MultiThreaded;
144     return CKR_OK;
145   }
146   if ((CK_CREATEMUTEX) NULL != pInitArgs->CreateMutex) functionCount++;
147   if ((CK_DESTROYMUTEX) NULL != pInitArgs->DestroyMutex) functionCount++;
148   if ((CK_LOCKMUTEX) NULL != pInitArgs->LockMutex) functionCount++;
149   if ((CK_UNLOCKMUTEX) NULL != pInitArgs->UnlockMutex) functionCount++;
150
151   /* CKF_OS_LOCKING_OK is not set, and not functions supplied, 
152    * explicit case 1 */
153   if (0 == functionCount) {
154     *pLocking_state = SingleThreaded;
155     return CKR_OK;
156   }
157
158   /* OS_LOCKING_OK is not set and functions have been supplied. Since
159    * ckfw uses nssbase library which explicitly calls NSPR, and since 
160    * there is no way to reliably override these explicit calls to NSPR,
161    * therefore we can't support applications which have their own threading 
162    * module.  Return CKR_CANT_LOCK if they supplied the correct number of 
163    * arguments, or CKR_ARGUMENTS_BAD if they did not in either case we will 
164    * fail the initialize */
165   return (4 == functionCount) ? CKR_CANT_LOCK : CKR_ARGUMENTS_BAD;
166 }
167
168 static PRInt32 liveInstances;
169
170 /*
171  * NSSCKFWC_Initialize
172  *
173  */
174 NSS_IMPLEMENT CK_RV
175 NSSCKFWC_Initialize
176 (
177   NSSCKFWInstance **pFwInstance,
178   NSSCKMDInstance *mdInstance,
179   CK_VOID_PTR pInitArgs
180 )
181 {
182   CK_RV error = CKR_OK;
183   CryptokiLockingState locking_state;
184
185   if( (NSSCKFWInstance **)NULL == pFwInstance ) {
186     error = CKR_GENERAL_ERROR;
187     goto loser;
188   }
189
190   if (*pFwInstance) {
191     error = CKR_CRYPTOKI_ALREADY_INITIALIZED;
192     goto loser;
193   }
194
195   if (!mdInstance) {
196     error = CKR_GENERAL_ERROR;
197     goto loser;
198   }
199
200   error = nssCKFW_GetThreadSafeState(pInitArgs,&locking_state);
201   if( CKR_OK != error ) {
202     goto loser;
203   }
204
205   *pFwInstance = nssCKFWInstance_Create(pInitArgs, locking_state, mdInstance, &error);
206   if (!*pFwInstance) {
207     goto loser;
208   }
209   PR_ATOMIC_INCREMENT(&liveInstances);
210   return CKR_OK;
211
212  loser:
213   switch( error ) {
214   case CKR_ARGUMENTS_BAD:
215   case CKR_CANT_LOCK:
216   case CKR_CRYPTOKI_ALREADY_INITIALIZED:
217   case CKR_FUNCTION_FAILED:
218   case CKR_GENERAL_ERROR:
219   case CKR_HOST_MEMORY:
220   case CKR_NEED_TO_CREATE_THREADS:
221     break;
222   default:
223   case CKR_OK:
224     error = CKR_GENERAL_ERROR;
225     break;
226   }
227
228   return error;
229 }
230
231 /*
232  * NSSCKFWC_Finalize
233  *
234  */
235 NSS_IMPLEMENT CK_RV
236 NSSCKFWC_Finalize
237 (
238   NSSCKFWInstance **pFwInstance
239 )
240 {
241   CK_RV error = CKR_OK;
242
243   if( (NSSCKFWInstance **)NULL == pFwInstance ) {
244     error = CKR_GENERAL_ERROR;
245     goto loser;
246   }
247
248   if (!*pFwInstance) {
249     error = CKR_CRYPTOKI_NOT_INITIALIZED;
250     goto loser;
251   }
252
253   error = nssCKFWInstance_Destroy(*pFwInstance);
254
255   /* In any case */
256   *pFwInstance = (NSSCKFWInstance *)NULL;
257
258  loser:
259   switch( error ) {
260   PRInt32 remainingInstances;
261   case CKR_OK:
262     remainingInstances = PR_ATOMIC_DECREMENT(&liveInstances);
263     if (!remainingInstances) {
264         nssArena_Shutdown();
265     }
266     break;
267   case CKR_CRYPTOKI_NOT_INITIALIZED:
268   case CKR_FUNCTION_FAILED:
269   case CKR_GENERAL_ERROR:
270   case CKR_HOST_MEMORY:
271     break;
272   default:
273     error = CKR_GENERAL_ERROR;
274     break;
275   }
276
277   /*
278    * A thread's error stack is automatically destroyed when the thread
279    * terminates or, for the primordial thread, by PR_Cleanup.  On
280    * Windows with MinGW, the thread private data destructor PR_Free
281    * registered by this module is actually a thunk for PR_Free defined
282    * in this module.  When the thread that unloads this module terminates
283    * or calls PR_Cleanup, the thunk for PR_Free is already gone with the
284    * module.  Therefore we need to destroy the error stack before the
285    * module is unloaded.
286    */
287   nss_DestroyErrorStack();
288   return error;
289 }
290
291 /*
292  * NSSCKFWC_GetInfo
293  *
294  */
295 NSS_IMPLEMENT CK_RV
296 NSSCKFWC_GetInfo
297 (
298   NSSCKFWInstance *fwInstance,
299   CK_INFO_PTR pInfo
300 )
301 {
302   CK_RV error = CKR_OK;
303
304   if( (CK_INFO_PTR)CK_NULL_PTR == pInfo ) {
305     error = CKR_ARGUMENTS_BAD;
306     goto loser;
307   }
308
309   /*
310    * A purify error here means a caller error
311    */
312   (void)nsslibc_memset(pInfo, 0, sizeof(CK_INFO));
313
314   pInfo->cryptokiVersion = nssCKFWInstance_GetCryptokiVersion(fwInstance);
315
316   error = nssCKFWInstance_GetManufacturerID(fwInstance, pInfo->manufacturerID);
317   if( CKR_OK != error ) {
318     goto loser;
319   }
320
321   pInfo->flags = nssCKFWInstance_GetFlags(fwInstance);
322
323   error = nssCKFWInstance_GetLibraryDescription(fwInstance, pInfo->libraryDescription);
324   if( CKR_OK != error ) {
325     goto loser;
326   }
327
328   pInfo->libraryVersion = nssCKFWInstance_GetLibraryVersion(fwInstance);
329
330   return CKR_OK;
331
332  loser:
333   switch( error ) {
334   case CKR_CRYPTOKI_NOT_INITIALIZED:
335   case CKR_FUNCTION_FAILED:
336   case CKR_GENERAL_ERROR:
337   case CKR_HOST_MEMORY:
338     break;
339   default:
340     error = CKR_GENERAL_ERROR;
341     break;
342   }
343
344   return error;
345 }
346   
347 /*
348  * C_GetFunctionList is implemented entirely in the Module's file which
349  * includes the Framework API insert file.  It requires no "actual"
350  * NSSCKFW routine.
351  */
352
353 /*
354  * NSSCKFWC_GetSlotList
355  *
356  */
357 NSS_IMPLEMENT CK_RV
358 NSSCKFWC_GetSlotList
359 (
360   NSSCKFWInstance *fwInstance,
361   CK_BBOOL tokenPresent,
362   CK_SLOT_ID_PTR pSlotList,
363   CK_ULONG_PTR pulCount
364 )
365 {
366   CK_RV error = CKR_OK;
367   CK_ULONG nSlots;
368
369   if (!fwInstance) {
370     error = CKR_CRYPTOKI_NOT_INITIALIZED;
371     goto loser;
372   }
373
374   switch( tokenPresent ) {
375   case CK_TRUE:
376   case CK_FALSE:
377     break;
378   default:
379     error = CKR_ARGUMENTS_BAD;
380     goto loser;
381   }
382
383   if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
384     error = CKR_ARGUMENTS_BAD;
385     goto loser;
386   }
387
388   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
389   if( (CK_ULONG)0 == nSlots ) {
390     goto loser;
391   }
392
393   if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlotList ) {
394     *pulCount = nSlots;
395     return CKR_OK;
396   } 
397     
398   /*
399    * A purify error here indicates caller error.
400    */
401   (void)nsslibc_memset(pSlotList, 0, *pulCount * sizeof(CK_SLOT_ID));
402
403   if( *pulCount < nSlots ) {
404     *pulCount = nSlots;
405     error = CKR_BUFFER_TOO_SMALL;
406     goto loser;
407   } else {
408     CK_ULONG i;
409     *pulCount = nSlots;
410     
411     /* 
412      * Our secret "mapping": CK_SLOT_IDs are integers [1,N], and we
413      * just index one when we need it.
414      */
415
416     for( i = 0; i < nSlots; i++ ) {
417       pSlotList[i] = i+1;
418     }
419
420     return CKR_OK;
421   }
422
423  loser:
424   switch( error ) {
425   case CKR_BUFFER_TOO_SMALL:
426   case CKR_CRYPTOKI_NOT_INITIALIZED:
427   case CKR_FUNCTION_FAILED:
428   case CKR_GENERAL_ERROR:
429   case CKR_HOST_MEMORY:
430     break;
431   default:
432   case CKR_OK:
433     error = CKR_GENERAL_ERROR;
434     break;
435   }
436
437   return error;
438 }
439  
440 /*
441  * NSSCKFWC_GetSlotInfo
442  *
443  */
444 NSS_IMPLEMENT CK_RV
445 NSSCKFWC_GetSlotInfo
446 (
447   NSSCKFWInstance *fwInstance,
448   CK_SLOT_ID slotID,
449   CK_SLOT_INFO_PTR pInfo
450 )
451 {
452   CK_RV error = CKR_OK;
453   CK_ULONG nSlots;
454   NSSCKFWSlot **slots;
455   NSSCKFWSlot *fwSlot;
456
457   if (!fwInstance) {
458     error = CKR_CRYPTOKI_NOT_INITIALIZED;
459     goto loser;
460   }
461
462   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
463   if( (CK_ULONG)0 == nSlots ) {
464     goto loser;
465   }
466
467   if( (slotID < 1) || (slotID > nSlots) ) {
468     error = CKR_SLOT_ID_INVALID;
469     goto loser;
470   }
471
472   if( (CK_SLOT_INFO_PTR)CK_NULL_PTR == pInfo ) {
473     error = CKR_ARGUMENTS_BAD;
474     goto loser;
475   }
476
477   /*
478    * A purify error here indicates caller error.
479    */
480   (void)nsslibc_memset(pInfo, 0, sizeof(CK_SLOT_INFO));
481
482   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
483   if( (NSSCKFWSlot **)NULL == slots ) {
484     goto loser;
485   }
486
487   fwSlot = slots[ slotID-1 ];
488
489   error = nssCKFWSlot_GetSlotDescription(fwSlot, pInfo->slotDescription);
490   if( CKR_OK != error ) {
491     goto loser;
492   }
493
494   error = nssCKFWSlot_GetManufacturerID(fwSlot, pInfo->manufacturerID);
495   if( CKR_OK != error ) {
496     goto loser;
497   }
498
499   if( nssCKFWSlot_GetTokenPresent(fwSlot) ) {
500     pInfo->flags |= CKF_TOKEN_PRESENT;
501   }
502
503   if( nssCKFWSlot_GetRemovableDevice(fwSlot) ) {
504     pInfo->flags |= CKF_REMOVABLE_DEVICE;
505   }
506
507   if( nssCKFWSlot_GetHardwareSlot(fwSlot) ) {
508     pInfo->flags |= CKF_HW_SLOT;
509   }
510
511   pInfo->hardwareVersion = nssCKFWSlot_GetHardwareVersion(fwSlot);
512   pInfo->firmwareVersion = nssCKFWSlot_GetFirmwareVersion(fwSlot);
513
514   return CKR_OK;
515
516  loser:
517   switch( error ) {
518   case CKR_CRYPTOKI_NOT_INITIALIZED:
519   case CKR_DEVICE_ERROR:
520   case CKR_FUNCTION_FAILED:
521   case CKR_GENERAL_ERROR:
522   case CKR_HOST_MEMORY:
523   case CKR_SLOT_ID_INVALID:
524     break;
525   default:
526   case CKR_OK:
527     error = CKR_GENERAL_ERROR;
528   }
529
530   return error;
531 }
532
533 /*
534  * NSSCKFWC_GetTokenInfo
535  *
536  */
537 NSS_IMPLEMENT CK_RV
538 NSSCKFWC_GetTokenInfo
539 (
540   NSSCKFWInstance *fwInstance,
541   CK_SLOT_ID slotID,
542   CK_TOKEN_INFO_PTR pInfo
543 )
544 {
545   CK_RV error = CKR_OK;
546   CK_ULONG nSlots;
547   NSSCKFWSlot **slots;
548   NSSCKFWSlot *fwSlot;
549   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
550
551   if (!fwInstance) {
552     error = CKR_CRYPTOKI_NOT_INITIALIZED;
553     goto loser;
554   }
555
556   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
557   if( (CK_ULONG)0 == nSlots ) {
558     goto loser;
559   }
560
561   if( (slotID < 1) || (slotID > nSlots) ) {
562     error = CKR_SLOT_ID_INVALID;
563     goto loser;
564   }
565
566   if( (CK_TOKEN_INFO_PTR)CK_NULL_PTR == pInfo ) {
567     error = CKR_ARGUMENTS_BAD;
568     goto loser;
569   }
570
571   /*
572    * A purify error here indicates caller error.
573    */
574   (void)nsslibc_memset(pInfo, 0, sizeof(CK_TOKEN_INFO));
575
576   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
577   if( (NSSCKFWSlot **)NULL == slots ) {
578     goto loser;
579   }
580
581   fwSlot = slots[ slotID-1 ];
582
583   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
584     error = CKR_TOKEN_NOT_PRESENT;
585     goto loser;
586   }
587
588   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
589   if (!fwToken) {
590     goto loser;
591   }
592
593   error = nssCKFWToken_GetLabel(fwToken, pInfo->label);
594   if( CKR_OK != error ) {
595     goto loser;
596   }
597
598   error = nssCKFWToken_GetManufacturerID(fwToken, pInfo->manufacturerID);
599   if( CKR_OK != error ) {
600     goto loser;
601   }
602
603   error = nssCKFWToken_GetModel(fwToken, pInfo->model);
604   if( CKR_OK != error ) {
605     goto loser;
606   }
607
608   error = nssCKFWToken_GetSerialNumber(fwToken, pInfo->serialNumber);
609   if( CKR_OK != error ) {
610     goto loser;
611   }
612
613   if( nssCKFWToken_GetHasRNG(fwToken) ) {
614     pInfo->flags |= CKF_RNG;
615   }
616
617   if( nssCKFWToken_GetIsWriteProtected(fwToken) ) {
618     pInfo->flags |= CKF_WRITE_PROTECTED;
619   }
620
621   if( nssCKFWToken_GetLoginRequired(fwToken) ) {
622     pInfo->flags |= CKF_LOGIN_REQUIRED;
623   }
624
625   if( nssCKFWToken_GetUserPinInitialized(fwToken) ) {
626     pInfo->flags |= CKF_USER_PIN_INITIALIZED;
627   }
628
629   if( nssCKFWToken_GetRestoreKeyNotNeeded(fwToken) ) {
630     pInfo->flags |= CKF_RESTORE_KEY_NOT_NEEDED;
631   }
632
633   if( nssCKFWToken_GetHasClockOnToken(fwToken) ) {
634     pInfo->flags |= CKF_CLOCK_ON_TOKEN;
635   }
636
637   if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
638     pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
639   }
640
641   if( nssCKFWToken_GetSupportsDualCryptoOperations(fwToken) ) {
642     pInfo->flags |= CKF_DUAL_CRYPTO_OPERATIONS;
643   }
644
645   pInfo->ulMaxSessionCount = nssCKFWToken_GetMaxSessionCount(fwToken);
646   pInfo->ulSessionCount = nssCKFWToken_GetSessionCount(fwToken);
647   pInfo->ulMaxRwSessionCount = nssCKFWToken_GetMaxRwSessionCount(fwToken);
648   pInfo->ulRwSessionCount= nssCKFWToken_GetRwSessionCount(fwToken);
649   pInfo->ulMaxPinLen = nssCKFWToken_GetMaxPinLen(fwToken);
650   pInfo->ulMinPinLen = nssCKFWToken_GetMinPinLen(fwToken);
651   pInfo->ulTotalPublicMemory = nssCKFWToken_GetTotalPublicMemory(fwToken);
652   pInfo->ulFreePublicMemory = nssCKFWToken_GetFreePublicMemory(fwToken);
653   pInfo->ulTotalPrivateMemory = nssCKFWToken_GetTotalPrivateMemory(fwToken);
654   pInfo->ulFreePrivateMemory = nssCKFWToken_GetFreePrivateMemory(fwToken);
655   pInfo->hardwareVersion = nssCKFWToken_GetHardwareVersion(fwToken);
656   pInfo->firmwareVersion = nssCKFWToken_GetFirmwareVersion(fwToken);
657   
658   error = nssCKFWToken_GetUTCTime(fwToken, pInfo->utcTime);
659   if( CKR_OK != error ) {
660     goto loser;
661   }
662
663   return CKR_OK;
664
665  loser:
666   switch( error ) {
667   case CKR_DEVICE_REMOVED:
668   case CKR_TOKEN_NOT_PRESENT:
669     if (fwToken)
670       nssCKFWToken_Destroy(fwToken);
671     break;
672   case CKR_CRYPTOKI_NOT_INITIALIZED:
673   case CKR_DEVICE_ERROR:
674   case CKR_DEVICE_MEMORY:
675   case CKR_FUNCTION_FAILED:
676   case CKR_GENERAL_ERROR:
677   case CKR_HOST_MEMORY:
678   case CKR_SLOT_ID_INVALID:
679   case CKR_TOKEN_NOT_RECOGNIZED:
680     break;
681   default:
682   case CKR_OK:
683     error = CKR_GENERAL_ERROR;
684     break;
685   }
686
687   return error;
688 }
689
690 /*
691  * NSSCKFWC_WaitForSlotEvent
692  *
693  */
694 NSS_IMPLEMENT CK_RV
695 NSSCKFWC_WaitForSlotEvent
696 (
697   NSSCKFWInstance *fwInstance,
698   CK_FLAGS flags,
699   CK_SLOT_ID_PTR pSlot,
700   CK_VOID_PTR pReserved
701 )
702 {
703   CK_RV error = CKR_OK;
704   CK_ULONG nSlots;
705   CK_BBOOL block;
706   NSSCKFWSlot **slots;
707   NSSCKFWSlot *fwSlot;
708   CK_ULONG i;
709
710   if (!fwInstance) {
711     error = CKR_CRYPTOKI_NOT_INITIALIZED;
712     goto loser;
713   }
714
715   if( flags & ~CKF_DONT_BLOCK ) {
716     error = CKR_ARGUMENTS_BAD;
717     goto loser;
718   }
719
720   block = (flags & CKF_DONT_BLOCK) ? CK_TRUE : CK_FALSE;
721
722   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
723   if( (CK_ULONG)0 == nSlots ) {
724     goto loser;
725   }
726
727   if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlot ) {
728     error = CKR_ARGUMENTS_BAD;
729     goto loser;
730   }
731
732   if( (CK_VOID_PTR)CK_NULL_PTR != pReserved ) {
733     error = CKR_ARGUMENTS_BAD;
734     goto loser;
735   }
736
737   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
738   if( (NSSCKFWSlot **)NULL == slots ) {
739     goto loser;
740   }
741
742   fwSlot = nssCKFWInstance_WaitForSlotEvent(fwInstance, block, &error);
743   if (!fwSlot) {
744     goto loser;
745   }
746
747   for( i = 0; i < nSlots; i++ ) {
748     if( fwSlot == slots[i] ) {
749       *pSlot = (CK_SLOT_ID)(CK_ULONG)(i+1);
750       return CKR_OK;
751     }
752   }
753
754   error = CKR_GENERAL_ERROR; /* returned something not in the slot list */
755
756  loser:
757   switch( error ) {
758   case CKR_CRYPTOKI_NOT_INITIALIZED:
759   case CKR_FUNCTION_FAILED:
760   case CKR_GENERAL_ERROR:
761   case CKR_HOST_MEMORY:
762   case CKR_NO_EVENT:
763     break;
764   default:
765   case CKR_OK:
766     error = CKR_GENERAL_ERROR;
767     break;
768   }
769
770   return error;
771 }
772
773 /*
774  * NSSCKFWC_GetMechanismList
775  *
776  */
777 NSS_IMPLEMENT CK_RV
778 NSSCKFWC_GetMechanismList
779 (
780   NSSCKFWInstance *fwInstance,
781   CK_SLOT_ID slotID,
782   CK_MECHANISM_TYPE_PTR pMechanismList,
783   CK_ULONG_PTR pulCount
784 )
785 {
786   CK_RV error = CKR_OK;
787   CK_ULONG nSlots;
788   NSSCKFWSlot **slots;
789   NSSCKFWSlot *fwSlot;
790   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
791   CK_ULONG count;
792
793   if (!fwInstance) {
794     error = CKR_CRYPTOKI_NOT_INITIALIZED;
795     goto loser;
796   }
797
798   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
799   if( (CK_ULONG)0 == nSlots ) {
800     goto loser;
801   }
802
803   if( (slotID < 1) || (slotID > nSlots) ) {
804     error = CKR_SLOT_ID_INVALID;
805     goto loser;
806   }
807
808   if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
809     error = CKR_ARGUMENTS_BAD;
810     goto loser;
811   }
812
813   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
814   if( (NSSCKFWSlot **)NULL == slots ) {
815     goto loser;
816   }
817
818   fwSlot = slots[ slotID-1 ];
819
820   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
821     error = CKR_TOKEN_NOT_PRESENT;
822     goto loser;
823   }
824
825   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
826   if (!fwToken) {
827     goto loser;
828   }
829
830   count = nssCKFWToken_GetMechanismCount(fwToken);
831
832   if( (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR == pMechanismList ) {
833     *pulCount = count;
834     return CKR_OK;
835   }
836
837   if( *pulCount < count ) {
838     *pulCount = count;
839     error = CKR_BUFFER_TOO_SMALL;
840     goto loser;
841   }
842
843   /*
844    * A purify error here indicates caller error.
845    */
846   (void)nsslibc_memset(pMechanismList, 0, *pulCount * sizeof(CK_MECHANISM_TYPE));
847
848   *pulCount = count;
849
850   if( 0 != count ) {
851     error = nssCKFWToken_GetMechanismTypes(fwToken, pMechanismList);
852   } else {
853     error = CKR_OK;
854   }
855
856   if( CKR_OK == error ) {
857     return CKR_OK;
858   }
859
860  loser:
861   switch( error ) {
862   case CKR_DEVICE_REMOVED:
863   case CKR_TOKEN_NOT_PRESENT:
864     if (fwToken)
865       nssCKFWToken_Destroy(fwToken);
866     break;
867   case CKR_ARGUMENTS_BAD:
868   case CKR_BUFFER_TOO_SMALL:
869   case CKR_CRYPTOKI_NOT_INITIALIZED:
870   case CKR_DEVICE_ERROR:
871   case CKR_DEVICE_MEMORY:
872   case CKR_FUNCTION_FAILED:
873   case CKR_GENERAL_ERROR:
874   case CKR_HOST_MEMORY:
875   case CKR_SLOT_ID_INVALID:
876   case CKR_TOKEN_NOT_RECOGNIZED:
877     break;
878   default:
879   case CKR_OK:
880     error = CKR_GENERAL_ERROR;
881     break;
882   }
883
884   return error;
885 }
886
887 /*
888  * NSSCKFWC_GetMechanismInfo
889  *
890  */
891 NSS_IMPLEMENT CK_RV
892 NSSCKFWC_GetMechanismInfo
893 (
894   NSSCKFWInstance *fwInstance,
895   CK_SLOT_ID slotID,
896   CK_MECHANISM_TYPE type,
897   CK_MECHANISM_INFO_PTR pInfo
898 )
899 {
900   CK_RV error = CKR_OK;
901   CK_ULONG nSlots;
902   NSSCKFWSlot **slots;
903   NSSCKFWSlot *fwSlot;
904   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
905   NSSCKFWMechanism *fwMechanism;
906
907   if (!fwInstance) {
908     error = CKR_CRYPTOKI_NOT_INITIALIZED;
909     goto loser;
910   }
911
912   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
913   if( (CK_ULONG)0 == nSlots ) {
914     goto loser;
915   }
916
917   if( (slotID < 1) || (slotID > nSlots) ) {
918     error = CKR_SLOT_ID_INVALID;
919     goto loser;
920   }
921
922   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
923   if( (NSSCKFWSlot **)NULL == slots ) {
924     goto loser;
925   }
926
927   fwSlot = slots[ slotID-1 ];
928
929   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
930     error = CKR_TOKEN_NOT_PRESENT;
931     goto loser;
932   }
933
934   if( (CK_MECHANISM_INFO_PTR)CK_NULL_PTR == pInfo ) {
935     error = CKR_ARGUMENTS_BAD;
936     goto loser;
937   }
938
939   /*
940    * A purify error here indicates caller error.
941    */
942   (void)nsslibc_memset(pInfo, 0, sizeof(CK_MECHANISM_INFO));
943
944   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
945   if (!fwToken) {
946     goto loser;
947   }
948
949   fwMechanism = nssCKFWToken_GetMechanism(fwToken, type, &error);
950   if (!fwMechanism) {
951     goto loser;
952   }
953
954   pInfo->ulMinKeySize = nssCKFWMechanism_GetMinKeySize(fwMechanism, &error);
955   pInfo->ulMaxKeySize = nssCKFWMechanism_GetMaxKeySize(fwMechanism, &error);
956
957   if( nssCKFWMechanism_GetInHardware(fwMechanism, &error) ) {
958     pInfo->flags |= CKF_HW;
959   }
960   if( nssCKFWMechanism_GetCanEncrypt(fwMechanism, &error) ) {
961     pInfo->flags |= CKF_ENCRYPT;
962   }
963   if( nssCKFWMechanism_GetCanDecrypt(fwMechanism, &error) ) {
964     pInfo->flags |= CKF_DECRYPT;
965   }
966   if( nssCKFWMechanism_GetCanDigest(fwMechanism, &error) ) {
967     pInfo->flags |= CKF_DIGEST;
968   }
969   if( nssCKFWMechanism_GetCanSign(fwMechanism, &error) ) {
970     pInfo->flags |= CKF_SIGN;
971   }
972   if( nssCKFWMechanism_GetCanSignRecover(fwMechanism, &error) ) {
973     pInfo->flags |= CKF_SIGN_RECOVER;
974   }
975   if( nssCKFWMechanism_GetCanVerify(fwMechanism, &error) ) {
976     pInfo->flags |= CKF_VERIFY;
977   }
978   if( nssCKFWMechanism_GetCanVerifyRecover(fwMechanism, &error) ) {
979     pInfo->flags |= CKF_VERIFY_RECOVER;
980   }
981   if( nssCKFWMechanism_GetCanGenerate(fwMechanism, &error) ) {
982     pInfo->flags |= CKF_GENERATE;
983   }
984   if( nssCKFWMechanism_GetCanGenerateKeyPair(fwMechanism, &error) ) {
985     pInfo->flags |= CKF_GENERATE_KEY_PAIR;
986   }
987   if( nssCKFWMechanism_GetCanWrap(fwMechanism, &error) ) {
988     pInfo->flags |= CKF_WRAP;
989   }
990   if( nssCKFWMechanism_GetCanUnwrap(fwMechanism, &error) ) {
991     pInfo->flags |= CKF_UNWRAP;
992   }
993   if( nssCKFWMechanism_GetCanDerive(fwMechanism, &error) ) {
994     pInfo->flags |= CKF_DERIVE;
995   }
996   nssCKFWMechanism_Destroy(fwMechanism);
997
998   return error;
999
1000  loser:
1001   switch( error ) {
1002   case CKR_DEVICE_REMOVED:
1003   case CKR_TOKEN_NOT_PRESENT:
1004     if (fwToken)
1005       nssCKFWToken_Destroy(fwToken);
1006     break;
1007   case CKR_ARGUMENTS_BAD:
1008   case CKR_CRYPTOKI_NOT_INITIALIZED:
1009   case CKR_DEVICE_ERROR:
1010   case CKR_DEVICE_MEMORY:
1011   case CKR_FUNCTION_FAILED:
1012   case CKR_GENERAL_ERROR:
1013   case CKR_HOST_MEMORY:
1014   case CKR_MECHANISM_INVALID:
1015   case CKR_SLOT_ID_INVALID:
1016   case CKR_TOKEN_NOT_RECOGNIZED:
1017     break;
1018   default:
1019   case CKR_OK:
1020     error = CKR_GENERAL_ERROR;
1021     break;
1022   }
1023
1024   return error;
1025 }
1026
1027 /*
1028  * NSSCKFWC_InitToken
1029  *
1030  */
1031 NSS_IMPLEMENT CK_RV
1032 NSSCKFWC_InitToken
1033 (
1034   NSSCKFWInstance *fwInstance,
1035   CK_SLOT_ID slotID,
1036   CK_CHAR_PTR pPin,
1037   CK_ULONG ulPinLen,
1038   CK_CHAR_PTR pLabel
1039 )
1040 {
1041   CK_RV error = CKR_OK;
1042   CK_ULONG nSlots;
1043   NSSCKFWSlot **slots;
1044   NSSCKFWSlot *fwSlot;
1045   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
1046   NSSItem pin;
1047   NSSUTF8 *label;
1048
1049   if (!fwInstance) {
1050     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1051     goto loser;
1052   }
1053
1054   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
1055   if( (CK_ULONG)0 == nSlots ) {
1056     goto loser;
1057   }
1058
1059   if( (slotID < 1) || (slotID > nSlots) ) {
1060     error = CKR_SLOT_ID_INVALID;
1061     goto loser;
1062   }
1063
1064   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
1065   if( (NSSCKFWSlot **)NULL == slots ) {
1066     goto loser;
1067   }
1068
1069   fwSlot = slots[ slotID-1 ];
1070
1071   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
1072     error = CKR_TOKEN_NOT_PRESENT;
1073     goto loser;
1074   }
1075
1076   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
1077   if (!fwToken) {
1078     goto loser;
1079   }
1080
1081   pin.size = (PRUint32)ulPinLen;
1082   pin.data = (void *)pPin;
1083   label = (NSSUTF8 *)pLabel; /* identity conversion */
1084
1085   error = nssCKFWToken_InitToken(fwToken, &pin, label);
1086   if( CKR_OK != error ) {
1087     goto loser;
1088   }
1089
1090   return CKR_OK;
1091
1092  loser:
1093   switch( error ) {
1094   case CKR_DEVICE_REMOVED:
1095   case CKR_TOKEN_NOT_PRESENT:
1096     if (fwToken)
1097       nssCKFWToken_Destroy(fwToken);
1098     break;
1099   case CKR_ARGUMENTS_BAD:
1100   case CKR_CRYPTOKI_NOT_INITIALIZED:
1101   case CKR_DEVICE_ERROR:
1102   case CKR_DEVICE_MEMORY:
1103   case CKR_FUNCTION_FAILED:
1104   case CKR_GENERAL_ERROR:
1105   case CKR_HOST_MEMORY:
1106   case CKR_PIN_INCORRECT:
1107   case CKR_PIN_LOCKED:
1108   case CKR_SESSION_EXISTS:
1109   case CKR_SLOT_ID_INVALID:
1110   case CKR_TOKEN_NOT_RECOGNIZED:
1111   case CKR_TOKEN_WRITE_PROTECTED:
1112     break;
1113   default:
1114   case CKR_OK:
1115     error = CKR_GENERAL_ERROR;
1116     break;
1117   }
1118
1119   return error;
1120 }
1121
1122 /*
1123  * NSSCKFWC_InitPIN
1124  *
1125  */
1126 NSS_IMPLEMENT CK_RV
1127 NSSCKFWC_InitPIN
1128 (
1129   NSSCKFWInstance *fwInstance,
1130   CK_SESSION_HANDLE hSession,
1131   CK_CHAR_PTR pPin,
1132   CK_ULONG ulPinLen
1133 )
1134 {
1135   CK_RV error = CKR_OK;
1136   NSSCKFWSession *fwSession;
1137   NSSItem pin, *arg;
1138
1139   if (!fwInstance) {
1140     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1141     goto loser;
1142   }
1143
1144   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1145   if (!fwSession) {
1146     error = CKR_SESSION_HANDLE_INVALID;
1147     goto loser;
1148   }
1149
1150   if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
1151     arg = (NSSItem *)NULL;
1152   } else {
1153     arg = &pin;
1154     pin.size = (PRUint32)ulPinLen;
1155     pin.data = (void *)pPin;
1156   }
1157
1158   error = nssCKFWSession_InitPIN(fwSession, arg);
1159   if( CKR_OK != error ) {
1160     goto loser;
1161   }
1162
1163   return CKR_OK;
1164
1165  loser:
1166   switch( error ) {
1167   case CKR_SESSION_CLOSED:
1168     /* destroy session? */
1169     break;
1170   case CKR_DEVICE_REMOVED:
1171     /* (void)nssCKFWToken_Destroy(fwToken); */
1172     break;
1173   case CKR_ARGUMENTS_BAD:
1174   case CKR_CRYPTOKI_NOT_INITIALIZED:
1175   case CKR_DEVICE_ERROR:
1176   case CKR_DEVICE_MEMORY:
1177   case CKR_FUNCTION_FAILED:
1178   case CKR_GENERAL_ERROR:
1179   case CKR_HOST_MEMORY:
1180   case CKR_PIN_INVALID:
1181   case CKR_PIN_LEN_RANGE:
1182   case CKR_SESSION_READ_ONLY:
1183   case CKR_SESSION_HANDLE_INVALID:
1184   case CKR_TOKEN_WRITE_PROTECTED:
1185   case CKR_USER_NOT_LOGGED_IN:
1186     break;
1187   default:
1188   case CKR_OK:
1189     error = CKR_GENERAL_ERROR;
1190     break;
1191   }
1192
1193   return error;
1194 }
1195
1196 /*
1197  * NSSCKFWC_SetPIN
1198  *
1199  */
1200 NSS_IMPLEMENT CK_RV
1201 NSSCKFWC_SetPIN
1202 (
1203   NSSCKFWInstance *fwInstance,
1204   CK_SESSION_HANDLE hSession,
1205   CK_CHAR_PTR pOldPin,
1206   CK_ULONG ulOldLen,
1207   CK_CHAR_PTR pNewPin,
1208   CK_ULONG ulNewLen
1209 )
1210 {
1211   CK_RV error = CKR_OK;
1212   NSSCKFWSession *fwSession;
1213   NSSItem oldPin, newPin, *oldArg, *newArg;
1214
1215   if (!fwInstance) {
1216     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1217     goto loser;
1218   }
1219
1220   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1221   if (!fwSession) {
1222     error = CKR_SESSION_HANDLE_INVALID;
1223     goto loser;
1224   }
1225
1226   if( (CK_CHAR_PTR)CK_NULL_PTR == pOldPin ) {
1227     oldArg = (NSSItem *)NULL;
1228   } else {
1229     oldArg = &oldPin;
1230     oldPin.size = (PRUint32)ulOldLen;
1231     oldPin.data = (void *)pOldPin;
1232   }
1233
1234   if( (CK_CHAR_PTR)CK_NULL_PTR == pNewPin ) {
1235     newArg = (NSSItem *)NULL;
1236   } else {
1237     newArg = &newPin;
1238     newPin.size = (PRUint32)ulNewLen;
1239     newPin.data = (void *)pNewPin;
1240   }
1241
1242   error = nssCKFWSession_SetPIN(fwSession, oldArg, newArg);
1243   if( CKR_OK != error ) {
1244     goto loser;
1245   }
1246
1247   return CKR_OK;
1248
1249  loser:
1250   switch( error ) {
1251   case CKR_SESSION_CLOSED:
1252     /* destroy session? */
1253     break;
1254   case CKR_DEVICE_REMOVED:
1255     /* (void)nssCKFWToken_Destroy(fwToken); */
1256     break;
1257   case CKR_ARGUMENTS_BAD:
1258   case CKR_CRYPTOKI_NOT_INITIALIZED:
1259   case CKR_DEVICE_ERROR:
1260   case CKR_DEVICE_MEMORY:
1261   case CKR_FUNCTION_FAILED:
1262   case CKR_GENERAL_ERROR:
1263   case CKR_HOST_MEMORY:
1264   case CKR_PIN_INCORRECT:
1265   case CKR_PIN_INVALID:
1266   case CKR_PIN_LEN_RANGE:
1267   case CKR_PIN_LOCKED:
1268   case CKR_SESSION_HANDLE_INVALID:
1269   case CKR_SESSION_READ_ONLY:
1270   case CKR_TOKEN_WRITE_PROTECTED:
1271     break;
1272   default:
1273   case CKR_OK:
1274     error = CKR_GENERAL_ERROR;
1275     break;
1276   }
1277
1278   return error;
1279 }
1280
1281 /*
1282  * NSSCKFWC_OpenSession
1283  *
1284  */
1285 NSS_IMPLEMENT CK_RV
1286 NSSCKFWC_OpenSession
1287 (
1288   NSSCKFWInstance *fwInstance,
1289   CK_SLOT_ID slotID,
1290   CK_FLAGS flags,
1291   CK_VOID_PTR pApplication,
1292   CK_NOTIFY Notify,
1293   CK_SESSION_HANDLE_PTR phSession
1294 )
1295 {
1296   CK_RV error = CKR_OK;
1297   CK_ULONG nSlots;
1298   NSSCKFWSlot **slots;
1299   NSSCKFWSlot *fwSlot;
1300   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
1301   NSSCKFWSession *fwSession;
1302   CK_BBOOL rw;
1303
1304   if (!fwInstance) {
1305     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1306     goto loser;
1307   }
1308
1309   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
1310   if( (CK_ULONG)0 == nSlots ) {
1311     goto loser;
1312   }
1313
1314   if( (slotID < 1) || (slotID > nSlots) ) {
1315     error = CKR_SLOT_ID_INVALID;
1316     goto loser;
1317   }
1318
1319   if( flags & CKF_RW_SESSION ) {
1320     rw = CK_TRUE;
1321   } else {
1322     rw = CK_FALSE;
1323   }
1324
1325   if( flags & CKF_SERIAL_SESSION ) {
1326     ;
1327   } else {
1328     error = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
1329     goto loser;
1330   }
1331
1332   if( flags & ~(CKF_RW_SESSION|CKF_SERIAL_SESSION) ) {
1333     error = CKR_ARGUMENTS_BAD;
1334     goto loser;
1335   }
1336
1337   if( (CK_SESSION_HANDLE_PTR)CK_NULL_PTR == phSession ) {
1338     error = CKR_ARGUMENTS_BAD;
1339     goto loser;
1340   }
1341
1342   /*
1343    * A purify error here indicates caller error.
1344    */
1345   *phSession = (CK_SESSION_HANDLE)0;
1346
1347   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
1348   if( (NSSCKFWSlot **)NULL == slots ) {
1349     goto loser;
1350   }
1351
1352   fwSlot = slots[ slotID-1 ];
1353
1354   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
1355     error = CKR_TOKEN_NOT_PRESENT;
1356     goto loser;
1357   }
1358
1359   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
1360   if (!fwToken) {
1361     goto loser;
1362   }
1363
1364   fwSession = nssCKFWToken_OpenSession(fwToken, rw, pApplication,
1365                Notify, &error);
1366   if (!fwSession) {
1367     goto loser;
1368   }
1369
1370   *phSession = nssCKFWInstance_CreateSessionHandle(fwInstance,
1371                  fwSession, &error);
1372   if( (CK_SESSION_HANDLE)0 == *phSession ) {
1373     goto loser;
1374   }
1375
1376   return CKR_OK;
1377
1378  loser:
1379   switch( error ) {
1380   case CKR_SESSION_CLOSED:
1381     /* destroy session? */
1382     break;
1383   case CKR_DEVICE_REMOVED:
1384     /* (void)nssCKFWToken_Destroy(fwToken); */
1385     break;
1386   case CKR_CRYPTOKI_NOT_INITIALIZED:
1387   case CKR_DEVICE_ERROR:
1388   case CKR_DEVICE_MEMORY:
1389   case CKR_FUNCTION_FAILED:
1390   case CKR_GENERAL_ERROR:
1391   case CKR_HOST_MEMORY:
1392   case CKR_SESSION_COUNT:
1393   case CKR_SESSION_EXISTS:
1394   case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
1395   case CKR_SESSION_READ_WRITE_SO_EXISTS:
1396   case CKR_SLOT_ID_INVALID:
1397   case CKR_TOKEN_NOT_PRESENT:
1398   case CKR_TOKEN_NOT_RECOGNIZED:
1399   case CKR_TOKEN_WRITE_PROTECTED:
1400     break;
1401   default:
1402   case CKR_OK:
1403     error = CKR_GENERAL_ERROR;
1404     break;
1405   }
1406
1407   return error;
1408 }
1409
1410 /*
1411  * NSSCKFWC_CloseSession
1412  *
1413  */
1414 NSS_IMPLEMENT CK_RV
1415 NSSCKFWC_CloseSession
1416 (
1417   NSSCKFWInstance *fwInstance,
1418   CK_SESSION_HANDLE hSession
1419 )
1420 {
1421   CK_RV error = CKR_OK;
1422   NSSCKFWSession *fwSession;
1423
1424   if (!fwInstance) {
1425     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1426     goto loser;
1427   }
1428
1429   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1430   if (!fwSession) {
1431     error = CKR_SESSION_HANDLE_INVALID;
1432     goto loser;
1433   }
1434
1435   nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
1436   error = nssCKFWSession_Destroy(fwSession, CK_TRUE);
1437
1438   if( CKR_OK != error ) {
1439     goto loser;
1440   }
1441
1442   return CKR_OK;
1443
1444  loser:
1445   switch( error ) {
1446   case CKR_SESSION_CLOSED:
1447     /* destroy session? */
1448     break;
1449   case CKR_DEVICE_REMOVED:
1450     /* (void)nssCKFWToken_Destroy(fwToken); */
1451     break;
1452   case CKR_CRYPTOKI_NOT_INITIALIZED:
1453   case CKR_DEVICE_ERROR:
1454   case CKR_DEVICE_MEMORY:
1455   case CKR_FUNCTION_FAILED:
1456   case CKR_GENERAL_ERROR:
1457   case CKR_HOST_MEMORY:
1458   case CKR_SESSION_HANDLE_INVALID:
1459     break;
1460   default:
1461   case CKR_OK:
1462     error = CKR_GENERAL_ERROR;
1463     break;
1464   }
1465
1466   return error;
1467 }
1468
1469 /*
1470  * NSSCKFWC_CloseAllSessions
1471  *
1472  */
1473 NSS_IMPLEMENT CK_RV
1474 NSSCKFWC_CloseAllSessions
1475 (
1476   NSSCKFWInstance *fwInstance,
1477   CK_SLOT_ID slotID
1478 )
1479 {
1480   CK_RV error = CKR_OK;
1481   CK_ULONG nSlots;
1482   NSSCKFWSlot **slots;
1483   NSSCKFWSlot *fwSlot;
1484   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
1485
1486   if (!fwInstance) {
1487     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1488     goto loser;
1489   }
1490
1491   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
1492   if( (CK_ULONG)0 == nSlots ) {
1493     goto loser;
1494   }
1495
1496   if( (slotID < 1) || (slotID > nSlots) ) {
1497     error = CKR_SLOT_ID_INVALID;
1498     goto loser;
1499   }
1500
1501   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
1502   if( (NSSCKFWSlot **)NULL == slots ) {
1503     goto loser;
1504   }
1505
1506   fwSlot = slots[ slotID-1 ];
1507
1508   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
1509     error = CKR_TOKEN_NOT_PRESENT;
1510     goto loser;
1511   }
1512
1513   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
1514   if (!fwToken) {
1515     goto loser;
1516   }
1517
1518   error = nssCKFWToken_CloseAllSessions(fwToken);
1519   if( CKR_OK != error ) {
1520     goto loser;
1521   }
1522
1523   return CKR_OK;
1524
1525  loser:
1526   switch( error ) {
1527   case CKR_DEVICE_REMOVED:
1528     /* (void)nssCKFWToken_Destroy(fwToken); */
1529     break;
1530   case CKR_CRYPTOKI_NOT_INITIALIZED:
1531   case CKR_DEVICE_ERROR:
1532   case CKR_DEVICE_MEMORY:
1533   case CKR_FUNCTION_FAILED:
1534   case CKR_GENERAL_ERROR:
1535   case CKR_HOST_MEMORY:
1536   case CKR_SLOT_ID_INVALID:
1537   case CKR_TOKEN_NOT_PRESENT:
1538     break;
1539   default:
1540   case CKR_OK:
1541     error = CKR_GENERAL_ERROR;
1542     break;
1543   }
1544
1545   return error;
1546 }
1547
1548 /*
1549  * NSSCKFWC_GetSessionInfo
1550  *
1551  */
1552 NSS_IMPLEMENT CK_RV
1553 NSSCKFWC_GetSessionInfo
1554 (
1555   NSSCKFWInstance *fwInstance,
1556   CK_SESSION_HANDLE hSession,
1557   CK_SESSION_INFO_PTR pInfo
1558 )
1559 {
1560   CK_RV error = CKR_OK;
1561   NSSCKFWSession *fwSession;
1562   NSSCKFWSlot *fwSlot;
1563
1564   if (!fwInstance) {
1565     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1566     goto loser;
1567   }
1568
1569   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1570   if (!fwSession) {
1571     error = CKR_SESSION_HANDLE_INVALID;
1572     goto loser;
1573   }
1574
1575   if( (CK_SESSION_INFO_PTR)CK_NULL_PTR == pInfo ) {
1576     error = CKR_ARGUMENTS_BAD;
1577     goto loser;
1578   }
1579
1580   /*
1581    * A purify error here indicates caller error.
1582    */
1583   (void)nsslibc_memset(pInfo, 0, sizeof(CK_SESSION_INFO));
1584
1585   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
1586   if (!fwSlot) {
1587     error = CKR_GENERAL_ERROR;
1588     goto loser;
1589   }
1590
1591   pInfo->slotID = nssCKFWSlot_GetSlotID(fwSlot);
1592   pInfo->state = nssCKFWSession_GetSessionState(fwSession);
1593
1594   if( CK_TRUE == nssCKFWSession_IsRWSession(fwSession) ) {
1595     pInfo->flags |= CKF_RW_SESSION;
1596   }
1597
1598   pInfo->flags |= CKF_SERIAL_SESSION; /* Always true */
1599
1600   pInfo->ulDeviceError = nssCKFWSession_GetDeviceError(fwSession);
1601
1602   return CKR_OK;
1603
1604  loser:
1605   switch( error ) {
1606   case CKR_SESSION_CLOSED:
1607     /* destroy session? */
1608     break;
1609   case CKR_DEVICE_REMOVED:
1610     /* (void)nssCKFWToken_Destroy(fwToken); */
1611     break;
1612   case CKR_CRYPTOKI_NOT_INITIALIZED:
1613   case CKR_DEVICE_ERROR:
1614   case CKR_DEVICE_MEMORY:
1615   case CKR_FUNCTION_FAILED:
1616   case CKR_GENERAL_ERROR:
1617   case CKR_HOST_MEMORY:
1618   case CKR_SESSION_HANDLE_INVALID:
1619     break;
1620   default:
1621   case CKR_OK:
1622     error = CKR_GENERAL_ERROR;
1623     break;
1624   }
1625
1626   return error;
1627 }
1628
1629 /*
1630  * NSSCKFWC_GetOperationState
1631  *
1632  */
1633 NSS_IMPLEMENT CK_RV
1634 NSSCKFWC_GetOperationState
1635 (
1636   NSSCKFWInstance *fwInstance,
1637   CK_SESSION_HANDLE hSession,
1638   CK_BYTE_PTR pOperationState,
1639   CK_ULONG_PTR pulOperationStateLen
1640 )
1641 {
1642   CK_RV error = CKR_OK;
1643   NSSCKFWSession *fwSession;
1644   CK_ULONG len;
1645   NSSItem buf;
1646
1647   if (!fwInstance) {
1648     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1649     goto loser;
1650   }
1651
1652   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1653   if (!fwSession) {
1654     error = CKR_SESSION_HANDLE_INVALID;
1655     goto loser;
1656   }
1657
1658   if( (CK_ULONG_PTR)CK_NULL_PTR == pulOperationStateLen ) {
1659     error = CKR_ARGUMENTS_BAD;
1660     goto loser;
1661   }
1662
1663   len = nssCKFWSession_GetOperationStateLen(fwSession, &error);
1664   if( ((CK_ULONG)0 == len) && (CKR_OK != error) ) {
1665     goto loser;
1666   }
1667
1668   if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
1669     *pulOperationStateLen = len;
1670     return CKR_OK;
1671   }
1672
1673   if( *pulOperationStateLen < len ) {
1674     *pulOperationStateLen = len;
1675     error = CKR_BUFFER_TOO_SMALL;
1676     goto loser;
1677   }
1678
1679   buf.size = (PRUint32)*pulOperationStateLen;
1680   buf.data = (void *)pOperationState;
1681   *pulOperationStateLen = len;
1682   error = nssCKFWSession_GetOperationState(fwSession, &buf);
1683
1684   if( CKR_OK != error ) {
1685     goto loser;
1686   }
1687
1688   return CKR_OK;
1689
1690  loser:
1691   switch( error ) {
1692   case CKR_SESSION_CLOSED:
1693     /* destroy session? */
1694     break;
1695   case CKR_DEVICE_REMOVED:
1696     /* (void)nssCKFWToken_Destroy(fwToken); */
1697     break;
1698   case CKR_BUFFER_TOO_SMALL:
1699   case CKR_CRYPTOKI_NOT_INITIALIZED:
1700   case CKR_DEVICE_ERROR:
1701   case CKR_DEVICE_MEMORY:
1702   case CKR_FUNCTION_FAILED:
1703   case CKR_GENERAL_ERROR:
1704   case CKR_HOST_MEMORY:
1705   case CKR_OPERATION_NOT_INITIALIZED:
1706   case CKR_SESSION_HANDLE_INVALID:
1707   case CKR_STATE_UNSAVEABLE:
1708     break;
1709   default:
1710   case CKR_OK:
1711     error = CKR_GENERAL_ERROR;
1712     break;
1713   }
1714
1715   return error;
1716 }
1717
1718 /*
1719  * NSSCKFWC_SetOperationState
1720  *
1721  */
1722 NSS_IMPLEMENT CK_RV
1723 NSSCKFWC_SetOperationState
1724 (
1725   NSSCKFWInstance *fwInstance,
1726   CK_SESSION_HANDLE hSession,
1727   CK_BYTE_PTR pOperationState,
1728   CK_ULONG ulOperationStateLen,
1729   CK_OBJECT_HANDLE hEncryptionKey,
1730   CK_OBJECT_HANDLE hAuthenticationKey
1731 )
1732 {
1733   CK_RV error = CKR_OK;
1734   NSSCKFWSession *fwSession;
1735   NSSCKFWObject *eKey;
1736   NSSCKFWObject *aKey;
1737   NSSItem state;
1738
1739   if (!fwInstance) {
1740     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1741     goto loser;
1742   }
1743   
1744   if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
1745     error = CKR_ARGUMENTS_BAD;
1746     goto loser;
1747   }
1748
1749   /* 
1750    * We could loop through the buffer, to catch any purify errors
1751    * in a place with a "user error" note.
1752    */
1753
1754   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1755   if (!fwSession) {
1756     error = CKR_SESSION_HANDLE_INVALID;
1757     goto loser;
1758   }
1759
1760   if( (CK_OBJECT_HANDLE)0 == hEncryptionKey ) {
1761     eKey = (NSSCKFWObject *)NULL;
1762   } else {
1763     eKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hEncryptionKey);
1764     if (!eKey) {
1765       error = CKR_KEY_HANDLE_INVALID;
1766       goto loser;
1767     }
1768   }
1769
1770   if( (CK_OBJECT_HANDLE)0 == hAuthenticationKey ) {
1771     aKey = (NSSCKFWObject *)NULL;
1772   } else {
1773     aKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hAuthenticationKey);
1774     if (!aKey) {
1775       error = CKR_KEY_HANDLE_INVALID;
1776       goto loser;
1777     }
1778   }
1779
1780   state.data = pOperationState;
1781   state.size = ulOperationStateLen;
1782
1783   error = nssCKFWSession_SetOperationState(fwSession, &state, eKey, aKey);
1784   if( CKR_OK != error ) {
1785     goto loser;
1786   }
1787
1788   return CKR_OK;
1789
1790  loser:
1791   switch( error ) {
1792   case CKR_SESSION_CLOSED:
1793     /* destroy session? */
1794     break;
1795   case CKR_DEVICE_REMOVED:
1796     /* (void)nssCKFWToken_Destroy(fwToken); */
1797     break;
1798   case CKR_CRYPTOKI_NOT_INITIALIZED:
1799   case CKR_DEVICE_ERROR:
1800   case CKR_DEVICE_MEMORY:
1801   case CKR_FUNCTION_FAILED:
1802   case CKR_GENERAL_ERROR:
1803   case CKR_HOST_MEMORY:
1804   case CKR_KEY_CHANGED:
1805   case CKR_KEY_NEEDED:
1806   case CKR_KEY_NOT_NEEDED:
1807   case CKR_SAVED_STATE_INVALID:
1808   case CKR_SESSION_HANDLE_INVALID:
1809     break;
1810   default:
1811   case CKR_OK:
1812     error = CKR_GENERAL_ERROR;
1813     break;
1814   }
1815
1816   return error;
1817 }
1818
1819 /*
1820  * NSSCKFWC_Login
1821  *
1822  */
1823 NSS_IMPLEMENT CK_RV
1824 NSSCKFWC_Login
1825 (
1826   NSSCKFWInstance *fwInstance,
1827   CK_SESSION_HANDLE hSession,
1828   CK_USER_TYPE userType,
1829   CK_CHAR_PTR pPin,
1830   CK_ULONG ulPinLen
1831 )
1832 {
1833   CK_RV error = CKR_OK;
1834   NSSCKFWSession *fwSession;
1835   NSSItem pin, *arg;
1836
1837   if (!fwInstance) {
1838     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1839     goto loser;
1840   }
1841   
1842   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1843   if (!fwSession) {
1844     error = CKR_SESSION_HANDLE_INVALID;
1845     goto loser;
1846   }
1847
1848   if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
1849     arg = (NSSItem *)NULL;
1850   } else {
1851     arg = &pin;
1852     pin.size = (PRUint32)ulPinLen;
1853     pin.data = (void *)pPin;
1854   }
1855
1856   error = nssCKFWSession_Login(fwSession, userType, arg);
1857   if( CKR_OK != error ) {
1858     goto loser;
1859   }
1860
1861   return CKR_OK;
1862
1863  loser:
1864   switch( error ) {
1865   case CKR_SESSION_CLOSED:
1866     /* destroy session? */
1867     break;
1868   case CKR_DEVICE_REMOVED:
1869     /* (void)nssCKFWToken_Destroy(fwToken); */
1870     break;
1871   case CKR_CRYPTOKI_NOT_INITIALIZED:
1872   case CKR_DEVICE_ERROR:
1873   case CKR_DEVICE_MEMORY:
1874   case CKR_FUNCTION_FAILED:
1875   case CKR_GENERAL_ERROR:
1876   case CKR_HOST_MEMORY:
1877   case CKR_PIN_EXPIRED:
1878   case CKR_PIN_INCORRECT:
1879   case CKR_PIN_LOCKED:
1880   case CKR_SESSION_HANDLE_INVALID:
1881   case CKR_SESSION_READ_ONLY_EXISTS:
1882   case CKR_USER_ALREADY_LOGGED_IN:
1883   case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
1884   case CKR_USER_PIN_NOT_INITIALIZED:
1885   case CKR_USER_TOO_MANY_TYPES:
1886   case CKR_USER_TYPE_INVALID:
1887     break;
1888   default:
1889   case CKR_OK:
1890     error = CKR_GENERAL_ERROR;
1891     break;
1892   }
1893
1894   return error;
1895 }
1896
1897 /*
1898  * NSSCKFWC_Logout
1899  *
1900  */
1901 NSS_IMPLEMENT CK_RV
1902 NSSCKFWC_Logout
1903 (
1904   NSSCKFWInstance *fwInstance,
1905   CK_SESSION_HANDLE hSession
1906 )
1907 {
1908   CK_RV error = CKR_OK;
1909   NSSCKFWSession *fwSession;
1910
1911   if (!fwInstance) {
1912     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1913     goto loser;
1914   }
1915   
1916   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1917   if (!fwSession) {
1918     error = CKR_SESSION_HANDLE_INVALID;
1919     goto loser;
1920   }
1921
1922   error = nssCKFWSession_Logout(fwSession);
1923   if( CKR_OK != error ) {
1924     goto loser;
1925   }
1926
1927   return CKR_OK;
1928
1929  loser:
1930   switch( error ) {
1931   case CKR_SESSION_CLOSED:
1932     /* destroy session? */
1933     break;
1934   case CKR_DEVICE_REMOVED:
1935     /* (void)nssCKFWToken_Destroy(fwToken); */
1936     break;
1937   case CKR_CRYPTOKI_NOT_INITIALIZED:
1938   case CKR_DEVICE_ERROR:
1939   case CKR_DEVICE_MEMORY:
1940   case CKR_FUNCTION_FAILED:
1941   case CKR_GENERAL_ERROR:
1942   case CKR_HOST_MEMORY:
1943   case CKR_SESSION_HANDLE_INVALID:
1944   case CKR_USER_NOT_LOGGED_IN:
1945     break;
1946   default:
1947   case CKR_OK:
1948     error = CKR_GENERAL_ERROR;
1949     break;
1950   }
1951
1952   return error;
1953 }
1954
1955 /*
1956  * NSSCKFWC_CreateObject
1957  *
1958  */
1959 NSS_IMPLEMENT CK_RV
1960 NSSCKFWC_CreateObject
1961 (
1962   NSSCKFWInstance *fwInstance,
1963   CK_SESSION_HANDLE hSession,
1964   CK_ATTRIBUTE_PTR pTemplate,
1965   CK_ULONG ulCount,
1966   CK_OBJECT_HANDLE_PTR phObject
1967 )
1968 {
1969   CK_RV error = CKR_OK;
1970   NSSCKFWSession *fwSession;
1971   NSSCKFWObject *fwObject;
1972
1973   if (!fwInstance) {
1974     error = CKR_CRYPTOKI_NOT_INITIALIZED;
1975     goto loser;
1976   }
1977   
1978   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
1979   if (!fwSession) {
1980     error = CKR_SESSION_HANDLE_INVALID;
1981     goto loser;
1982   }
1983
1984   if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
1985     error = CKR_ARGUMENTS_BAD;
1986     goto loser;
1987   }
1988
1989   /*
1990    * A purify error here indicates caller error.
1991    */
1992   *phObject = (CK_OBJECT_HANDLE)0;
1993
1994   fwObject = nssCKFWSession_CreateObject(fwSession, pTemplate,
1995                ulCount, &error);
1996   if (!fwObject) {
1997     goto loser;
1998   }
1999
2000   *phObject = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
2001   if( (CK_OBJECT_HANDLE)0 == *phObject ) {
2002     nssCKFWObject_Destroy(fwObject);
2003     goto loser;
2004   }
2005
2006   return CKR_OK;
2007
2008  loser:
2009   switch( error ) {
2010   case CKR_SESSION_CLOSED:
2011     /* destroy session? */
2012     break;
2013   case CKR_DEVICE_REMOVED:
2014     /* (void)nssCKFWToken_Destroy(fwToken); */
2015     break;
2016   case CKR_ATTRIBUTE_READ_ONLY:
2017   case CKR_ATTRIBUTE_TYPE_INVALID:
2018   case CKR_ATTRIBUTE_VALUE_INVALID:
2019   case CKR_CRYPTOKI_NOT_INITIALIZED:
2020   case CKR_DEVICE_ERROR:
2021   case CKR_DEVICE_MEMORY:
2022   case CKR_FUNCTION_FAILED:
2023   case CKR_GENERAL_ERROR:
2024   case CKR_HOST_MEMORY:
2025   case CKR_SESSION_HANDLE_INVALID:
2026   case CKR_SESSION_READ_ONLY:
2027   case CKR_TEMPLATE_INCOMPLETE:
2028   case CKR_TEMPLATE_INCONSISTENT:
2029   case CKR_TOKEN_WRITE_PROTECTED:
2030   case CKR_USER_NOT_LOGGED_IN:
2031     break;
2032   default:
2033   case CKR_OK:
2034     error = CKR_GENERAL_ERROR;
2035     break;
2036   }
2037
2038   return error;
2039 }
2040
2041 /*
2042  * NSSCKFWC_CopyObject
2043  *
2044  */
2045 NSS_IMPLEMENT CK_RV
2046 NSSCKFWC_CopyObject
2047 (
2048   NSSCKFWInstance *fwInstance,
2049   CK_SESSION_HANDLE hSession,
2050   CK_OBJECT_HANDLE hObject,
2051   CK_ATTRIBUTE_PTR pTemplate,
2052   CK_ULONG ulCount,
2053   CK_OBJECT_HANDLE_PTR phNewObject
2054 )
2055 {
2056   CK_RV error = CKR_OK;
2057   NSSCKFWSession *fwSession;
2058   NSSCKFWObject *fwObject;
2059   NSSCKFWObject *fwNewObject;
2060
2061   if (!fwInstance) {
2062     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2063     goto loser;
2064   }
2065   
2066   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2067   if (!fwSession) {
2068     error = CKR_SESSION_HANDLE_INVALID;
2069     goto loser;
2070   }
2071
2072   if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phNewObject ) {
2073     error = CKR_ARGUMENTS_BAD;
2074     goto loser;
2075   }
2076
2077   /*
2078    * A purify error here indicates caller error.
2079    */
2080   *phNewObject = (CK_OBJECT_HANDLE)0;
2081
2082   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
2083   if (!fwObject) {
2084     error = CKR_OBJECT_HANDLE_INVALID;
2085     goto loser;
2086   }
2087
2088   fwNewObject = nssCKFWSession_CopyObject(fwSession, fwObject,
2089                   pTemplate, ulCount, &error);
2090   if (!fwNewObject) {
2091     goto loser;
2092   }
2093
2094   *phNewObject = nssCKFWInstance_CreateObjectHandle(fwInstance, 
2095                    fwNewObject, &error);
2096   if( (CK_OBJECT_HANDLE)0 == *phNewObject ) {
2097     nssCKFWObject_Destroy(fwNewObject);
2098     goto loser;
2099   }
2100
2101   return CKR_OK;
2102
2103  loser:
2104   switch( error ) {
2105   case CKR_SESSION_CLOSED:
2106     /* destroy session? */
2107     break;
2108   case CKR_DEVICE_REMOVED:
2109     /* (void)nssCKFWToken_Destroy(fwToken); */
2110     break;
2111   case CKR_ATTRIBUTE_READ_ONLY:
2112   case CKR_ATTRIBUTE_TYPE_INVALID:
2113   case CKR_ATTRIBUTE_VALUE_INVALID:
2114   case CKR_CRYPTOKI_NOT_INITIALIZED:
2115   case CKR_DEVICE_ERROR:
2116   case CKR_DEVICE_MEMORY:
2117   case CKR_FUNCTION_FAILED:
2118   case CKR_GENERAL_ERROR:
2119   case CKR_HOST_MEMORY:
2120   case CKR_OBJECT_HANDLE_INVALID:
2121   case CKR_SESSION_HANDLE_INVALID:
2122   case CKR_SESSION_READ_ONLY:
2123   case CKR_TEMPLATE_INCONSISTENT:
2124   case CKR_TOKEN_WRITE_PROTECTED:
2125   case CKR_USER_NOT_LOGGED_IN:
2126     break;
2127   default:
2128   case CKR_OK:
2129     error = CKR_GENERAL_ERROR;
2130     break;
2131   }
2132
2133   return error;
2134 }
2135
2136 /*
2137  * NSSCKFWC_DestroyObject
2138  *
2139  */
2140 NSS_IMPLEMENT CK_RV
2141 NSSCKFWC_DestroyObject
2142 (
2143   NSSCKFWInstance *fwInstance,
2144   CK_SESSION_HANDLE hSession,
2145   CK_OBJECT_HANDLE hObject
2146 )
2147 {
2148   CK_RV error = CKR_OK;
2149   NSSCKFWSession *fwSession;
2150   NSSCKFWObject *fwObject;
2151
2152   if (!fwInstance) {
2153     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2154     goto loser;
2155   }
2156   
2157   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2158   if (!fwSession) {
2159     error = CKR_SESSION_HANDLE_INVALID;
2160     goto loser;
2161   }
2162
2163   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
2164   if (!fwObject) {
2165     error = CKR_OBJECT_HANDLE_INVALID;
2166     goto loser;
2167   }
2168
2169   nssCKFWInstance_DestroyObjectHandle(fwInstance, hObject);
2170   nssCKFWObject_Destroy(fwObject);
2171
2172   return CKR_OK;
2173
2174  loser:
2175   switch( error ) {
2176   case CKR_SESSION_CLOSED:
2177     /* destroy session? */
2178     break;
2179   case CKR_DEVICE_REMOVED:
2180     /* (void)nssCKFWToken_Destroy(fwToken); */
2181     break;
2182   case CKR_CRYPTOKI_NOT_INITIALIZED:
2183   case CKR_DEVICE_ERROR:
2184   case CKR_DEVICE_MEMORY:
2185   case CKR_FUNCTION_FAILED:
2186   case CKR_GENERAL_ERROR:
2187   case CKR_HOST_MEMORY:
2188   case CKR_OBJECT_HANDLE_INVALID:
2189   case CKR_SESSION_HANDLE_INVALID:
2190   case CKR_SESSION_READ_ONLY:
2191   case CKR_TOKEN_WRITE_PROTECTED:
2192     break;
2193   default:
2194   case CKR_OK:
2195     error = CKR_GENERAL_ERROR;
2196     break;
2197   }
2198
2199   return error;
2200 }
2201
2202 /*
2203  * NSSCKFWC_GetObjectSize
2204  *
2205  */
2206 NSS_IMPLEMENT CK_RV
2207 NSSCKFWC_GetObjectSize
2208 (
2209   NSSCKFWInstance *fwInstance,
2210   CK_SESSION_HANDLE hSession,
2211   CK_OBJECT_HANDLE hObject,
2212   CK_ULONG_PTR pulSize
2213 )
2214 {
2215   CK_RV error = CKR_OK;
2216   NSSCKFWSession *fwSession;
2217   NSSCKFWObject *fwObject;
2218
2219   if (!fwInstance) {
2220     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2221     goto loser;
2222   }
2223   
2224   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2225   if (!fwSession) {
2226     error = CKR_SESSION_HANDLE_INVALID;
2227     goto loser;
2228   }
2229
2230   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
2231   if (!fwObject) {
2232     error = CKR_OBJECT_HANDLE_INVALID;
2233     goto loser;
2234   }
2235
2236   if( (CK_ULONG_PTR)CK_NULL_PTR == pulSize ) {
2237     error = CKR_ARGUMENTS_BAD;
2238     goto loser;
2239   }
2240
2241   /*
2242    * A purify error here indicates caller error.
2243    */
2244   *pulSize = (CK_ULONG)0;
2245
2246   *pulSize = nssCKFWObject_GetObjectSize(fwObject, &error);
2247   if( ((CK_ULONG)0 == *pulSize) && (CKR_OK != error) ) {
2248     goto loser;
2249   }
2250
2251   return CKR_OK;
2252
2253  loser:
2254   switch( error ) {
2255   case CKR_SESSION_CLOSED:
2256     /* destroy session? */
2257     break;
2258   case CKR_DEVICE_REMOVED:
2259     /* (void)nssCKFWToken_Destroy(fwToken); */
2260     break;
2261   case CKR_CRYPTOKI_NOT_INITIALIZED:
2262   case CKR_DEVICE_ERROR:
2263   case CKR_DEVICE_MEMORY:
2264   case CKR_FUNCTION_FAILED:
2265   case CKR_GENERAL_ERROR:
2266   case CKR_HOST_MEMORY:
2267   case CKR_INFORMATION_SENSITIVE:
2268   case CKR_OBJECT_HANDLE_INVALID:
2269   case CKR_SESSION_HANDLE_INVALID:
2270     break;
2271   default:
2272   case CKR_OK:
2273     error = CKR_GENERAL_ERROR;
2274     break;
2275   }
2276
2277   return error;
2278 }
2279
2280 /*
2281  * NSSCKFWC_GetAttributeValue
2282  *
2283  */
2284 NSS_IMPLEMENT CK_RV
2285 NSSCKFWC_GetAttributeValue
2286 (
2287   NSSCKFWInstance *fwInstance,
2288   CK_SESSION_HANDLE hSession,
2289   CK_OBJECT_HANDLE hObject,
2290   CK_ATTRIBUTE_PTR pTemplate,
2291   CK_ULONG ulCount
2292 )
2293 {
2294   CK_RV error = CKR_OK;
2295   NSSCKFWSession *fwSession;
2296   NSSCKFWObject *fwObject;
2297   CK_BBOOL sensitive = CK_FALSE;
2298   CK_BBOOL invalid = CK_FALSE;
2299   CK_BBOOL tooSmall = CK_FALSE;
2300   CK_ULONG i;
2301
2302   if (!fwInstance) {
2303     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2304     goto loser;
2305   }
2306   
2307   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2308   if (!fwSession) {
2309     error = CKR_SESSION_HANDLE_INVALID;
2310     goto loser;
2311   }
2312
2313   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
2314   if (!fwObject) {
2315     error = CKR_OBJECT_HANDLE_INVALID;
2316     goto loser;
2317   }
2318
2319   if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
2320     error = CKR_ARGUMENTS_BAD;
2321     goto loser;
2322   }
2323
2324   for( i = 0; i < ulCount; i++ ) {
2325     CK_ULONG size = nssCKFWObject_GetAttributeSize(fwObject, 
2326                       pTemplate[i].type, &error);
2327     if( (CK_ULONG)0 == size ) {
2328       switch( error ) {
2329       case CKR_ATTRIBUTE_SENSITIVE:
2330       case CKR_INFORMATION_SENSITIVE:
2331         sensitive = CK_TRUE;
2332         pTemplate[i].ulValueLen = (CK_ULONG)(-1);
2333         continue;
2334       case CKR_ATTRIBUTE_TYPE_INVALID:
2335         invalid = CK_TRUE;
2336         pTemplate[i].ulValueLen = (CK_ULONG)(-1);
2337         continue;
2338       case CKR_OK:
2339         break;
2340       default:
2341         goto loser;
2342       }
2343     }
2344
2345     if( (CK_VOID_PTR)CK_NULL_PTR == pTemplate[i].pValue ) {
2346       pTemplate[i].ulValueLen = size;
2347     } else {
2348       NSSItem it, *p;
2349
2350       if( pTemplate[i].ulValueLen < size ) {
2351         tooSmall = CK_TRUE;
2352         continue;
2353       }
2354
2355       it.size = (PRUint32)pTemplate[i].ulValueLen;
2356       it.data = (void *)pTemplate[i].pValue;
2357       p = nssCKFWObject_GetAttribute(fwObject, pTemplate[i].type, &it, 
2358             (NSSArena *)NULL, &error);
2359       if (!p) {
2360         switch( error ) {
2361         case CKR_ATTRIBUTE_SENSITIVE:
2362         case CKR_INFORMATION_SENSITIVE:
2363           sensitive = CK_TRUE;
2364           pTemplate[i].ulValueLen = (CK_ULONG)(-1);
2365           continue;
2366         case CKR_ATTRIBUTE_TYPE_INVALID:
2367           invalid = CK_TRUE;
2368           pTemplate[i].ulValueLen = (CK_ULONG)(-1);
2369           continue;
2370         default:
2371           goto loser;
2372         }
2373       }
2374
2375       pTemplate[i].ulValueLen = size;
2376     }
2377   }
2378
2379   if( sensitive ) {
2380     error = CKR_ATTRIBUTE_SENSITIVE;
2381     goto loser;
2382   } else if( invalid ) {
2383     error = CKR_ATTRIBUTE_TYPE_INVALID;
2384     goto loser;
2385   } else if( tooSmall ) {
2386     error = CKR_BUFFER_TOO_SMALL;
2387     goto loser;
2388   }
2389
2390   return CKR_OK;
2391
2392  loser:
2393   switch( error ) {
2394   case CKR_SESSION_CLOSED:
2395     /* destroy session? */
2396     break;
2397   case CKR_DEVICE_REMOVED:
2398     /* (void)nssCKFWToken_Destroy(fwToken); */
2399     break;
2400   case CKR_ATTRIBUTE_SENSITIVE:
2401   case CKR_ATTRIBUTE_TYPE_INVALID:
2402   case CKR_BUFFER_TOO_SMALL:
2403   case CKR_CRYPTOKI_NOT_INITIALIZED:
2404   case CKR_DEVICE_ERROR:
2405   case CKR_DEVICE_MEMORY:
2406   case CKR_FUNCTION_FAILED:
2407   case CKR_GENERAL_ERROR:
2408   case CKR_HOST_MEMORY:
2409   case CKR_OBJECT_HANDLE_INVALID:
2410   case CKR_SESSION_HANDLE_INVALID:
2411     break;
2412   default:
2413   case CKR_OK:
2414     error = CKR_GENERAL_ERROR;
2415     break;
2416   }
2417
2418   return error;
2419 }
2420   
2421 /*
2422  * NSSCKFWC_SetAttributeValue
2423  *
2424  */
2425 NSS_IMPLEMENT CK_RV
2426 NSSCKFWC_SetAttributeValue
2427 (
2428   NSSCKFWInstance *fwInstance,
2429   CK_SESSION_HANDLE hSession,
2430   CK_OBJECT_HANDLE hObject,
2431   CK_ATTRIBUTE_PTR pTemplate,
2432   CK_ULONG ulCount
2433 )
2434 {
2435   CK_RV error = CKR_OK;
2436   NSSCKFWSession *fwSession;
2437   NSSCKFWObject *fwObject;
2438   CK_ULONG i;
2439
2440   if (!fwInstance) {
2441     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2442     goto loser;
2443   }
2444   
2445   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2446   if (!fwSession) {
2447     error = CKR_SESSION_HANDLE_INVALID;
2448     goto loser;
2449   }
2450
2451   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
2452   if (!fwObject) {
2453     error = CKR_OBJECT_HANDLE_INVALID;
2454     goto loser;
2455   }
2456
2457   if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
2458     error = CKR_ARGUMENTS_BAD;
2459     goto loser;
2460   }
2461
2462   for (i=0; i < ulCount; i++) {
2463     NSSItem value;
2464
2465     value.data = pTemplate[i].pValue;
2466     value.size = pTemplate[i].ulValueLen;
2467
2468     error = nssCKFWObject_SetAttribute(fwObject, fwSession, 
2469                                        pTemplate[i].type, &value);
2470
2471     if( CKR_OK != error ) {
2472       goto loser;
2473     }
2474   }
2475
2476   return CKR_OK;
2477
2478  loser:
2479   switch( error ) {
2480   case CKR_SESSION_CLOSED:
2481     /* destroy session? */
2482     break;
2483   case CKR_DEVICE_REMOVED:
2484     /* (void)nssCKFWToken_Destroy(fwToken); */
2485     break;
2486   case CKR_ATTRIBUTE_READ_ONLY:
2487   case CKR_ATTRIBUTE_TYPE_INVALID:
2488   case CKR_ATTRIBUTE_VALUE_INVALID:
2489   case CKR_CRYPTOKI_NOT_INITIALIZED:
2490   case CKR_DEVICE_ERROR:
2491   case CKR_DEVICE_MEMORY:
2492   case CKR_FUNCTION_FAILED:
2493   case CKR_GENERAL_ERROR:
2494   case CKR_HOST_MEMORY:
2495   case CKR_OBJECT_HANDLE_INVALID:
2496   case CKR_SESSION_HANDLE_INVALID:
2497   case CKR_SESSION_READ_ONLY:
2498   case CKR_TEMPLATE_INCONSISTENT:
2499   case CKR_TOKEN_WRITE_PROTECTED:
2500     break;
2501   default:
2502   case CKR_OK:
2503     error = CKR_GENERAL_ERROR;
2504     break;
2505   }
2506
2507   return error;
2508 }
2509
2510 /*
2511  * NSSCKFWC_FindObjectsInit
2512  *
2513  */
2514 NSS_IMPLEMENT CK_RV
2515 NSSCKFWC_FindObjectsInit
2516 (
2517   NSSCKFWInstance *fwInstance,
2518   CK_SESSION_HANDLE hSession,
2519   CK_ATTRIBUTE_PTR pTemplate,
2520   CK_ULONG ulCount
2521 )
2522 {
2523   CK_RV error = CKR_OK;
2524   NSSCKFWSession *fwSession;
2525   NSSCKFWFindObjects *fwFindObjects;
2526
2527   if (!fwInstance) {
2528     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2529     goto loser;
2530   }
2531   
2532   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2533   if (!fwSession) {
2534     error = CKR_SESSION_HANDLE_INVALID;
2535     goto loser;
2536   }
2537
2538   if( ((CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate) && (ulCount != 0) ) {
2539     error = CKR_ARGUMENTS_BAD;
2540     goto loser;
2541   }
2542
2543   fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
2544   if (fwFindObjects) {
2545     error = CKR_OPERATION_ACTIVE;
2546     goto loser;
2547   }
2548
2549   if( CKR_OPERATION_NOT_INITIALIZED != error ) {
2550     goto loser;
2551   }
2552
2553   fwFindObjects = nssCKFWSession_FindObjectsInit(fwSession,
2554                     pTemplate, ulCount, &error);
2555   if (!fwFindObjects) {
2556     goto loser;
2557   }
2558
2559   error = nssCKFWSession_SetFWFindObjects(fwSession, fwFindObjects);
2560
2561   if( CKR_OK != error ) {
2562     nssCKFWFindObjects_Destroy(fwFindObjects);
2563     goto loser;
2564   }
2565
2566   return CKR_OK;
2567
2568  loser:
2569   switch( error ) {
2570   case CKR_SESSION_CLOSED:
2571     /* destroy session? */
2572     break;
2573   case CKR_DEVICE_REMOVED:
2574     /* (void)nssCKFWToken_Destroy(fwToken); */
2575     break;
2576   case CKR_ATTRIBUTE_TYPE_INVALID:
2577   case CKR_ATTRIBUTE_VALUE_INVALID:
2578   case CKR_CRYPTOKI_NOT_INITIALIZED:
2579   case CKR_DEVICE_ERROR:
2580   case CKR_DEVICE_MEMORY:
2581   case CKR_FUNCTION_FAILED:
2582   case CKR_GENERAL_ERROR:
2583   case CKR_HOST_MEMORY:
2584   case CKR_OPERATION_ACTIVE:
2585   case CKR_SESSION_HANDLE_INVALID:
2586     break;
2587   default:
2588   case CKR_OK:
2589     error = CKR_GENERAL_ERROR;
2590     break;
2591   }
2592
2593   return error;
2594 }
2595
2596 /*
2597  * NSSCKFWC_FindObjects
2598  *
2599  */
2600 NSS_IMPLEMENT CK_RV
2601 NSSCKFWC_FindObjects
2602 (
2603   NSSCKFWInstance *fwInstance,
2604   CK_SESSION_HANDLE hSession,
2605   CK_OBJECT_HANDLE_PTR phObject,
2606   CK_ULONG ulMaxObjectCount,
2607   CK_ULONG_PTR pulObjectCount
2608 )
2609 {
2610   CK_RV error = CKR_OK;
2611   NSSCKFWSession *fwSession;
2612   NSSCKFWFindObjects *fwFindObjects;
2613   CK_ULONG i;
2614
2615   if (!fwInstance) {
2616     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2617     goto loser;
2618   }
2619   
2620   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2621   if (!fwSession) {
2622     error = CKR_SESSION_HANDLE_INVALID;
2623     goto loser;
2624   }
2625
2626   if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
2627     error = CKR_ARGUMENTS_BAD;
2628     goto loser;
2629   }
2630
2631   /*
2632    * A purify error here indicates caller error.
2633    */
2634   (void)nsslibc_memset(phObject, 0, sizeof(CK_OBJECT_HANDLE) * ulMaxObjectCount);
2635   *pulObjectCount = (CK_ULONG)0;
2636
2637   fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
2638   if (!fwFindObjects) {
2639     goto loser;
2640   }
2641
2642   for( i = 0; i < ulMaxObjectCount; i++ ) {
2643     NSSCKFWObject *fwObject = nssCKFWFindObjects_Next(fwFindObjects,
2644                                 NULL, &error);
2645     if (!fwObject) {
2646       break;
2647     }
2648
2649     phObject[i] = nssCKFWInstance_FindObjectHandle(fwInstance, fwObject);
2650     if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
2651       phObject[i] = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
2652     }
2653     if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
2654       /* This isn't right either, is it? */
2655       nssCKFWObject_Destroy(fwObject);
2656       goto loser;
2657     }
2658   }
2659
2660   *pulObjectCount = i;
2661
2662   return CKR_OK;
2663
2664  loser:
2665   switch( error ) {
2666   case CKR_SESSION_CLOSED:
2667     /* destroy session? */
2668     break;
2669   case CKR_DEVICE_REMOVED:
2670     /* (void)nssCKFWToken_Destroy(fwToken); */
2671     break;
2672   case CKR_CRYPTOKI_NOT_INITIALIZED:
2673   case CKR_DEVICE_ERROR:
2674   case CKR_DEVICE_MEMORY:
2675   case CKR_FUNCTION_FAILED:
2676   case CKR_GENERAL_ERROR:
2677   case CKR_HOST_MEMORY:
2678   case CKR_OPERATION_NOT_INITIALIZED:
2679   case CKR_SESSION_HANDLE_INVALID:
2680     break;
2681   default:
2682   case CKR_OK:
2683     error = CKR_GENERAL_ERROR;
2684     break;
2685   }
2686
2687   return error;
2688 }
2689
2690 /*
2691  * NSSCKFWC_FindObjectsFinal
2692  *
2693  */
2694 NSS_IMPLEMENT CK_RV
2695 NSSCKFWC_FindObjectsFinal
2696 (
2697   NSSCKFWInstance *fwInstance,
2698   CK_SESSION_HANDLE hSession
2699 )
2700 {
2701   CK_RV error = CKR_OK;
2702   NSSCKFWSession *fwSession;
2703   NSSCKFWFindObjects *fwFindObjects;
2704   
2705   if (!fwInstance) {
2706     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2707     goto loser;
2708   }
2709   
2710   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2711   if (!fwSession) {
2712     error = CKR_SESSION_HANDLE_INVALID;
2713     goto loser;
2714   }
2715
2716   fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
2717   if (!fwFindObjects) {
2718     error = CKR_OPERATION_NOT_INITIALIZED;
2719     goto loser;
2720   }
2721
2722   nssCKFWFindObjects_Destroy(fwFindObjects);
2723   error = nssCKFWSession_SetFWFindObjects(fwSession, 
2724                                           (NSSCKFWFindObjects *)NULL);
2725
2726   if( CKR_OK != error ) {
2727     goto loser;
2728   }
2729
2730   return CKR_OK;
2731
2732  loser:
2733   switch( error ) {
2734   case CKR_SESSION_CLOSED:
2735     /* destroy session? */
2736     break;
2737   case CKR_DEVICE_REMOVED:
2738     /* (void)nssCKFWToken_Destroy(fwToken); */
2739     break;
2740   case CKR_CRYPTOKI_NOT_INITIALIZED:
2741   case CKR_DEVICE_ERROR:
2742   case CKR_DEVICE_MEMORY:
2743   case CKR_FUNCTION_FAILED:
2744   case CKR_GENERAL_ERROR:
2745   case CKR_HOST_MEMORY:
2746   case CKR_OPERATION_NOT_INITIALIZED:
2747   case CKR_SESSION_HANDLE_INVALID:
2748     break;
2749   default:
2750   case CKR_OK:
2751     error = CKR_GENERAL_ERROR;
2752     break;
2753   }
2754
2755   return error;
2756 }
2757
2758 /*
2759  * NSSCKFWC_EncryptInit
2760  *
2761  */
2762 NSS_IMPLEMENT CK_RV
2763 NSSCKFWC_EncryptInit
2764 (
2765   NSSCKFWInstance *fwInstance,
2766   CK_SESSION_HANDLE hSession,
2767   CK_MECHANISM_PTR pMechanism,
2768   CK_OBJECT_HANDLE hKey
2769 )
2770 {
2771   CK_RV error = CKR_OK;
2772   NSSCKFWSession *fwSession;
2773   NSSCKFWObject *fwObject;
2774   NSSCKFWSlot  *fwSlot;
2775   NSSCKFWToken  *fwToken;
2776   NSSCKFWMechanism *fwMechanism;
2777
2778   if (!fwInstance) {
2779     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2780     goto loser;
2781   }
2782   
2783   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2784   if (!fwSession) {
2785     error = CKR_SESSION_HANDLE_INVALID;
2786     goto loser;
2787   }
2788
2789   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
2790   if (!fwObject) {
2791     error = CKR_KEY_HANDLE_INVALID;
2792     goto loser;
2793   }
2794
2795   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
2796   if (!fwSlot) {
2797     error = CKR_GENERAL_ERROR; /* should never happen! */
2798     goto loser;
2799   }
2800
2801   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
2802     error = CKR_TOKEN_NOT_PRESENT;
2803     goto loser;
2804   }
2805
2806   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
2807   if (!fwToken) {
2808     goto loser;
2809   }
2810
2811   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
2812   if (!fwMechanism) {
2813     goto loser;
2814   }
2815
2816   error = nssCKFWMechanism_EncryptInit(fwMechanism, pMechanism,
2817                                         fwSession, fwObject);
2818
2819   nssCKFWMechanism_Destroy(fwMechanism);
2820
2821   if (CKR_OK == error) {
2822     return CKR_OK;
2823   }
2824
2825 loser:
2826   /* verify error */
2827   switch( error ) {
2828   case CKR_CRYPTOKI_NOT_INITIALIZED:
2829   case CKR_DEVICE_ERROR:
2830   case CKR_DEVICE_MEMORY:
2831   case CKR_DEVICE_REMOVED:
2832   case CKR_FUNCTION_CANCELED:
2833   case CKR_FUNCTION_FAILED:
2834   case CKR_GENERAL_ERROR:
2835   case CKR_HOST_MEMORY:
2836   case CKR_KEY_FUNCTION_NOT_PERMITTED:
2837   case CKR_KEY_HANDLE_INVALID:
2838   case CKR_KEY_SIZE_RANGE:
2839   case CKR_KEY_TYPE_INCONSISTENT:
2840   case CKR_MECHANISM_INVALID:
2841   case CKR_MECHANISM_PARAM_INVALID:
2842   case CKR_OPERATION_ACTIVE:
2843   case CKR_PIN_EXPIRED:
2844   case CKR_SESSION_CLOSED:
2845   case CKR_SESSION_HANDLE_INVALID:
2846   case CKR_USER_NOT_LOGGED_IN:
2847     break;
2848   default:
2849   case CKR_OK:
2850     error = CKR_GENERAL_ERROR;
2851     break;
2852   }
2853   return error;
2854 }
2855
2856 /*
2857  * NSSCKFWC_Encrypt
2858  *
2859  */
2860 NSS_IMPLEMENT CK_RV
2861 NSSCKFWC_Encrypt
2862 (
2863   NSSCKFWInstance *fwInstance,
2864   CK_SESSION_HANDLE hSession,
2865   CK_BYTE_PTR pData,
2866   CK_ULONG ulDataLen,
2867   CK_BYTE_PTR pEncryptedData,
2868   CK_ULONG_PTR pulEncryptedDataLen
2869 )
2870 {
2871   CK_RV error = CKR_OK;
2872   NSSCKFWSession *fwSession;
2873
2874   if (!fwInstance) {
2875     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2876     goto loser;
2877   }
2878   
2879   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2880   if (!fwSession) {
2881     error = CKR_SESSION_HANDLE_INVALID;
2882     goto loser;
2883   }
2884
2885   error = nssCKFWSession_UpdateFinal(fwSession,
2886            NSSCKFWCryptoOperationType_Encrypt, 
2887            NSSCKFWCryptoOperationState_EncryptDecrypt,
2888            pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
2889
2890   if (CKR_OK == error) {
2891     return CKR_OK;
2892   }
2893
2894 loser:
2895   /* verify error */
2896   switch( error ) {
2897   case CKR_ARGUMENTS_BAD:
2898   case CKR_BUFFER_TOO_SMALL:
2899   case CKR_CRYPTOKI_NOT_INITIALIZED:
2900   case CKR_DATA_INVALID:
2901   case CKR_DATA_LEN_RANGE:
2902   case CKR_DEVICE_ERROR:
2903   case CKR_DEVICE_MEMORY:
2904   case CKR_DEVICE_REMOVED:
2905   case CKR_FUNCTION_CANCELED:
2906   case CKR_FUNCTION_FAILED:
2907   case CKR_GENERAL_ERROR:
2908   case CKR_HOST_MEMORY:
2909   case CKR_OPERATION_NOT_INITIALIZED:
2910   case CKR_SESSION_HANDLE_INVALID:
2911   case CKR_SESSION_CLOSED:
2912     break;
2913   default:
2914   case CKR_OK:
2915     error = CKR_GENERAL_ERROR;
2916     break;
2917   }
2918   return error;
2919 }
2920
2921 /*
2922  * NSSCKFWC_EncryptUpdate
2923  *
2924  */
2925 NSS_IMPLEMENT CK_RV
2926 NSSCKFWC_EncryptUpdate
2927 (
2928   NSSCKFWInstance *fwInstance,
2929   CK_SESSION_HANDLE hSession,
2930   CK_BYTE_PTR pPart,
2931   CK_ULONG ulPartLen,
2932   CK_BYTE_PTR pEncryptedPart,
2933   CK_ULONG_PTR pulEncryptedPartLen
2934 )
2935 {
2936   CK_RV error = CKR_OK;
2937   NSSCKFWSession *fwSession;
2938
2939   if (!fwInstance) {
2940     error = CKR_CRYPTOKI_NOT_INITIALIZED;
2941     goto loser;
2942   }
2943   
2944   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
2945   if (!fwSession) {
2946     error = CKR_SESSION_HANDLE_INVALID;
2947     goto loser;
2948   }
2949
2950   error = nssCKFWSession_Update(fwSession,
2951            NSSCKFWCryptoOperationType_Encrypt, 
2952            NSSCKFWCryptoOperationState_EncryptDecrypt,
2953            pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
2954
2955   if (CKR_OK == error) {
2956     return CKR_OK;
2957   }
2958
2959 loser:
2960   /* verify error */
2961   switch( error ) {
2962   case CKR_ARGUMENTS_BAD:
2963   case CKR_BUFFER_TOO_SMALL:
2964   case CKR_CRYPTOKI_NOT_INITIALIZED:
2965   case CKR_DATA_LEN_RANGE:
2966   case CKR_DEVICE_ERROR:
2967   case CKR_DEVICE_MEMORY:
2968   case CKR_DEVICE_REMOVED:
2969   case CKR_FUNCTION_CANCELED:
2970   case CKR_FUNCTION_FAILED:
2971   case CKR_GENERAL_ERROR:
2972   case CKR_HOST_MEMORY:
2973   case CKR_OPERATION_NOT_INITIALIZED:
2974   case CKR_SESSION_CLOSED:
2975   case CKR_SESSION_HANDLE_INVALID:
2976     break;
2977   default:
2978   case CKR_OK:
2979     error = CKR_GENERAL_ERROR;
2980     break;
2981   }
2982   return error;
2983 }
2984
2985 /*
2986  * NSSCKFWC_EncryptFinal
2987  *
2988  */
2989 NSS_IMPLEMENT CK_RV
2990 NSSCKFWC_EncryptFinal
2991 (
2992   NSSCKFWInstance *fwInstance,
2993   CK_SESSION_HANDLE hSession,
2994   CK_BYTE_PTR pLastEncryptedPart,
2995   CK_ULONG_PTR pulLastEncryptedPartLen
2996 )
2997 {
2998   CK_RV error = CKR_OK;
2999   NSSCKFWSession *fwSession;
3000
3001   if (!fwInstance) {
3002     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3003     goto loser;
3004   }
3005   
3006   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3007   if (!fwSession) {
3008     error = CKR_SESSION_HANDLE_INVALID;
3009     goto loser;
3010   }
3011
3012   error = nssCKFWSession_Final(fwSession,
3013            NSSCKFWCryptoOperationType_Encrypt, 
3014            NSSCKFWCryptoOperationState_EncryptDecrypt,
3015            pLastEncryptedPart, pulLastEncryptedPartLen);
3016
3017   if (CKR_OK == error) {
3018     return CKR_OK;
3019   }
3020
3021 loser:
3022   /* verify error */
3023   switch( error ) {
3024   case CKR_ARGUMENTS_BAD:
3025   case CKR_BUFFER_TOO_SMALL:
3026   case CKR_CRYPTOKI_NOT_INITIALIZED:
3027   case CKR_DATA_LEN_RANGE:
3028   case CKR_DEVICE_ERROR:
3029   case CKR_DEVICE_MEMORY:
3030   case CKR_DEVICE_REMOVED:
3031   case CKR_FUNCTION_CANCELED:
3032   case CKR_FUNCTION_FAILED:
3033   case CKR_GENERAL_ERROR:
3034   case CKR_HOST_MEMORY:
3035   case CKR_OPERATION_NOT_INITIALIZED:
3036   case CKR_SESSION_CLOSED:
3037   case CKR_SESSION_HANDLE_INVALID:
3038     break;
3039   default:
3040   case CKR_OK:
3041     error = CKR_GENERAL_ERROR;
3042     break;
3043   }
3044   return error;
3045 }
3046
3047 /*
3048  * NSSCKFWC_DecryptInit
3049  *
3050  */
3051 NSS_IMPLEMENT CK_RV
3052 NSSCKFWC_DecryptInit
3053 (
3054   NSSCKFWInstance *fwInstance,
3055   CK_SESSION_HANDLE hSession,
3056   CK_MECHANISM_PTR pMechanism,
3057   CK_OBJECT_HANDLE hKey
3058 )
3059 {
3060   CK_RV error = CKR_OK;
3061   NSSCKFWSession *fwSession;
3062   NSSCKFWObject *fwObject;
3063   NSSCKFWSlot  *fwSlot;
3064   NSSCKFWToken  *fwToken;
3065   NSSCKFWMechanism *fwMechanism;
3066
3067   if (!fwInstance) {
3068     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3069     goto loser;
3070   }
3071   
3072   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3073   if (!fwSession) {
3074     error = CKR_SESSION_HANDLE_INVALID;
3075     goto loser;
3076   }
3077
3078   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
3079   if (!fwObject) {
3080     error = CKR_KEY_HANDLE_INVALID;
3081     goto loser;
3082   }
3083
3084   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
3085   if (!fwSlot) {
3086     error = CKR_GENERAL_ERROR; /* should never happen! */
3087     goto loser;
3088   }
3089
3090   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
3091     error = CKR_TOKEN_NOT_PRESENT;
3092     goto loser;
3093   }
3094
3095   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
3096   if (!fwToken) {
3097     goto loser;
3098   }
3099
3100   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
3101   if (!fwMechanism) {
3102     goto loser;
3103   }
3104
3105   error = nssCKFWMechanism_DecryptInit(fwMechanism, pMechanism, 
3106                                        fwSession, fwObject);
3107   nssCKFWMechanism_Destroy(fwMechanism);
3108
3109   if (CKR_OK == error) {
3110     return CKR_OK;
3111   }
3112
3113 loser:
3114   /* verify error */
3115   switch( error ) {
3116   case CKR_ARGUMENTS_BAD:
3117   case CKR_CRYPTOKI_NOT_INITIALIZED:
3118   case CKR_DEVICE_ERROR:
3119   case CKR_DEVICE_MEMORY:
3120   case CKR_DEVICE_REMOVED:
3121   case CKR_FUNCTION_CANCELED:
3122   case CKR_FUNCTION_FAILED:
3123   case CKR_GENERAL_ERROR:
3124   case CKR_HOST_MEMORY:
3125   case CKR_KEY_FUNCTION_NOT_PERMITTED:
3126   case CKR_KEY_HANDLE_INVALID:
3127   case CKR_KEY_SIZE_RANGE:
3128   case CKR_KEY_TYPE_INCONSISTENT:
3129   case CKR_MECHANISM_INVALID:
3130   case CKR_MECHANISM_PARAM_INVALID:
3131   case CKR_OPERATION_ACTIVE:
3132   case CKR_PIN_EXPIRED:
3133   case CKR_SESSION_CLOSED:
3134   case CKR_SESSION_HANDLE_INVALID:
3135   case CKR_USER_NOT_LOGGED_IN:
3136     break;
3137   default:
3138   case CKR_OK:
3139     error = CKR_GENERAL_ERROR;
3140     break;
3141   }
3142   return error;
3143 }
3144
3145 /*
3146  * NSSCKFWC_Decrypt
3147  *
3148  */
3149 NSS_IMPLEMENT CK_RV
3150 NSSCKFWC_Decrypt
3151 (
3152   NSSCKFWInstance *fwInstance,
3153   CK_SESSION_HANDLE hSession,
3154   CK_BYTE_PTR pEncryptedData,
3155   CK_ULONG ulEncryptedDataLen,
3156   CK_BYTE_PTR pData,
3157   CK_ULONG_PTR pulDataLen
3158 )
3159 {
3160   CK_RV error = CKR_OK;
3161   NSSCKFWSession *fwSession;
3162
3163   if (!fwInstance) {
3164     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3165     goto loser;
3166   }
3167   
3168   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3169   if (!fwSession) {
3170     error = CKR_SESSION_HANDLE_INVALID;
3171     goto loser;
3172   }
3173
3174   error = nssCKFWSession_UpdateFinal(fwSession,
3175            NSSCKFWCryptoOperationType_Decrypt, 
3176            NSSCKFWCryptoOperationState_EncryptDecrypt,
3177            pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
3178
3179   if (CKR_OK == error) {
3180     return CKR_OK;
3181   }
3182
3183 loser:
3184   /* verify error */
3185   switch( error ) {
3186   case CKR_ARGUMENTS_BAD:
3187   case CKR_BUFFER_TOO_SMALL:
3188   case CKR_CRYPTOKI_NOT_INITIALIZED:
3189   case CKR_DEVICE_ERROR:
3190   case CKR_DEVICE_MEMORY:
3191   case CKR_DEVICE_REMOVED:
3192   case CKR_ENCRYPTED_DATA_INVALID:
3193   case CKR_ENCRYPTED_DATA_LEN_RANGE:
3194   case CKR_FUNCTION_CANCELED:
3195   case CKR_FUNCTION_FAILED:
3196   case CKR_GENERAL_ERROR:
3197   case CKR_HOST_MEMORY:
3198   case CKR_OPERATION_NOT_INITIALIZED:
3199   case CKR_SESSION_CLOSED:
3200   case CKR_SESSION_HANDLE_INVALID:
3201   case CKR_USER_NOT_LOGGED_IN:
3202     break;
3203   case CKR_DATA_LEN_RANGE:
3204     error = CKR_ENCRYPTED_DATA_LEN_RANGE;
3205     break;
3206   case CKR_DATA_INVALID:
3207     error = CKR_ENCRYPTED_DATA_INVALID;
3208     break;
3209   default:
3210   case CKR_OK:
3211     error = CKR_GENERAL_ERROR;
3212     break;
3213   }
3214   return error;
3215 }
3216
3217 /*
3218  * NSSCKFWC_DecryptUpdate
3219  *
3220  */
3221 NSS_IMPLEMENT CK_RV
3222 NSSCKFWC_DecryptUpdate
3223 (
3224   NSSCKFWInstance *fwInstance,
3225   CK_SESSION_HANDLE hSession,
3226   CK_BYTE_PTR pEncryptedPart,
3227   CK_ULONG ulEncryptedPartLen,
3228   CK_BYTE_PTR pPart,
3229   CK_ULONG_PTR pulPartLen
3230 )
3231 {
3232   CK_RV error = CKR_OK;
3233   NSSCKFWSession *fwSession;
3234
3235   if (!fwInstance) {
3236     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3237     goto loser;
3238   }
3239   
3240   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3241   if (!fwSession) {
3242     error = CKR_SESSION_HANDLE_INVALID;
3243     goto loser;
3244   }
3245
3246   error = nssCKFWSession_Update(fwSession,
3247            NSSCKFWCryptoOperationType_Decrypt, 
3248            NSSCKFWCryptoOperationState_EncryptDecrypt,
3249            pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
3250
3251   if (CKR_OK == error) {
3252     return CKR_OK;
3253   }
3254
3255 loser:
3256   /* verify error */
3257   switch( error ) {
3258   case CKR_ARGUMENTS_BAD:
3259   case CKR_BUFFER_TOO_SMALL:
3260   case CKR_CRYPTOKI_NOT_INITIALIZED:
3261   case CKR_DEVICE_ERROR:
3262   case CKR_DEVICE_MEMORY:
3263   case CKR_DEVICE_REMOVED:
3264   case CKR_ENCRYPTED_DATA_INVALID:
3265   case CKR_ENCRYPTED_DATA_LEN_RANGE:
3266   case CKR_FUNCTION_CANCELED:
3267   case CKR_FUNCTION_FAILED:
3268   case CKR_GENERAL_ERROR:
3269   case CKR_HOST_MEMORY:
3270   case CKR_OPERATION_NOT_INITIALIZED:
3271   case CKR_SESSION_CLOSED:
3272   case CKR_SESSION_HANDLE_INVALID:
3273   case CKR_USER_NOT_LOGGED_IN:
3274     break;
3275   case CKR_DATA_LEN_RANGE:
3276     error = CKR_ENCRYPTED_DATA_LEN_RANGE;
3277     break;
3278   case CKR_DATA_INVALID:
3279     error = CKR_ENCRYPTED_DATA_INVALID;
3280     break;
3281   default:
3282   case CKR_OK:
3283     error = CKR_GENERAL_ERROR;
3284     break;
3285   }
3286   return error;
3287 }
3288
3289 /*
3290  * NSSCKFWC_DecryptFinal
3291  *
3292  */
3293 NSS_IMPLEMENT CK_RV
3294 NSSCKFWC_DecryptFinal
3295 (
3296   NSSCKFWInstance *fwInstance,
3297   CK_SESSION_HANDLE hSession,
3298   CK_BYTE_PTR pLastPart,
3299   CK_ULONG_PTR pulLastPartLen
3300 )
3301 {
3302   CK_RV error = CKR_OK;
3303   NSSCKFWSession *fwSession;
3304
3305   if (!fwInstance) {
3306     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3307     goto loser;
3308   }
3309   
3310   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3311   if (!fwSession) {
3312     error = CKR_SESSION_HANDLE_INVALID;
3313     goto loser;
3314   }
3315
3316   error = nssCKFWSession_Final(fwSession,
3317            NSSCKFWCryptoOperationType_Decrypt, 
3318            NSSCKFWCryptoOperationState_EncryptDecrypt,
3319            pLastPart, pulLastPartLen);
3320
3321   if (CKR_OK == error) {
3322     return CKR_OK;
3323   }
3324
3325 loser:
3326   /* verify error */
3327   switch( error ) {
3328   case CKR_ARGUMENTS_BAD:
3329   case CKR_BUFFER_TOO_SMALL:
3330   case CKR_CRYPTOKI_NOT_INITIALIZED:
3331   case CKR_DEVICE_ERROR:
3332   case CKR_DEVICE_MEMORY:
3333   case CKR_DEVICE_REMOVED:
3334   case CKR_FUNCTION_FAILED:
3335   case CKR_FUNCTION_CANCELED:
3336   case CKR_ENCRYPTED_DATA_INVALID:
3337   case CKR_ENCRYPTED_DATA_LEN_RANGE:
3338   case CKR_GENERAL_ERROR:
3339   case CKR_HOST_MEMORY:
3340   case CKR_OPERATION_NOT_INITIALIZED:
3341   case CKR_SESSION_CLOSED:
3342   case CKR_SESSION_HANDLE_INVALID:
3343   case CKR_USER_NOT_LOGGED_IN:
3344     break;
3345   case CKR_DATA_LEN_RANGE:
3346     error = CKR_ENCRYPTED_DATA_LEN_RANGE;
3347     break;
3348   case CKR_DATA_INVALID:
3349     error = CKR_ENCRYPTED_DATA_INVALID;
3350     break;
3351   default:
3352   case CKR_OK:
3353     error = CKR_GENERAL_ERROR;
3354     break;
3355   }
3356   return error;
3357 }
3358
3359 /*
3360  * NSSCKFWC_DigestInit
3361  *
3362  */
3363 NSS_IMPLEMENT CK_RV
3364 NSSCKFWC_DigestInit
3365 (
3366   NSSCKFWInstance *fwInstance,
3367   CK_SESSION_HANDLE hSession,
3368   CK_MECHANISM_PTR pMechanism
3369 )
3370 {
3371   CK_RV error = CKR_OK;
3372   NSSCKFWSession *fwSession;
3373   NSSCKFWSlot  *fwSlot;
3374   NSSCKFWToken  *fwToken;
3375   NSSCKFWMechanism *fwMechanism;
3376
3377   if (!fwInstance) {
3378     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3379     goto loser;
3380   }
3381   
3382   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3383   if (!fwSession) {
3384     error = CKR_SESSION_HANDLE_INVALID;
3385     goto loser;
3386   }
3387
3388   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
3389   if (!fwSlot) {
3390     error = CKR_GENERAL_ERROR; /* should never happen! */
3391     goto loser;
3392   }
3393
3394   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
3395     error = CKR_TOKEN_NOT_PRESENT;
3396     goto loser;
3397   }
3398
3399   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
3400   if (!fwToken) {
3401     goto loser;
3402   }
3403
3404   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
3405   if (!fwMechanism) {
3406     goto loser;
3407   }
3408
3409   error = nssCKFWMechanism_DigestInit(fwMechanism, pMechanism, fwSession);
3410
3411   nssCKFWMechanism_Destroy(fwMechanism);
3412
3413   if (CKR_OK == error) {
3414     return CKR_OK;
3415   }
3416
3417 loser:
3418   /* verify error */
3419   switch( error ) {
3420   case CKR_ARGUMENTS_BAD:
3421   case CKR_CRYPTOKI_NOT_INITIALIZED:
3422   case CKR_DEVICE_ERROR:
3423   case CKR_DEVICE_MEMORY:
3424   case CKR_DEVICE_REMOVED:
3425   case CKR_FUNCTION_CANCELED:
3426   case CKR_FUNCTION_FAILED:
3427   case CKR_GENERAL_ERROR:
3428   case CKR_HOST_MEMORY:
3429   case CKR_MECHANISM_INVALID:
3430   case CKR_MECHANISM_PARAM_INVALID:
3431   case CKR_OPERATION_ACTIVE:
3432   case CKR_PIN_EXPIRED:
3433   case CKR_SESSION_CLOSED:
3434   case CKR_SESSION_HANDLE_INVALID:
3435   case CKR_USER_NOT_LOGGED_IN:
3436     break;
3437   default:
3438   case CKR_OK:
3439     error = CKR_GENERAL_ERROR;
3440     break;
3441   }
3442   return error;
3443 }
3444
3445 /*
3446  * NSSCKFWC_Digest
3447  *
3448  */
3449 NSS_IMPLEMENT CK_RV
3450 NSSCKFWC_Digest
3451 (
3452   NSSCKFWInstance *fwInstance,
3453   CK_SESSION_HANDLE hSession,
3454   CK_BYTE_PTR pData,
3455   CK_ULONG ulDataLen,
3456   CK_BYTE_PTR pDigest,
3457   CK_ULONG_PTR pulDigestLen
3458 )
3459 {
3460   CK_RV error = CKR_OK;
3461   NSSCKFWSession *fwSession;
3462
3463   if (!fwInstance) {
3464     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3465     goto loser;
3466   }
3467   
3468   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3469   if (!fwSession) {
3470     error = CKR_SESSION_HANDLE_INVALID;
3471     goto loser;
3472   }
3473
3474   error = nssCKFWSession_UpdateFinal(fwSession,
3475            NSSCKFWCryptoOperationType_Digest, 
3476            NSSCKFWCryptoOperationState_Digest,
3477            pData, ulDataLen, pDigest, pulDigestLen);
3478
3479   if (CKR_OK == error) {
3480     return CKR_OK;
3481   }
3482
3483 loser:
3484   /* verify error */
3485   switch( error ) {
3486   case CKR_ARGUMENTS_BAD:
3487   case CKR_BUFFER_TOO_SMALL:
3488   case CKR_CRYPTOKI_NOT_INITIALIZED:
3489   case CKR_DEVICE_ERROR:
3490   case CKR_DEVICE_MEMORY:
3491   case CKR_DEVICE_REMOVED:
3492   case CKR_FUNCTION_CANCELED:
3493   case CKR_FUNCTION_FAILED:
3494   case CKR_GENERAL_ERROR:
3495   case CKR_HOST_MEMORY:
3496   case CKR_OPERATION_NOT_INITIALIZED:
3497   case CKR_SESSION_CLOSED:
3498   case CKR_SESSION_HANDLE_INVALID:
3499     break;
3500   default:
3501   case CKR_OK:
3502     error = CKR_GENERAL_ERROR;
3503     break;
3504   }
3505   return error;
3506 }
3507
3508 /*
3509  * NSSCKFWC_DigestUpdate
3510  *
3511  */
3512 NSS_IMPLEMENT CK_RV
3513 NSSCKFWC_DigestUpdate
3514 (
3515   NSSCKFWInstance *fwInstance,
3516   CK_SESSION_HANDLE hSession,
3517   CK_BYTE_PTR pData,
3518   CK_ULONG ulDataLen
3519 )
3520 {
3521   CK_RV error = CKR_OK;
3522   NSSCKFWSession *fwSession;
3523
3524   if (!fwInstance) {
3525     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3526     goto loser;
3527   }
3528   
3529   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3530   if (!fwSession) {
3531     error = CKR_SESSION_HANDLE_INVALID;
3532     goto loser;
3533   }
3534
3535   error = nssCKFWSession_DigestUpdate(fwSession,
3536            NSSCKFWCryptoOperationType_Digest, 
3537            NSSCKFWCryptoOperationState_Digest,
3538            pData, ulDataLen);
3539
3540   if (CKR_OK == error) {
3541     return CKR_OK;
3542   }
3543
3544 loser:
3545   /* verify error */
3546   switch( error ) {
3547   case CKR_ARGUMENTS_BAD:
3548   case CKR_CRYPTOKI_NOT_INITIALIZED:
3549   case CKR_DEVICE_ERROR:
3550   case CKR_DEVICE_MEMORY:
3551   case CKR_DEVICE_REMOVED:
3552   case CKR_FUNCTION_CANCELED:
3553   case CKR_FUNCTION_FAILED:
3554   case CKR_GENERAL_ERROR:
3555   case CKR_HOST_MEMORY:
3556   case CKR_OPERATION_NOT_INITIALIZED:
3557   case CKR_SESSION_CLOSED:
3558   case CKR_SESSION_HANDLE_INVALID:
3559     break;
3560   default:
3561   case CKR_OK:
3562     error = CKR_GENERAL_ERROR;
3563     break;
3564   }
3565   return error;
3566 }
3567
3568 /*
3569  * NSSCKFWC_DigestKey
3570  *
3571  */
3572 NSS_IMPLEMENT CK_RV
3573 NSSCKFWC_DigestKey
3574 (
3575   NSSCKFWInstance *fwInstance,
3576   CK_SESSION_HANDLE hSession,
3577   CK_OBJECT_HANDLE hKey
3578 )
3579 {
3580   CK_RV error = CKR_OK;
3581   NSSCKFWSession *fwSession;
3582   NSSCKFWObject *fwObject;
3583
3584   if (!fwInstance) {
3585     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3586     goto loser;
3587   }
3588   
3589   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3590   if (!fwSession) {
3591     error = CKR_SESSION_HANDLE_INVALID;
3592     goto loser;
3593   }
3594
3595   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
3596   if (!fwObject) {
3597     error = CKR_KEY_HANDLE_INVALID;
3598     goto loser;
3599   }
3600
3601   error = nssCKFWSession_DigestKey(fwSession, fwObject);
3602
3603   if (CKR_OK == error) {
3604     return CKR_OK;
3605   }
3606
3607 loser:
3608   /* verify error */
3609   switch( error ) {
3610   case CKR_CRYPTOKI_NOT_INITIALIZED:
3611   case CKR_DEVICE_ERROR:
3612   case CKR_DEVICE_MEMORY:
3613   case CKR_DEVICE_REMOVED:
3614   case CKR_FUNCTION_CANCELED:
3615   case CKR_FUNCTION_FAILED:
3616   case CKR_GENERAL_ERROR:
3617   case CKR_HOST_MEMORY:
3618   case CKR_KEY_HANDLE_INVALID:
3619   case CKR_KEY_INDIGESTIBLE:
3620   case CKR_KEY_SIZE_RANGE:
3621   case CKR_OPERATION_NOT_INITIALIZED:
3622   case CKR_SESSION_CLOSED:
3623   case CKR_SESSION_HANDLE_INVALID:
3624     break;
3625   default:
3626   case CKR_OK:
3627     error = CKR_GENERAL_ERROR;
3628     break;
3629   }
3630   return error;
3631 }
3632
3633 /*
3634  * NSSCKFWC_DigestFinal
3635  *
3636  */
3637 NSS_IMPLEMENT CK_RV
3638 NSSCKFWC_DigestFinal
3639 (
3640   NSSCKFWInstance *fwInstance,
3641   CK_SESSION_HANDLE hSession,
3642   CK_BYTE_PTR pDigest,
3643   CK_ULONG_PTR pulDigestLen
3644 )
3645 {
3646   CK_RV error = CKR_OK;
3647   NSSCKFWSession *fwSession;
3648
3649   if (!fwInstance) {
3650     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3651     goto loser;
3652   }
3653   
3654   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3655   if (!fwSession) {
3656     error = CKR_SESSION_HANDLE_INVALID;
3657     goto loser;
3658   }
3659
3660   error = nssCKFWSession_Final(fwSession,
3661            NSSCKFWCryptoOperationType_Digest, 
3662            NSSCKFWCryptoOperationState_Digest,
3663            pDigest, pulDigestLen);
3664
3665   if (CKR_OK == error) {
3666     return CKR_OK;
3667   }
3668
3669 loser:
3670   /* verify error */
3671   switch( error ) {
3672   case CKR_ARGUMENTS_BAD:
3673   case CKR_BUFFER_TOO_SMALL:
3674   case CKR_CRYPTOKI_NOT_INITIALIZED:
3675   case CKR_DEVICE_ERROR:
3676   case CKR_DEVICE_MEMORY:
3677   case CKR_DEVICE_REMOVED:
3678   case CKR_FUNCTION_CANCELED:
3679   case CKR_FUNCTION_FAILED:
3680   case CKR_GENERAL_ERROR:
3681   case CKR_HOST_MEMORY:
3682   case CKR_OPERATION_NOT_INITIALIZED:
3683   case CKR_SESSION_CLOSED:
3684   case CKR_SESSION_HANDLE_INVALID:
3685     break;
3686   default:
3687   case CKR_OK:
3688     error = CKR_GENERAL_ERROR;
3689     break;
3690   }
3691   return error;
3692 }
3693
3694 /*
3695  * NSSCKFWC_SignInit
3696  *
3697  */
3698 NSS_IMPLEMENT CK_RV
3699 NSSCKFWC_SignInit
3700 (
3701   NSSCKFWInstance *fwInstance,
3702   CK_SESSION_HANDLE hSession,
3703   CK_MECHANISM_PTR pMechanism,
3704   CK_OBJECT_HANDLE hKey
3705 )
3706 {
3707   CK_RV error = CKR_OK;
3708   NSSCKFWSession *fwSession;
3709   NSSCKFWObject *fwObject;
3710   NSSCKFWSlot  *fwSlot;
3711   NSSCKFWToken  *fwToken;
3712   NSSCKFWMechanism *fwMechanism;
3713
3714   if (!fwInstance) {
3715     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3716     goto loser;
3717   }
3718   
3719   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3720   if (!fwSession) {
3721     error = CKR_SESSION_HANDLE_INVALID;
3722     goto loser;
3723   }
3724
3725   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
3726   if (!fwObject) {
3727     error = CKR_KEY_HANDLE_INVALID;
3728     goto loser;
3729   }
3730
3731   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
3732   if (!fwSlot) {
3733     error = CKR_GENERAL_ERROR; /* should never happen! */
3734     goto loser;
3735   }
3736
3737   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
3738     error = CKR_TOKEN_NOT_PRESENT;
3739     goto loser;
3740   }
3741
3742   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
3743   if (!fwToken) {
3744     goto loser;
3745   }
3746
3747   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
3748   if (!fwMechanism) {
3749     goto loser;
3750   }
3751
3752   error = nssCKFWMechanism_SignInit(fwMechanism, pMechanism, fwSession, 
3753                                     fwObject);
3754
3755   nssCKFWMechanism_Destroy(fwMechanism);
3756
3757   if (CKR_OK == error) {
3758     return CKR_OK;
3759   }
3760
3761 loser:
3762   /* verify error */
3763   switch( error ) {
3764   case CKR_ARGUMENTS_BAD:
3765   case CKR_CRYPTOKI_NOT_INITIALIZED:
3766   case CKR_DEVICE_ERROR:
3767   case CKR_DEVICE_MEMORY:
3768   case CKR_DEVICE_REMOVED:
3769   case CKR_FUNCTION_CANCELED:
3770   case CKR_FUNCTION_FAILED:
3771   case CKR_GENERAL_ERROR:
3772   case CKR_HOST_MEMORY:
3773   case CKR_KEY_FUNCTION_NOT_PERMITTED:
3774   case CKR_KEY_HANDLE_INVALID:
3775   case CKR_KEY_SIZE_RANGE:
3776   case CKR_KEY_TYPE_INCONSISTENT:
3777   case CKR_MECHANISM_INVALID:
3778   case CKR_MECHANISM_PARAM_INVALID:
3779   case CKR_OPERATION_ACTIVE:
3780   case CKR_PIN_EXPIRED:
3781   case CKR_SESSION_CLOSED:
3782   case CKR_SESSION_HANDLE_INVALID:
3783   case CKR_USER_NOT_LOGGED_IN:
3784     break;
3785   default:
3786   case CKR_OK:
3787     error = CKR_GENERAL_ERROR;
3788     break;
3789   }
3790   return error;
3791 }
3792
3793 /*
3794  * NSSCKFWC_Sign
3795  *
3796  */
3797 NSS_IMPLEMENT CK_RV
3798 NSSCKFWC_Sign
3799 (
3800   NSSCKFWInstance *fwInstance,
3801   CK_SESSION_HANDLE hSession,
3802   CK_BYTE_PTR pData,
3803   CK_ULONG ulDataLen,
3804   CK_BYTE_PTR pSignature,
3805   CK_ULONG_PTR pulSignatureLen
3806 )
3807 {
3808   CK_RV error = CKR_OK;
3809   NSSCKFWSession *fwSession;
3810
3811   if (!fwInstance) {
3812     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3813     goto loser;
3814   }
3815   
3816   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3817   if (!fwSession) {
3818     error = CKR_SESSION_HANDLE_INVALID;
3819     goto loser;
3820   }
3821
3822   error = nssCKFWSession_UpdateFinal(fwSession,
3823            NSSCKFWCryptoOperationType_Sign, 
3824            NSSCKFWCryptoOperationState_SignVerify,
3825            pData, ulDataLen, pSignature, pulSignatureLen);
3826
3827   if (CKR_OK == error) {
3828     return CKR_OK;
3829   }
3830
3831 loser:
3832   /* verify error */
3833   switch( error ) {
3834   case CKR_ARGUMENTS_BAD:
3835   case CKR_BUFFER_TOO_SMALL:
3836   case CKR_CRYPTOKI_NOT_INITIALIZED:
3837   case CKR_DATA_INVALID:
3838   case CKR_DATA_LEN_RANGE:
3839   case CKR_DEVICE_ERROR:
3840   case CKR_DEVICE_MEMORY:
3841   case CKR_DEVICE_REMOVED:
3842   case CKR_FUNCTION_CANCELED:
3843   case CKR_FUNCTION_FAILED:
3844   case CKR_GENERAL_ERROR:
3845   case CKR_HOST_MEMORY:
3846   case CKR_OPERATION_NOT_INITIALIZED:
3847   case CKR_SESSION_CLOSED:
3848   case CKR_SESSION_HANDLE_INVALID:
3849   case CKR_USER_NOT_LOGGED_IN:
3850   case CKR_FUNCTION_REJECTED:
3851     break;
3852   default:
3853   case CKR_OK:
3854     error = CKR_GENERAL_ERROR;
3855     break;
3856   }
3857   return error;
3858 }
3859
3860 /*
3861  * NSSCKFWC_SignUpdate
3862  *
3863  */
3864 NSS_IMPLEMENT CK_RV
3865 NSSCKFWC_SignUpdate
3866 (
3867   NSSCKFWInstance *fwInstance,
3868   CK_SESSION_HANDLE hSession,
3869   CK_BYTE_PTR pPart,
3870   CK_ULONG ulPartLen
3871 )
3872 {
3873   CK_RV error = CKR_OK;
3874   NSSCKFWSession *fwSession;
3875
3876   if (!fwInstance) {
3877     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3878     goto loser;
3879   }
3880   
3881   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3882   if (!fwSession) {
3883     error = CKR_SESSION_HANDLE_INVALID;
3884     goto loser;
3885   }
3886
3887   error = nssCKFWSession_DigestUpdate(fwSession,
3888            NSSCKFWCryptoOperationType_Sign, 
3889            NSSCKFWCryptoOperationState_SignVerify,
3890            pPart, ulPartLen);
3891
3892   if (CKR_OK == error) {
3893     return CKR_OK;
3894   }
3895
3896 loser:
3897   /* verify error */
3898   switch( error ) {
3899   case CKR_ARGUMENTS_BAD:
3900   case CKR_CRYPTOKI_NOT_INITIALIZED:
3901   case CKR_DATA_LEN_RANGE:
3902   case CKR_DEVICE_ERROR:
3903   case CKR_DEVICE_MEMORY:
3904   case CKR_DEVICE_REMOVED:
3905   case CKR_FUNCTION_CANCELED:
3906   case CKR_FUNCTION_FAILED:
3907   case CKR_GENERAL_ERROR:
3908   case CKR_HOST_MEMORY:
3909   case CKR_OPERATION_NOT_INITIALIZED:
3910   case CKR_SESSION_CLOSED:
3911   case CKR_SESSION_HANDLE_INVALID:
3912   case CKR_USER_NOT_LOGGED_IN:
3913     break;
3914   default:
3915   case CKR_OK:
3916     error = CKR_GENERAL_ERROR;
3917     break;
3918   }
3919   return error;
3920 }
3921
3922 /*
3923  * NSSCKFWC_SignFinal
3924  *
3925  */
3926 NSS_IMPLEMENT CK_RV
3927 NSSCKFWC_SignFinal
3928 (
3929   NSSCKFWInstance *fwInstance,
3930   CK_SESSION_HANDLE hSession,
3931   CK_BYTE_PTR pSignature,
3932   CK_ULONG_PTR pulSignatureLen
3933 )
3934 {
3935   CK_RV error = CKR_OK;
3936   NSSCKFWSession *fwSession;
3937
3938   if (!fwInstance) {
3939     error = CKR_CRYPTOKI_NOT_INITIALIZED;
3940     goto loser;
3941   }
3942   
3943   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
3944   if (!fwSession) {
3945     error = CKR_SESSION_HANDLE_INVALID;
3946     goto loser;
3947   }
3948
3949   error = nssCKFWSession_Final(fwSession,
3950            NSSCKFWCryptoOperationType_Sign, 
3951            NSSCKFWCryptoOperationState_SignVerify,
3952            pSignature, pulSignatureLen);
3953
3954   if (CKR_OK == error) {
3955     return CKR_OK;
3956   }
3957
3958 loser:
3959   /* verify error */
3960   switch( error ) {
3961   case CKR_ARGUMENTS_BAD:
3962   case CKR_BUFFER_TOO_SMALL:
3963   case CKR_CRYPTOKI_NOT_INITIALIZED:
3964   case CKR_DATA_LEN_RANGE:
3965   case CKR_DEVICE_ERROR:
3966   case CKR_DEVICE_MEMORY:
3967   case CKR_DEVICE_REMOVED:
3968   case CKR_FUNCTION_CANCELED:
3969   case CKR_FUNCTION_FAILED:
3970   case CKR_GENERAL_ERROR:
3971   case CKR_HOST_MEMORY:
3972   case CKR_OPERATION_NOT_INITIALIZED:
3973   case CKR_SESSION_CLOSED:
3974   case CKR_SESSION_HANDLE_INVALID:
3975   case CKR_USER_NOT_LOGGED_IN:
3976   case CKR_FUNCTION_REJECTED:
3977     break;
3978   default:
3979   case CKR_OK:
3980     error = CKR_GENERAL_ERROR;
3981     break;
3982   }
3983   return error;
3984 }
3985
3986 /*
3987  * NSSCKFWC_SignRecoverInit
3988  *
3989  */
3990 NSS_IMPLEMENT CK_RV
3991 NSSCKFWC_SignRecoverInit
3992 (
3993   NSSCKFWInstance *fwInstance,
3994   CK_SESSION_HANDLE hSession,
3995   CK_MECHANISM_PTR pMechanism,
3996   CK_OBJECT_HANDLE hKey
3997 )
3998 {
3999   CK_RV error = CKR_OK;
4000   NSSCKFWSession *fwSession;
4001   NSSCKFWObject *fwObject;
4002   NSSCKFWSlot  *fwSlot;
4003   NSSCKFWToken  *fwToken;
4004   NSSCKFWMechanism *fwMechanism;
4005
4006   if (!fwInstance) {
4007     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4008     goto loser;
4009   }
4010   
4011   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4012   if (!fwSession) {
4013     error = CKR_SESSION_HANDLE_INVALID;
4014     goto loser;
4015   }
4016
4017   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
4018   if (!fwObject) {
4019     error = CKR_KEY_HANDLE_INVALID;
4020     goto loser;
4021   }
4022
4023   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
4024   if (!fwSlot) {
4025     error = CKR_GENERAL_ERROR; /* should never happen! */
4026     goto loser;
4027   }
4028
4029   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
4030     error = CKR_TOKEN_NOT_PRESENT;
4031     goto loser;
4032   }
4033
4034   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
4035   if (!fwToken) {
4036     goto loser;
4037   }
4038
4039   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
4040   if (!fwMechanism) {
4041     goto loser;
4042   }
4043
4044   error = nssCKFWMechanism_SignRecoverInit(fwMechanism, pMechanism, fwSession, 
4045                                            fwObject);
4046
4047   nssCKFWMechanism_Destroy(fwMechanism);
4048
4049   if (CKR_OK == error) {
4050     return CKR_OK;
4051   }
4052
4053 loser:
4054   /* verify error */
4055   switch( error ) {
4056   case CKR_ARGUMENTS_BAD:
4057   case CKR_CRYPTOKI_NOT_INITIALIZED:
4058   case CKR_DEVICE_ERROR:
4059   case CKR_DEVICE_MEMORY:
4060   case CKR_DEVICE_REMOVED:
4061   case CKR_FUNCTION_CANCELED:
4062   case CKR_FUNCTION_FAILED:
4063   case CKR_GENERAL_ERROR:
4064   case CKR_HOST_MEMORY:
4065   case CKR_KEY_FUNCTION_NOT_PERMITTED:
4066   case CKR_KEY_HANDLE_INVALID:
4067   case CKR_KEY_SIZE_RANGE:
4068   case CKR_KEY_TYPE_INCONSISTENT:
4069   case CKR_MECHANISM_INVALID:
4070   case CKR_MECHANISM_PARAM_INVALID:
4071   case CKR_OPERATION_ACTIVE:
4072   case CKR_PIN_EXPIRED:
4073   case CKR_SESSION_CLOSED:
4074   case CKR_SESSION_HANDLE_INVALID:
4075   case CKR_USER_NOT_LOGGED_IN:
4076     break;
4077   default:
4078   case CKR_OK:
4079     error = CKR_GENERAL_ERROR;
4080     break;
4081   }
4082   return error;
4083 }
4084
4085 /*
4086  * NSSCKFWC_SignRecover
4087  *
4088  */
4089 NSS_IMPLEMENT CK_RV
4090 NSSCKFWC_SignRecover
4091 (
4092   NSSCKFWInstance *fwInstance,
4093   CK_SESSION_HANDLE hSession,
4094   CK_BYTE_PTR pData,
4095   CK_ULONG ulDataLen,
4096   CK_BYTE_PTR pSignature,
4097   CK_ULONG_PTR pulSignatureLen
4098 )
4099 {
4100   CK_RV error = CKR_OK;
4101   NSSCKFWSession *fwSession;
4102
4103   if (!fwInstance) {
4104     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4105     goto loser;
4106   }
4107   
4108   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4109   if (!fwSession) {
4110     error = CKR_SESSION_HANDLE_INVALID;
4111     goto loser;
4112   }
4113
4114   error = nssCKFWSession_UpdateFinal(fwSession,
4115            NSSCKFWCryptoOperationType_SignRecover, 
4116            NSSCKFWCryptoOperationState_SignVerify,
4117            pData, ulDataLen, pSignature, pulSignatureLen);
4118
4119   if (CKR_OK == error) {
4120     return CKR_OK;
4121   }
4122
4123 loser:
4124   /* verify error */
4125   switch( error ) {
4126   case CKR_ARGUMENTS_BAD:
4127   case CKR_BUFFER_TOO_SMALL:
4128   case CKR_CRYPTOKI_NOT_INITIALIZED:
4129   case CKR_DATA_INVALID:
4130   case CKR_DATA_LEN_RANGE:
4131   case CKR_DEVICE_ERROR:
4132   case CKR_DEVICE_MEMORY:
4133   case CKR_DEVICE_REMOVED:
4134   case CKR_FUNCTION_CANCELED:
4135   case CKR_FUNCTION_FAILED:
4136   case CKR_GENERAL_ERROR:
4137   case CKR_HOST_MEMORY:
4138   case CKR_OPERATION_NOT_INITIALIZED:
4139   case CKR_SESSION_CLOSED:
4140   case CKR_SESSION_HANDLE_INVALID:
4141   case CKR_USER_NOT_LOGGED_IN:
4142     break;
4143   default:
4144   case CKR_OK:
4145     error = CKR_GENERAL_ERROR;
4146     break;
4147   }
4148   return error;
4149 }
4150
4151 /*
4152  * NSSCKFWC_VerifyInit
4153  *
4154  */
4155 NSS_IMPLEMENT CK_RV
4156 NSSCKFWC_VerifyInit
4157 (
4158   NSSCKFWInstance *fwInstance,
4159   CK_SESSION_HANDLE hSession,
4160   CK_MECHANISM_PTR pMechanism,
4161   CK_OBJECT_HANDLE hKey
4162 )
4163 {
4164   CK_RV error = CKR_OK;
4165   NSSCKFWSession *fwSession;
4166   NSSCKFWObject *fwObject;
4167   NSSCKFWSlot  *fwSlot;
4168   NSSCKFWToken  *fwToken;
4169   NSSCKFWMechanism *fwMechanism;
4170
4171   if (!fwInstance) {
4172     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4173     goto loser;
4174   }
4175   
4176   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4177   if (!fwSession) {
4178     error = CKR_SESSION_HANDLE_INVALID;
4179     goto loser;
4180   }
4181
4182   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
4183   if (!fwObject) {
4184     error = CKR_KEY_HANDLE_INVALID;
4185     goto loser;
4186   }
4187
4188   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
4189   if (!fwSlot) {
4190     error = CKR_GENERAL_ERROR; /* should never happen! */
4191     goto loser;
4192   }
4193
4194   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
4195     error = CKR_TOKEN_NOT_PRESENT;
4196     goto loser;
4197   }
4198
4199   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
4200   if (!fwToken) {
4201     goto loser;
4202   }
4203
4204   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
4205   if (!fwMechanism) {
4206     goto loser;
4207   }
4208
4209   error = nssCKFWMechanism_VerifyInit(fwMechanism, pMechanism, fwSession,
4210                                       fwObject);
4211
4212   nssCKFWMechanism_Destroy(fwMechanism);
4213
4214   if (CKR_OK == error) {
4215     return CKR_OK;
4216   }
4217
4218 loser:
4219   /* verify error */
4220   switch( error ) {
4221   case CKR_ARGUMENTS_BAD:
4222   case CKR_CRYPTOKI_NOT_INITIALIZED:
4223   case CKR_DEVICE_ERROR:
4224   case CKR_DEVICE_MEMORY:
4225   case CKR_DEVICE_REMOVED:
4226   case CKR_FUNCTION_CANCELED:
4227   case CKR_FUNCTION_FAILED:
4228   case CKR_GENERAL_ERROR:
4229   case CKR_HOST_MEMORY:
4230   case CKR_KEY_FUNCTION_NOT_PERMITTED:
4231   case CKR_KEY_HANDLE_INVALID:
4232   case CKR_KEY_SIZE_RANGE:
4233   case CKR_KEY_TYPE_INCONSISTENT:
4234   case CKR_MECHANISM_INVALID:
4235   case CKR_MECHANISM_PARAM_INVALID:
4236   case CKR_OPERATION_ACTIVE:
4237   case CKR_PIN_EXPIRED:
4238   case CKR_SESSION_CLOSED:
4239   case CKR_SESSION_HANDLE_INVALID:
4240   case CKR_USER_NOT_LOGGED_IN:
4241     break;
4242   default:
4243   case CKR_OK:
4244     error = CKR_GENERAL_ERROR;
4245     break;
4246   }
4247   return error;
4248 }
4249
4250 /*
4251  * NSSCKFWC_Verify
4252  *
4253  */
4254 NSS_IMPLEMENT CK_RV
4255 NSSCKFWC_Verify
4256 (
4257   NSSCKFWInstance *fwInstance,
4258   CK_SESSION_HANDLE hSession,
4259   CK_BYTE_PTR pData,
4260   CK_ULONG ulDataLen,
4261   CK_BYTE_PTR pSignature,
4262   CK_ULONG ulSignatureLen
4263 )
4264 {
4265   CK_RV error = CKR_OK;
4266   NSSCKFWSession *fwSession;
4267
4268   if (!fwInstance) {
4269     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4270     goto loser;
4271   }
4272   
4273   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4274   if (!fwSession) {
4275     error = CKR_SESSION_HANDLE_INVALID;
4276     goto loser;
4277   }
4278
4279   error = nssCKFWSession_UpdateFinal(fwSession,
4280            NSSCKFWCryptoOperationType_Verify, 
4281            NSSCKFWCryptoOperationState_SignVerify,
4282            pData, ulDataLen, pSignature, &ulSignatureLen);
4283
4284   if (CKR_OK == error) {
4285     return CKR_OK;
4286   }
4287
4288 loser:
4289   /* verify error */
4290   switch( error ) {
4291   case CKR_ARGUMENTS_BAD:
4292   case CKR_CRYPTOKI_NOT_INITIALIZED:
4293   case CKR_DATA_INVALID:
4294   case CKR_DATA_LEN_RANGE:
4295   case CKR_DEVICE_ERROR:
4296   case CKR_DEVICE_MEMORY:
4297   case CKR_DEVICE_REMOVED:
4298   case CKR_FUNCTION_CANCELED:
4299   case CKR_FUNCTION_FAILED:
4300   case CKR_GENERAL_ERROR:
4301   case CKR_HOST_MEMORY:
4302   case CKR_OPERATION_NOT_INITIALIZED:
4303   case CKR_SESSION_CLOSED:
4304   case CKR_SESSION_HANDLE_INVALID:
4305   case CKR_SIGNATURE_INVALID:
4306   case CKR_SIGNATURE_LEN_RANGE:
4307     break;
4308   default:
4309   case CKR_OK:
4310     error = CKR_GENERAL_ERROR;
4311     break;
4312   }
4313   return error;
4314 }
4315
4316 /*
4317  * NSSCKFWC_VerifyUpdate
4318  *
4319  */
4320 NSS_IMPLEMENT CK_RV
4321 NSSCKFWC_VerifyUpdate
4322 (
4323   NSSCKFWInstance *fwInstance,
4324   CK_SESSION_HANDLE hSession,
4325   CK_BYTE_PTR pPart,
4326   CK_ULONG ulPartLen
4327 )
4328 {
4329   CK_RV error = CKR_OK;
4330   NSSCKFWSession *fwSession;
4331
4332   if (!fwInstance) {
4333     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4334     goto loser;
4335   }
4336   
4337   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4338   if (!fwSession) {
4339     error = CKR_SESSION_HANDLE_INVALID;
4340     goto loser;
4341   }
4342
4343   error = nssCKFWSession_DigestUpdate(fwSession,
4344            NSSCKFWCryptoOperationType_Verify, 
4345            NSSCKFWCryptoOperationState_SignVerify,
4346            pPart, ulPartLen);
4347
4348   if (CKR_OK == error) {
4349     return CKR_OK;
4350   }
4351
4352 loser:
4353   /* verify error */
4354   switch( error ) {
4355   case CKR_ARGUMENTS_BAD:
4356   case CKR_CRYPTOKI_NOT_INITIALIZED:
4357   case CKR_DATA_LEN_RANGE:
4358   case CKR_DEVICE_ERROR:
4359   case CKR_DEVICE_MEMORY:
4360   case CKR_DEVICE_REMOVED:
4361   case CKR_FUNCTION_CANCELED:
4362   case CKR_FUNCTION_FAILED:
4363   case CKR_GENERAL_ERROR:
4364   case CKR_HOST_MEMORY:
4365   case CKR_OPERATION_NOT_INITIALIZED:
4366   case CKR_SESSION_CLOSED:
4367   case CKR_SESSION_HANDLE_INVALID:
4368     break;
4369   default:
4370   case CKR_OK:
4371     error = CKR_GENERAL_ERROR;
4372     break;
4373   }
4374   return error;
4375 }
4376
4377 /*
4378  * NSSCKFWC_VerifyFinal
4379  *
4380  */
4381 NSS_IMPLEMENT CK_RV
4382 NSSCKFWC_VerifyFinal
4383 (
4384   NSSCKFWInstance *fwInstance,
4385   CK_SESSION_HANDLE hSession,
4386   CK_BYTE_PTR pSignature,
4387   CK_ULONG ulSignatureLen
4388 )
4389 {
4390   CK_RV error = CKR_OK;
4391   NSSCKFWSession *fwSession;
4392
4393   if (!fwInstance) {
4394     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4395     goto loser;
4396   }
4397   
4398   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4399   if (!fwSession) {
4400     error = CKR_SESSION_HANDLE_INVALID;
4401     goto loser;
4402   }
4403
4404   error = nssCKFWSession_Final(fwSession,
4405            NSSCKFWCryptoOperationType_Verify, 
4406            NSSCKFWCryptoOperationState_SignVerify,
4407            pSignature, &ulSignatureLen);
4408
4409   if (CKR_OK == error) {
4410     return CKR_OK;
4411   }
4412
4413 loser:
4414   /* verify error */
4415   switch( error ) {
4416   case CKR_ARGUMENTS_BAD:
4417   case CKR_CRYPTOKI_NOT_INITIALIZED:
4418   case CKR_DATA_LEN_RANGE:
4419   case CKR_DEVICE_ERROR:
4420   case CKR_DEVICE_MEMORY:
4421   case CKR_DEVICE_REMOVED:
4422   case CKR_FUNCTION_CANCELED:
4423   case CKR_FUNCTION_FAILED:
4424   case CKR_GENERAL_ERROR:
4425   case CKR_HOST_MEMORY:
4426   case CKR_OPERATION_NOT_INITIALIZED:
4427   case CKR_SESSION_CLOSED:
4428   case CKR_SESSION_HANDLE_INVALID:
4429   case CKR_SIGNATURE_INVALID:
4430   case CKR_SIGNATURE_LEN_RANGE:
4431     break;
4432   default:
4433   case CKR_OK:
4434     error = CKR_GENERAL_ERROR;
4435     break;
4436   }
4437   return error;
4438 }
4439
4440 /*
4441  * NSSCKFWC_VerifyRecoverInit
4442  *
4443  */
4444 NSS_IMPLEMENT CK_RV
4445 NSSCKFWC_VerifyRecoverInit
4446 (
4447   NSSCKFWInstance *fwInstance,
4448   CK_SESSION_HANDLE hSession,
4449   CK_MECHANISM_PTR pMechanism,
4450   CK_OBJECT_HANDLE hKey
4451 )
4452 {
4453   CK_RV error = CKR_OK;
4454   NSSCKFWSession *fwSession;
4455   NSSCKFWObject *fwObject;
4456   NSSCKFWSlot  *fwSlot;
4457   NSSCKFWToken  *fwToken;
4458   NSSCKFWMechanism *fwMechanism;
4459
4460   if (!fwInstance) {
4461     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4462     goto loser;
4463   }
4464   
4465   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4466   if (!fwSession) {
4467     error = CKR_SESSION_HANDLE_INVALID;
4468     goto loser;
4469   }
4470
4471   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
4472   if (!fwObject) {
4473     error = CKR_KEY_HANDLE_INVALID;
4474     goto loser;
4475   }
4476
4477   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
4478   if (!fwSlot) {
4479     error = CKR_GENERAL_ERROR; /* should never happen! */
4480     goto loser;
4481   }
4482
4483   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
4484     error = CKR_TOKEN_NOT_PRESENT;
4485     goto loser;
4486   }
4487
4488   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
4489   if (!fwToken) {
4490     goto loser;
4491   }
4492
4493   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
4494   if (!fwMechanism) {
4495     goto loser;
4496   }
4497
4498   error = nssCKFWMechanism_VerifyRecoverInit(fwMechanism, pMechanism, 
4499                                              fwSession, fwObject);
4500
4501   nssCKFWMechanism_Destroy(fwMechanism);
4502
4503   if (CKR_OK == error) {
4504     return CKR_OK;
4505   }
4506
4507 loser:
4508   /* verify error */
4509   switch( error ) {
4510   case CKR_ARGUMENTS_BAD:
4511   case CKR_CRYPTOKI_NOT_INITIALIZED:
4512   case CKR_DEVICE_ERROR:
4513   case CKR_DEVICE_MEMORY:
4514   case CKR_DEVICE_REMOVED:
4515   case CKR_FUNCTION_CANCELED:
4516   case CKR_FUNCTION_FAILED:
4517   case CKR_GENERAL_ERROR:
4518   case CKR_HOST_MEMORY:
4519   case CKR_KEY_FUNCTION_NOT_PERMITTED:
4520   case CKR_KEY_HANDLE_INVALID:
4521   case CKR_KEY_SIZE_RANGE:
4522   case CKR_KEY_TYPE_INCONSISTENT:
4523   case CKR_MECHANISM_INVALID:
4524   case CKR_MECHANISM_PARAM_INVALID:
4525   case CKR_OPERATION_ACTIVE:
4526   case CKR_PIN_EXPIRED:
4527   case CKR_SESSION_HANDLE_INVALID:
4528   case CKR_SESSION_CLOSED:
4529   case CKR_USER_NOT_LOGGED_IN:
4530     break;
4531   default:
4532   case CKR_OK:
4533     error = CKR_GENERAL_ERROR;
4534     break;
4535   }
4536   return error;
4537 }
4538
4539 /*
4540  * NSSCKFWC_VerifyRecover
4541  *
4542  */
4543 NSS_IMPLEMENT CK_RV
4544 NSSCKFWC_VerifyRecover
4545 (
4546   NSSCKFWInstance *fwInstance,
4547   CK_SESSION_HANDLE hSession,
4548   CK_BYTE_PTR pSignature,
4549   CK_ULONG ulSignatureLen,
4550   CK_BYTE_PTR pData,
4551   CK_ULONG_PTR pulDataLen
4552 )
4553 {
4554   CK_RV error = CKR_OK;
4555   NSSCKFWSession *fwSession;
4556
4557   if (!fwInstance) {
4558     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4559     goto loser;
4560   }
4561   
4562   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4563   if (!fwSession) {
4564     error = CKR_SESSION_HANDLE_INVALID;
4565     goto loser;
4566   }
4567
4568   error = nssCKFWSession_UpdateFinal(fwSession,
4569            NSSCKFWCryptoOperationType_VerifyRecover, 
4570            NSSCKFWCryptoOperationState_SignVerify,
4571            pSignature, ulSignatureLen, pData, pulDataLen);
4572   if (CKR_OK == error) {
4573     return CKR_OK;
4574   }
4575 loser:
4576   /* verify error */
4577   switch( error ) {
4578   case CKR_ARGUMENTS_BAD:
4579   case CKR_BUFFER_TOO_SMALL:
4580   case CKR_CRYPTOKI_NOT_INITIALIZED:
4581   case CKR_DATA_INVALID:
4582   case CKR_DATA_LEN_RANGE:
4583   case CKR_DEVICE_ERROR:
4584   case CKR_DEVICE_MEMORY:
4585   case CKR_DEVICE_REMOVED:
4586   case CKR_FUNCTION_CANCELED:
4587   case CKR_FUNCTION_FAILED:
4588   case CKR_GENERAL_ERROR:
4589   case CKR_HOST_MEMORY:
4590   case CKR_OPERATION_NOT_INITIALIZED:
4591   case CKR_SESSION_CLOSED:
4592   case CKR_SESSION_HANDLE_INVALID:
4593   case CKR_SIGNATURE_INVALID:
4594   case CKR_SIGNATURE_LEN_RANGE:
4595     break;
4596   default:
4597   case CKR_OK:
4598     error = CKR_GENERAL_ERROR;
4599     break;
4600   }
4601   return error;
4602 }
4603
4604 /*
4605  * NSSCKFWC_DigestEncryptUpdate
4606  *
4607  */
4608 NSS_IMPLEMENT CK_RV
4609 NSSCKFWC_DigestEncryptUpdate
4610 (
4611   NSSCKFWInstance *fwInstance,
4612   CK_SESSION_HANDLE hSession,
4613   CK_BYTE_PTR pPart,
4614   CK_ULONG ulPartLen,
4615   CK_BYTE_PTR pEncryptedPart,
4616   CK_ULONG_PTR pulEncryptedPartLen
4617 )
4618 {
4619   CK_RV error = CKR_OK;
4620   NSSCKFWSession *fwSession;
4621
4622   if (!fwInstance) {
4623     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4624     goto loser;
4625   }
4626   
4627   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4628   if (!fwSession) {
4629     error = CKR_SESSION_HANDLE_INVALID;
4630     goto loser;
4631   }
4632
4633   error = nssCKFWSession_UpdateCombo(fwSession,
4634            NSSCKFWCryptoOperationType_Encrypt, 
4635            NSSCKFWCryptoOperationType_Digest, 
4636            NSSCKFWCryptoOperationState_Digest,
4637            pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
4638
4639   if (CKR_OK == error) {
4640     return CKR_OK;
4641   }
4642
4643 loser:
4644   /* verify error */
4645   switch( error ) {
4646   case CKR_ARGUMENTS_BAD:
4647   case CKR_BUFFER_TOO_SMALL:
4648   case CKR_CRYPTOKI_NOT_INITIALIZED:
4649   case CKR_DATA_LEN_RANGE:
4650   case CKR_DEVICE_ERROR:
4651   case CKR_DEVICE_MEMORY:
4652   case CKR_DEVICE_REMOVED:
4653   case CKR_FUNCTION_CANCELED:
4654   case CKR_FUNCTION_FAILED:
4655   case CKR_GENERAL_ERROR:
4656   case CKR_HOST_MEMORY:
4657   case CKR_OPERATION_NOT_INITIALIZED:
4658   case CKR_SESSION_CLOSED:
4659   case CKR_SESSION_HANDLE_INVALID:
4660     break;
4661   default:
4662   case CKR_OK:
4663     error = CKR_GENERAL_ERROR;
4664     break;
4665   }
4666   return error;
4667 }
4668
4669 /*
4670  * NSSCKFWC_DecryptDigestUpdate
4671  *
4672  */
4673 NSS_IMPLEMENT CK_RV
4674 NSSCKFWC_DecryptDigestUpdate
4675 (
4676   NSSCKFWInstance *fwInstance,
4677   CK_SESSION_HANDLE hSession,
4678   CK_BYTE_PTR pEncryptedPart,
4679   CK_ULONG ulEncryptedPartLen,
4680   CK_BYTE_PTR pPart,
4681   CK_ULONG_PTR pulPartLen
4682 )
4683 {
4684   CK_RV error = CKR_OK;
4685   NSSCKFWSession *fwSession;
4686
4687   if (!fwInstance) {
4688     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4689     goto loser;
4690   }
4691   
4692   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4693   if (!fwSession) {
4694     error = CKR_SESSION_HANDLE_INVALID;
4695     goto loser;
4696   }
4697
4698   error = nssCKFWSession_UpdateCombo(fwSession,
4699            NSSCKFWCryptoOperationType_Decrypt, 
4700            NSSCKFWCryptoOperationType_Digest, 
4701            NSSCKFWCryptoOperationState_Digest,
4702            pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
4703
4704   if (CKR_OK == error) {
4705     return CKR_OK;
4706   }
4707
4708 loser:
4709   /* verify error */
4710   switch( error ) {
4711   case CKR_ARGUMENTS_BAD:
4712   case CKR_BUFFER_TOO_SMALL:
4713   case CKR_CRYPTOKI_NOT_INITIALIZED:
4714   case CKR_DEVICE_ERROR:
4715   case CKR_DEVICE_MEMORY:
4716   case CKR_DEVICE_REMOVED:
4717   case CKR_ENCRYPTED_DATA_INVALID:
4718   case CKR_ENCRYPTED_DATA_LEN_RANGE:
4719   case CKR_FUNCTION_CANCELED:
4720   case CKR_FUNCTION_FAILED:
4721   case CKR_GENERAL_ERROR:
4722   case CKR_HOST_MEMORY:
4723   case CKR_OPERATION_NOT_INITIALIZED:
4724   case CKR_SESSION_CLOSED:
4725   case CKR_SESSION_HANDLE_INVALID:
4726     break;
4727   case CKR_DATA_INVALID:
4728     error = CKR_ENCRYPTED_DATA_INVALID;
4729     break;
4730   case CKR_DATA_LEN_RANGE:
4731     error = CKR_ENCRYPTED_DATA_LEN_RANGE;
4732     break;
4733   default:
4734   case CKR_OK:
4735     error = CKR_GENERAL_ERROR;
4736     break;
4737   }
4738   return error;
4739 }
4740
4741 /*
4742  * NSSCKFWC_SignEncryptUpdate
4743  *
4744  */
4745 NSS_IMPLEMENT CK_RV
4746 NSSCKFWC_SignEncryptUpdate
4747 (
4748   NSSCKFWInstance *fwInstance,
4749   CK_SESSION_HANDLE hSession,
4750   CK_BYTE_PTR pPart,
4751   CK_ULONG ulPartLen,
4752   CK_BYTE_PTR pEncryptedPart,
4753   CK_ULONG_PTR pulEncryptedPartLen
4754 )
4755 {
4756   CK_RV error = CKR_OK;
4757   NSSCKFWSession *fwSession;
4758
4759   if (!fwInstance) {
4760     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4761     goto loser;
4762   }
4763   
4764   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4765   if (!fwSession) {
4766     error = CKR_SESSION_HANDLE_INVALID;
4767     goto loser;
4768   }
4769
4770   error = nssCKFWSession_UpdateCombo(fwSession,
4771            NSSCKFWCryptoOperationType_Encrypt, 
4772            NSSCKFWCryptoOperationType_Sign, 
4773            NSSCKFWCryptoOperationState_SignVerify,
4774            pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
4775
4776   if (CKR_OK == error) {
4777     return CKR_OK;
4778   }
4779
4780 loser:
4781   /* verify error */
4782   switch( error ) {
4783   case CKR_ARGUMENTS_BAD:
4784   case CKR_BUFFER_TOO_SMALL:
4785   case CKR_CRYPTOKI_NOT_INITIALIZED:
4786   case CKR_DATA_LEN_RANGE:
4787   case CKR_DEVICE_ERROR:
4788   case CKR_DEVICE_MEMORY:
4789   case CKR_DEVICE_REMOVED:
4790   case CKR_FUNCTION_CANCELED:
4791   case CKR_FUNCTION_FAILED:
4792   case CKR_GENERAL_ERROR:
4793   case CKR_HOST_MEMORY:
4794   case CKR_OPERATION_NOT_INITIALIZED:
4795   case CKR_SESSION_CLOSED:
4796   case CKR_SESSION_HANDLE_INVALID:
4797   case CKR_USER_NOT_LOGGED_IN:
4798     break;
4799   default:
4800   case CKR_OK:
4801     error = CKR_GENERAL_ERROR;
4802     break;
4803   }
4804   return error;
4805 }
4806
4807 /*
4808  * NSSCKFWC_DecryptVerifyUpdate
4809  *
4810  */
4811 NSS_IMPLEMENT CK_RV
4812 NSSCKFWC_DecryptVerifyUpdate
4813 (
4814   NSSCKFWInstance *fwInstance,
4815   CK_SESSION_HANDLE hSession,
4816   CK_BYTE_PTR pEncryptedPart,
4817   CK_ULONG ulEncryptedPartLen,
4818   CK_BYTE_PTR pPart,
4819   CK_ULONG_PTR pulPartLen
4820 )
4821 {
4822   CK_RV error = CKR_OK;
4823   NSSCKFWSession *fwSession;
4824
4825   if (!fwInstance) {
4826     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4827     goto loser;
4828   }
4829   
4830   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4831   if (!fwSession) {
4832     error = CKR_SESSION_HANDLE_INVALID;
4833     goto loser;
4834   }
4835
4836   error = nssCKFWSession_UpdateCombo(fwSession,
4837            NSSCKFWCryptoOperationType_Decrypt, 
4838            NSSCKFWCryptoOperationType_Verify, 
4839            NSSCKFWCryptoOperationState_SignVerify,
4840            pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
4841
4842   if (CKR_OK == error) {
4843     return CKR_OK;
4844   }
4845
4846 loser:
4847   /* verify error */
4848   switch( error ) {
4849   case CKR_ARGUMENTS_BAD:
4850   case CKR_BUFFER_TOO_SMALL:
4851   case CKR_CRYPTOKI_NOT_INITIALIZED:
4852   case CKR_DATA_LEN_RANGE:
4853   case CKR_DEVICE_ERROR:
4854   case CKR_DEVICE_MEMORY:
4855   case CKR_DEVICE_REMOVED:
4856   case CKR_ENCRYPTED_DATA_INVALID:
4857   case CKR_ENCRYPTED_DATA_LEN_RANGE:
4858   case CKR_FUNCTION_CANCELED:
4859   case CKR_FUNCTION_FAILED:
4860   case CKR_GENERAL_ERROR:
4861   case CKR_HOST_MEMORY:
4862   case CKR_OPERATION_NOT_INITIALIZED:
4863   case CKR_SESSION_CLOSED:
4864   case CKR_SESSION_HANDLE_INVALID:
4865     break;
4866   case CKR_DATA_INVALID:
4867     error = CKR_ENCRYPTED_DATA_INVALID;
4868     break;
4869   default:
4870   case CKR_OK:
4871     error = CKR_GENERAL_ERROR;
4872     break;
4873   }
4874   return error;
4875 }
4876
4877 /*
4878  * NSSCKFWC_GenerateKey
4879  *
4880  */
4881 NSS_IMPLEMENT CK_RV
4882 NSSCKFWC_GenerateKey
4883 (
4884   NSSCKFWInstance *fwInstance,
4885   CK_SESSION_HANDLE hSession,
4886   CK_MECHANISM_PTR pMechanism,
4887   CK_ATTRIBUTE_PTR pTemplate,
4888   CK_ULONG ulCount,
4889   CK_OBJECT_HANDLE_PTR phKey
4890 )
4891 {
4892   CK_RV error = CKR_OK;
4893   NSSCKFWSession *fwSession;
4894   NSSCKFWObject *fwObject;
4895   NSSCKFWSlot  *fwSlot;
4896   NSSCKFWToken  *fwToken;
4897   NSSCKFWMechanism *fwMechanism;
4898
4899   if (!fwInstance) {
4900     error = CKR_CRYPTOKI_NOT_INITIALIZED;
4901     goto loser;
4902   }
4903   
4904   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
4905   if (!fwSession) {
4906     error = CKR_SESSION_HANDLE_INVALID;
4907     goto loser;
4908   }
4909
4910   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
4911   if (!fwSlot) {
4912     error = CKR_GENERAL_ERROR; /* should never happen! */
4913     goto loser;
4914   }
4915
4916   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
4917     error = CKR_TOKEN_NOT_PRESENT;
4918     goto loser;
4919   }
4920
4921   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
4922   if (!fwToken) {
4923     goto loser;
4924   }
4925
4926   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
4927   if (!fwMechanism) {
4928     goto loser;
4929   }
4930
4931   fwObject = nssCKFWMechanism_GenerateKey(
4932                 fwMechanism, 
4933                 pMechanism, 
4934                 fwSession, 
4935                 pTemplate, 
4936                 ulCount, 
4937                 &error);
4938
4939   nssCKFWMechanism_Destroy(fwMechanism);
4940   if (!fwObject) {
4941     goto loser;
4942   }
4943   *phKey= nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
4944
4945   if (CKR_OK == error) {
4946     return CKR_OK;
4947   }
4948
4949 loser:
4950   /* verify error */
4951   switch( error ) {
4952   case CKR_ARGUMENTS_BAD:
4953   case CKR_ATTRIBUTE_READ_ONLY:
4954   case CKR_ATTRIBUTE_TYPE_INVALID:
4955   case CKR_ATTRIBUTE_VALUE_INVALID:
4956   case CKR_CRYPTOKI_NOT_INITIALIZED:
4957   case CKR_DEVICE_ERROR:
4958   case CKR_DEVICE_MEMORY:
4959   case CKR_DEVICE_REMOVED:
4960   case CKR_FUNCTION_CANCELED:
4961   case CKR_FUNCTION_FAILED:
4962   case CKR_GENERAL_ERROR:
4963   case CKR_HOST_MEMORY:
4964   case CKR_MECHANISM_INVALID:
4965   case CKR_MECHANISM_PARAM_INVALID:
4966   case CKR_OPERATION_ACTIVE:
4967   case CKR_PIN_EXPIRED:
4968   case CKR_SESSION_CLOSED:
4969   case CKR_SESSION_HANDLE_INVALID:
4970   case CKR_SESSION_READ_ONLY:
4971   case CKR_TEMPLATE_INCOMPLETE:
4972   case CKR_TEMPLATE_INCONSISTENT:
4973   case CKR_TOKEN_WRITE_PROTECTED:
4974   case CKR_USER_NOT_LOGGED_IN:
4975     break;
4976   default:
4977   case CKR_OK:
4978     error = CKR_GENERAL_ERROR;
4979     break;
4980   }
4981   return error;
4982 }
4983
4984 /*
4985  * NSSCKFWC_GenerateKeyPair
4986  *
4987  */
4988 NSS_IMPLEMENT CK_RV
4989 NSSCKFWC_GenerateKeyPair
4990 (
4991   NSSCKFWInstance *fwInstance,
4992   CK_SESSION_HANDLE hSession,
4993   CK_MECHANISM_PTR pMechanism,
4994   CK_ATTRIBUTE_PTR pPublicKeyTemplate,
4995   CK_ULONG ulPublicKeyAttributeCount,
4996   CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
4997   CK_ULONG ulPrivateKeyAttributeCount,
4998   CK_OBJECT_HANDLE_PTR phPublicKey,
4999   CK_OBJECT_HANDLE_PTR phPrivateKey
5000 )
5001 {
5002   CK_RV error = CKR_OK;
5003   NSSCKFWSession *fwSession;
5004   NSSCKFWObject *fwPrivateKeyObject;
5005   NSSCKFWObject *fwPublicKeyObject;
5006   NSSCKFWSlot  *fwSlot;
5007   NSSCKFWToken  *fwToken;
5008   NSSCKFWMechanism *fwMechanism;
5009
5010   if (!fwInstance) {
5011     error = CKR_CRYPTOKI_NOT_INITIALIZED;
5012     goto loser;
5013   }
5014   
5015   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
5016   if (!fwSession) {
5017     error = CKR_SESSION_HANDLE_INVALID;
5018     goto loser;
5019   }
5020
5021   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
5022   if (!fwSlot) {
5023     error = CKR_GENERAL_ERROR; /* should never happen! */
5024     goto loser;
5025   }
5026
5027   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
5028     error = CKR_TOKEN_NOT_PRESENT;
5029     goto loser;
5030   }
5031
5032   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
5033   if (!fwToken) {
5034     goto loser;
5035   }
5036
5037   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
5038   if (!fwMechanism) {
5039     goto loser;
5040   }
5041
5042   error= nssCKFWMechanism_GenerateKeyPair(
5043                 fwMechanism, 
5044                 pMechanism, 
5045                 fwSession, 
5046                 pPublicKeyTemplate, 
5047                 ulPublicKeyAttributeCount, 
5048                 pPublicKeyTemplate, 
5049                 ulPublicKeyAttributeCount, 
5050                 &fwPublicKeyObject,
5051                 &fwPrivateKeyObject);
5052
5053   nssCKFWMechanism_Destroy(fwMechanism);
5054   if (CKR_OK != error) {
5055     goto loser;
5056   }
5057   *phPublicKey = nssCKFWInstance_CreateObjectHandle(fwInstance, 
5058                                                  fwPublicKeyObject, 
5059                                                  &error);
5060   if (CKR_OK != error) {
5061     goto loser;
5062   }
5063   *phPrivateKey = nssCKFWInstance_CreateObjectHandle(fwInstance, 
5064                                                  fwPrivateKeyObject, 
5065                                                  &error);
5066   if (CKR_OK == error) {
5067     return CKR_OK;
5068   }
5069
5070 loser:
5071   /* verify error */
5072   switch( error ) {
5073   case CKR_ARGUMENTS_BAD:
5074   case CKR_ATTRIBUTE_READ_ONLY:
5075   case CKR_ATTRIBUTE_TYPE_INVALID:
5076   case CKR_ATTRIBUTE_VALUE_INVALID:
5077   case CKR_CRYPTOKI_NOT_INITIALIZED:
5078   case CKR_DEVICE_ERROR:
5079   case CKR_DEVICE_MEMORY:
5080   case CKR_DEVICE_REMOVED:
5081   case CKR_DOMAIN_PARAMS_INVALID:
5082   case CKR_FUNCTION_CANCELED:
5083   case CKR_FUNCTION_FAILED:
5084   case CKR_GENERAL_ERROR:
5085   case CKR_HOST_MEMORY:
5086   case CKR_MECHANISM_INVALID:
5087   case CKR_MECHANISM_PARAM_INVALID:
5088   case CKR_OPERATION_ACTIVE:
5089   case CKR_PIN_EXPIRED:
5090   case CKR_SESSION_CLOSED:
5091   case CKR_SESSION_HANDLE_INVALID:
5092   case CKR_SESSION_READ_ONLY:
5093   case CKR_TEMPLATE_INCOMPLETE:
5094   case CKR_TEMPLATE_INCONSISTENT:
5095   case CKR_TOKEN_WRITE_PROTECTED:
5096   case CKR_USER_NOT_LOGGED_IN:
5097     break;
5098   default:
5099   case CKR_OK:
5100     error = CKR_GENERAL_ERROR;
5101     break;
5102   }
5103   return error;
5104 }
5105
5106 /*
5107  * NSSCKFWC_WrapKey
5108  *
5109  */
5110 NSS_IMPLEMENT CK_RV
5111 NSSCKFWC_WrapKey
5112 (
5113   NSSCKFWInstance *fwInstance,
5114   CK_SESSION_HANDLE hSession,
5115   CK_MECHANISM_PTR pMechanism,
5116   CK_OBJECT_HANDLE hWrappingKey,
5117   CK_OBJECT_HANDLE hKey,
5118   CK_BYTE_PTR pWrappedKey,
5119   CK_ULONG_PTR pulWrappedKeyLen
5120 )
5121 {
5122   CK_RV error = CKR_OK;
5123   NSSCKFWSession *fwSession;
5124   NSSCKFWObject *fwKeyObject;
5125   NSSCKFWObject *fwWrappingKeyObject;
5126   NSSCKFWSlot  *fwSlot;
5127   NSSCKFWToken  *fwToken;
5128   NSSCKFWMechanism *fwMechanism;
5129   NSSItem  wrappedKey;
5130   CK_ULONG wrappedKeyLength = 0;
5131
5132   if (!fwInstance) {
5133     error = CKR_CRYPTOKI_NOT_INITIALIZED;
5134     goto loser;
5135   }
5136   
5137   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
5138   if (!fwSession) {
5139     error = CKR_SESSION_HANDLE_INVALID;
5140     goto loser;
5141   }
5142
5143   fwWrappingKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance,
5144                                                             hWrappingKey);
5145   if (!fwWrappingKeyObject) {
5146     error = CKR_WRAPPING_KEY_HANDLE_INVALID;
5147     goto loser;
5148   }
5149
5150   fwKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
5151   if (!fwKeyObject) {
5152     error = CKR_KEY_HANDLE_INVALID;
5153     goto loser;
5154   }
5155
5156   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
5157   if (!fwSlot) {
5158     error = CKR_GENERAL_ERROR; /* should never happen! */
5159     goto loser;
5160   }
5161
5162   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
5163     error = CKR_TOKEN_NOT_PRESENT;
5164     goto loser;
5165   }
5166
5167   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
5168   if (!fwToken) {
5169     goto loser;
5170   }
5171
5172   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
5173   if (!fwMechanism) {
5174     goto loser;
5175   }
5176
5177   /*
5178    * first get the length...
5179    */
5180   wrappedKeyLength = nssCKFWMechanism_GetWrapKeyLength(
5181                 fwMechanism, 
5182                 pMechanism, 
5183                 fwSession, 
5184                 fwWrappingKeyObject,
5185                 fwKeyObject,
5186                 &error);
5187   if ((CK_ULONG) 0 == wrappedKeyLength) {
5188     nssCKFWMechanism_Destroy(fwMechanism);
5189     goto loser;
5190   }
5191   if ((CK_BYTE_PTR)NULL == pWrappedKey) {
5192     *pulWrappedKeyLen = wrappedKeyLength;
5193     nssCKFWMechanism_Destroy(fwMechanism);
5194     return CKR_OK;
5195   }
5196   if (wrappedKeyLength > *pulWrappedKeyLen) {
5197     *pulWrappedKeyLen = wrappedKeyLength;
5198     nssCKFWMechanism_Destroy(fwMechanism);
5199     error = CKR_BUFFER_TOO_SMALL;
5200     goto loser;
5201   }
5202     
5203
5204   wrappedKey.data = pWrappedKey;
5205   wrappedKey.size = wrappedKeyLength;
5206
5207   error = nssCKFWMechanism_WrapKey(
5208                 fwMechanism, 
5209                 pMechanism, 
5210                 fwSession, 
5211                 fwWrappingKeyObject,
5212                 fwKeyObject,
5213                 &wrappedKey);
5214
5215   nssCKFWMechanism_Destroy(fwMechanism);
5216   *pulWrappedKeyLen = wrappedKey.size;
5217
5218   if (CKR_OK == error) {
5219     return CKR_OK;
5220   }
5221
5222 loser:
5223   /* verify error */
5224   switch( error ) {
5225   case CKR_ARGUMENTS_BAD:
5226   case CKR_BUFFER_TOO_SMALL:
5227   case CKR_CRYPTOKI_NOT_INITIALIZED:
5228   case CKR_DEVICE_ERROR:
5229   case CKR_DEVICE_MEMORY:
5230   case CKR_DEVICE_REMOVED:
5231   case CKR_FUNCTION_CANCELED:
5232   case CKR_FUNCTION_FAILED:
5233   case CKR_GENERAL_ERROR:
5234   case CKR_HOST_MEMORY:
5235   case CKR_KEY_HANDLE_INVALID:
5236   case CKR_KEY_NOT_WRAPPABLE:
5237   case CKR_KEY_SIZE_RANGE:
5238   case CKR_KEY_UNEXTRACTABLE:
5239   case CKR_MECHANISM_INVALID:
5240   case CKR_MECHANISM_PARAM_INVALID:
5241   case CKR_OPERATION_ACTIVE:
5242   case CKR_PIN_EXPIRED:
5243   case CKR_SESSION_CLOSED:
5244   case CKR_SESSION_HANDLE_INVALID:
5245   case CKR_WRAPPING_KEY_HANDLE_INVALID:
5246   case CKR_WRAPPING_KEY_SIZE_RANGE:
5247   case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
5248     break;
5249   case CKR_KEY_TYPE_INCONSISTENT:
5250     error = CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
5251     break;
5252   default:
5253   case CKR_OK:
5254     error = CKR_GENERAL_ERROR;
5255     break;
5256   }
5257   return error;
5258 }
5259
5260 /*
5261  * NSSCKFWC_UnwrapKey
5262  *
5263  */
5264 NSS_IMPLEMENT CK_RV
5265 NSSCKFWC_UnwrapKey
5266 (
5267   NSSCKFWInstance *fwInstance,
5268   CK_SESSION_HANDLE hSession,
5269   CK_MECHANISM_PTR pMechanism,
5270   CK_OBJECT_HANDLE hUnwrappingKey,
5271   CK_BYTE_PTR pWrappedKey,
5272   CK_ULONG ulWrappedKeyLen,
5273   CK_ATTRIBUTE_PTR pTemplate,
5274   CK_ULONG ulAttributeCount,
5275   CK_OBJECT_HANDLE_PTR phKey
5276 )
5277 {
5278   CK_RV error = CKR_OK;
5279   NSSCKFWSession *fwSession;
5280   NSSCKFWObject *fwObject;
5281   NSSCKFWObject *fwWrappingKeyObject;
5282   NSSCKFWSlot  *fwSlot;
5283   NSSCKFWToken  *fwToken;
5284   NSSCKFWMechanism *fwMechanism;
5285   NSSItem  wrappedKey;
5286
5287   if (!fwInstance) {
5288     error = CKR_CRYPTOKI_NOT_INITIALIZED;
5289     goto loser;
5290   }
5291   
5292   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
5293   if (!fwSession) {
5294     error = CKR_SESSION_HANDLE_INVALID;
5295     goto loser;
5296   }
5297
5298   fwWrappingKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance,
5299                                                             hUnwrappingKey);
5300   if (!fwWrappingKeyObject) {
5301     error = CKR_WRAPPING_KEY_HANDLE_INVALID;
5302     goto loser;
5303   }
5304
5305   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
5306   if (!fwSlot) {
5307     error = CKR_GENERAL_ERROR; /* should never happen! */
5308     goto loser;
5309   }
5310
5311   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
5312     error = CKR_TOKEN_NOT_PRESENT;
5313     goto loser;
5314   }
5315
5316   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
5317   if (!fwToken) {
5318     goto loser;
5319   }
5320
5321   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
5322   if (!fwMechanism) {
5323     goto loser;
5324   }
5325
5326   wrappedKey.data = pWrappedKey;
5327   wrappedKey.size = ulWrappedKeyLen;
5328
5329   fwObject = nssCKFWMechanism_UnwrapKey(
5330                 fwMechanism, 
5331                 pMechanism, 
5332                 fwSession, 
5333                 fwWrappingKeyObject,
5334                 &wrappedKey,
5335                 pTemplate, 
5336                 ulAttributeCount, 
5337                 &error);
5338
5339   nssCKFWMechanism_Destroy(fwMechanism);
5340   if (!fwObject) {
5341     goto loser;
5342   }
5343   *phKey = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
5344
5345   if (CKR_OK == error) {
5346     return CKR_OK;
5347   }
5348
5349 loser:
5350   /* verify error */
5351   switch( error ) {
5352   case CKR_ARGUMENTS_BAD:
5353   case CKR_ATTRIBUTE_READ_ONLY:
5354   case CKR_ATTRIBUTE_TYPE_INVALID:
5355   case CKR_ATTRIBUTE_VALUE_INVALID:
5356   case CKR_BUFFER_TOO_SMALL:
5357   case CKR_CRYPTOKI_NOT_INITIALIZED:
5358   case CKR_DEVICE_ERROR:
5359   case CKR_DEVICE_MEMORY:
5360   case CKR_DEVICE_REMOVED:
5361   case CKR_DOMAIN_PARAMS_INVALID:
5362   case CKR_FUNCTION_CANCELED:
5363   case CKR_FUNCTION_FAILED:
5364   case CKR_GENERAL_ERROR:
5365   case CKR_HOST_MEMORY:
5366   case CKR_MECHANISM_INVALID:
5367   case CKR_MECHANISM_PARAM_INVALID:
5368   case CKR_OPERATION_ACTIVE:
5369   case CKR_PIN_EXPIRED:
5370   case CKR_SESSION_CLOSED:
5371   case CKR_SESSION_HANDLE_INVALID:
5372   case CKR_SESSION_READ_ONLY:
5373   case CKR_TEMPLATE_INCOMPLETE:
5374   case CKR_TEMPLATE_INCONSISTENT:
5375   case CKR_TOKEN_WRITE_PROTECTED:
5376   case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
5377   case CKR_UNWRAPPING_KEY_SIZE_RANGE:
5378   case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
5379   case CKR_USER_NOT_LOGGED_IN:
5380   case CKR_WRAPPED_KEY_INVALID:
5381   case CKR_WRAPPED_KEY_LEN_RANGE:
5382     break;
5383   case CKR_KEY_HANDLE_INVALID:
5384     error = CKR_UNWRAPPING_KEY_HANDLE_INVALID;
5385     break;
5386   case CKR_KEY_SIZE_RANGE:
5387     error = CKR_UNWRAPPING_KEY_SIZE_RANGE;
5388     break;
5389   case CKR_KEY_TYPE_INCONSISTENT:
5390     error = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
5391     break;
5392   case CKR_ENCRYPTED_DATA_INVALID:
5393     error = CKR_WRAPPED_KEY_INVALID;
5394     break;
5395   case CKR_ENCRYPTED_DATA_LEN_RANGE:
5396     error = CKR_WRAPPED_KEY_LEN_RANGE;
5397     break;
5398   default:
5399   case CKR_OK:
5400     error = CKR_GENERAL_ERROR;
5401     break;
5402   }
5403   return error;
5404 }
5405
5406 /*
5407  * NSSCKFWC_DeriveKey
5408  *
5409  */
5410 NSS_IMPLEMENT CK_RV
5411 NSSCKFWC_DeriveKey
5412 (
5413   NSSCKFWInstance *fwInstance,
5414   CK_SESSION_HANDLE hSession,
5415   CK_MECHANISM_PTR pMechanism,
5416   CK_OBJECT_HANDLE hBaseKey,
5417   CK_ATTRIBUTE_PTR pTemplate,
5418   CK_ULONG ulAttributeCount,
5419   CK_OBJECT_HANDLE_PTR phKey
5420 )
5421 {
5422   CK_RV error = CKR_OK;
5423   NSSCKFWSession *fwSession;
5424   NSSCKFWObject *fwObject;
5425   NSSCKFWObject *fwBaseKeyObject;
5426   NSSCKFWSlot  *fwSlot;
5427   NSSCKFWToken  *fwToken;
5428   NSSCKFWMechanism *fwMechanism;
5429
5430   if (!fwInstance) {
5431     error = CKR_CRYPTOKI_NOT_INITIALIZED;
5432     goto loser;
5433   }
5434   
5435   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
5436   if (!fwSession) {
5437     error = CKR_SESSION_HANDLE_INVALID;
5438     goto loser;
5439   }
5440
5441   fwBaseKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hBaseKey);
5442   if (!fwBaseKeyObject) {
5443     error = CKR_KEY_HANDLE_INVALID;
5444     goto loser;
5445   }
5446
5447   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
5448   if (!fwSlot) {
5449     error = CKR_GENERAL_ERROR; /* should never happen! */
5450     goto loser;
5451   }
5452
5453   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
5454     error = CKR_TOKEN_NOT_PRESENT;
5455     goto loser;
5456   }
5457
5458   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
5459   if (!fwToken) {
5460     goto loser;
5461   }
5462
5463   fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
5464   if (!fwMechanism) {
5465     goto loser;
5466   }
5467
5468   fwObject = nssCKFWMechanism_DeriveKey(
5469                 fwMechanism, 
5470                 pMechanism, 
5471                 fwSession, 
5472                 fwBaseKeyObject,
5473                 pTemplate, 
5474                 ulAttributeCount, 
5475                 &error);
5476
5477   nssCKFWMechanism_Destroy(fwMechanism);
5478   if (!fwObject) {
5479     goto loser;
5480   }
5481   *phKey = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
5482
5483   if (CKR_OK == error) {
5484     return CKR_OK;
5485   }
5486
5487 loser:
5488   /* verify error */
5489   switch( error ) {
5490   case CKR_ARGUMENTS_BAD:
5491   case CKR_ATTRIBUTE_READ_ONLY:
5492   case CKR_ATTRIBUTE_TYPE_INVALID:
5493   case CKR_ATTRIBUTE_VALUE_INVALID:
5494   case CKR_CRYPTOKI_NOT_INITIALIZED:
5495   case CKR_DEVICE_ERROR:
5496   case CKR_DEVICE_MEMORY:
5497   case CKR_DEVICE_REMOVED:
5498   case CKR_DOMAIN_PARAMS_INVALID:
5499   case CKR_FUNCTION_CANCELED:
5500   case CKR_FUNCTION_FAILED:
5501   case CKR_GENERAL_ERROR:
5502   case CKR_HOST_MEMORY:
5503   case CKR_KEY_HANDLE_INVALID:
5504   case CKR_KEY_SIZE_RANGE:
5505   case CKR_KEY_TYPE_INCONSISTENT:
5506   case CKR_MECHANISM_INVALID:
5507   case CKR_MECHANISM_PARAM_INVALID:
5508   case CKR_OPERATION_ACTIVE:
5509   case CKR_PIN_EXPIRED:
5510   case CKR_SESSION_CLOSED:
5511   case CKR_SESSION_HANDLE_INVALID:
5512   case CKR_SESSION_READ_ONLY:
5513   case CKR_TEMPLATE_INCOMPLETE:
5514   case CKR_TEMPLATE_INCONSISTENT:
5515   case CKR_TOKEN_WRITE_PROTECTED:
5516   case CKR_USER_NOT_LOGGED_IN:
5517     break;
5518   default:
5519   case CKR_OK:
5520     error = CKR_GENERAL_ERROR;
5521     break;
5522   }
5523   return error;
5524 }
5525
5526 /*
5527  * NSSCKFWC_SeedRandom
5528  *
5529  */
5530 NSS_IMPLEMENT CK_RV
5531 NSSCKFWC_SeedRandom
5532 (
5533   NSSCKFWInstance *fwInstance,
5534   CK_SESSION_HANDLE hSession,
5535   CK_BYTE_PTR pSeed,
5536   CK_ULONG ulSeedLen
5537 )
5538 {
5539   CK_RV error = CKR_OK;
5540   NSSCKFWSession *fwSession;
5541   NSSItem seed;
5542
5543   if (!fwInstance) {
5544     error = CKR_CRYPTOKI_NOT_INITIALIZED;
5545     goto loser;
5546   }
5547
5548   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
5549   if (!fwSession) {
5550     error = CKR_SESSION_HANDLE_INVALID;
5551     goto loser;
5552   }
5553
5554   if( (CK_BYTE_PTR)CK_NULL_PTR == pSeed ) {
5555     error = CKR_ARGUMENTS_BAD;
5556     goto loser;
5557   }
5558
5559   /* We could read through the buffer in a Purify trap */
5560
5561   seed.size = (PRUint32)ulSeedLen;
5562   seed.data = (void *)pSeed;
5563
5564   error = nssCKFWSession_SeedRandom(fwSession, &seed);
5565
5566   if( CKR_OK != error ) {
5567     goto loser;
5568   }
5569
5570   return CKR_OK;
5571
5572  loser:
5573   switch( error ) {
5574   case CKR_SESSION_CLOSED:
5575     /* destroy session? */
5576     break;
5577   case CKR_DEVICE_REMOVED:
5578     /* (void)nssCKFWToken_Destroy(fwToken); */
5579     break;
5580   case CKR_ARGUMENTS_BAD:
5581   case CKR_CRYPTOKI_NOT_INITIALIZED:
5582   case CKR_DEVICE_ERROR:
5583   case CKR_DEVICE_MEMORY:
5584   case CKR_FUNCTION_CANCELED:
5585   case CKR_FUNCTION_FAILED:
5586   case CKR_GENERAL_ERROR:
5587   case CKR_HOST_MEMORY:
5588   case CKR_OPERATION_ACTIVE:
5589   case CKR_RANDOM_SEED_NOT_SUPPORTED:
5590   case CKR_RANDOM_NO_RNG:
5591   case CKR_SESSION_HANDLE_INVALID:
5592   case CKR_USER_NOT_LOGGED_IN:
5593     break;
5594   default:
5595   case CKR_OK:
5596     error = CKR_GENERAL_ERROR;
5597     break;
5598   }
5599
5600   return error;
5601 }
5602
5603 /*
5604  * NSSCKFWC_GenerateRandom
5605  *
5606  */
5607 NSS_IMPLEMENT CK_RV
5608 NSSCKFWC_GenerateRandom
5609 (
5610   NSSCKFWInstance *fwInstance,
5611   CK_SESSION_HANDLE hSession,
5612   CK_BYTE_PTR pRandomData,
5613   CK_ULONG ulRandomLen
5614 )
5615 {
5616   CK_RV error = CKR_OK;
5617   NSSCKFWSession *fwSession;
5618   NSSItem buffer;
5619
5620   if (!fwInstance) {
5621     error = CKR_CRYPTOKI_NOT_INITIALIZED;
5622     goto loser;
5623   }
5624
5625   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
5626   if (!fwSession) {
5627     error = CKR_SESSION_HANDLE_INVALID;
5628     goto loser;
5629   }
5630
5631   if( (CK_BYTE_PTR)CK_NULL_PTR == pRandomData ) {
5632     error = CKR_ARGUMENTS_BAD;
5633     goto loser;
5634   }
5635
5636   /*
5637    * A purify error here indicates caller error.
5638    */
5639   (void)nsslibc_memset(pRandomData, 0, ulRandomLen);
5640
5641   buffer.size = (PRUint32)ulRandomLen;
5642   buffer.data = (void *)pRandomData;
5643
5644   error = nssCKFWSession_GetRandom(fwSession, &buffer);
5645
5646   if( CKR_OK != error ) {
5647     goto loser;
5648   }
5649
5650   return CKR_OK;
5651
5652  loser:
5653   switch( error ) {
5654   case CKR_SESSION_CLOSED:
5655     /* destroy session? */
5656     break;
5657   case CKR_DEVICE_REMOVED:
5658     /* (void)nssCKFWToken_Destroy(fwToken); */
5659     break;
5660   case CKR_ARGUMENTS_BAD:
5661   case CKR_CRYPTOKI_NOT_INITIALIZED:
5662   case CKR_DEVICE_ERROR:
5663   case CKR_DEVICE_MEMORY:
5664   case CKR_FUNCTION_CANCELED:
5665   case CKR_FUNCTION_FAILED:
5666   case CKR_GENERAL_ERROR:
5667   case CKR_HOST_MEMORY:
5668   case CKR_OPERATION_ACTIVE:
5669   case CKR_RANDOM_NO_RNG:
5670   case CKR_SESSION_HANDLE_INVALID:
5671   case CKR_USER_NOT_LOGGED_IN:
5672     break;
5673   default:
5674   case CKR_OK:
5675     error = CKR_GENERAL_ERROR;
5676     break;
5677   }
5678
5679   return error;
5680 }
5681
5682 /*
5683  * NSSCKFWC_GetFunctionStatus
5684  *
5685  */
5686 NSS_IMPLEMENT CK_RV
5687 NSSCKFWC_GetFunctionStatus
5688 (
5689   NSSCKFWInstance *fwInstance,
5690   CK_SESSION_HANDLE hSession
5691 )
5692 {
5693   return CKR_FUNCTION_NOT_PARALLEL;
5694 }
5695
5696 /*
5697  * NSSCKFWC_CancelFunction
5698  *
5699  */
5700 NSS_IMPLEMENT CK_RV
5701 NSSCKFWC_CancelFunction
5702 (
5703   NSSCKFWInstance *fwInstance,
5704   CK_SESSION_HANDLE hSession
5705 )
5706 {
5707   return CKR_FUNCTION_NOT_PARALLEL;
5708 }