tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

wrap.c (140607B)


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