/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 * This file implements PKCS 11 on top of our existing security modules
 *
 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
 *   This implementation has two slots:
 *      slot 1 is our generic crypto support. It does not require login.
 *   It supports Public Key ops, and all they bulk ciphers and hashes.
 *   It can also support Private Key ops for imported Private keys. It does
 *   not have any token storage.
 *      slot 2 is our private key support. It requires a login before use. It
 *   can store Private Keys and Certs as token objects. Currently only private
 *   keys and their associated Certificates are saved on the token.
 *
 *   In this implementation, session objects are only visible to the session
 *   that created or generated them.
 */
#include "seccomon.h"
#include "secitem.h"
#include "secport.h"
#include "blapi.h"
#include "pkcs11.h"
#include "pkcs11i.h"
#include "pkcs1sig.h"
#include "lowkeyi.h"
#include "secder.h"
#include "secdig.h"
#include "lowpbe.h" /* We do PBE below */
#include "pkcs11t.h"
#include "secoid.h"
#include "alghmac.h"
#include "softoken.h"
#include "secasn1.h"
#include "secerr.h"

#include "prprf.h"
#include "prenv.h"

#define __PASTE(x, y) x##y

/*
 * we renamed all our internal functions, get the correct
 * definitions for them...
 */
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST

#define CK_EXTERN extern
#define CK_PKCS11_FUNCTION_INFO(func) \
    CK_RV __PASTE(NS, func)
#define CK_NEED_ARG_LIST 1

#include "pkcs11f.h"

typedef struct {
    PRUint8 client_version[2];
    PRUint8 random[46];
} SSL3RSAPreMasterSecret;

static void
sftk_Null(void *data, PRBool freeit)
{
    return;
}

#ifdef EC_DEBUG
#define SEC_PRINT(str1, str2, num, sitem)             \
    printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \
           str1, str2, num, sitem->len);              \
    for (i = 0; i < sitem->len; i++) {                \
        printf("%02x:", sitem->data[i]);              \
    }                                                 \
    printf("\n")
#else
#undef EC_DEBUG
#define SEC_PRINT(a, b, c, d)
#endif

/*
 * free routines.... Free local type  allocated data, and convert
 * other free routines to the destroy signature.
 */
static void
sftk_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit)
{
    nsslowkey_DestroyPrivateKey(key);
}

static void
sftk_Space(void *data, PRBool freeit)
{
    PORT_Free(data);
}

/*
 * map all the SEC_ERROR_xxx error codes that may be returned by freebl
 * functions to CKR_xxx.  return CKR_DEVICE_ERROR by default for backward
 * compatibility.
 */
static CK_RV
sftk_MapCryptError(int error)
{
    switch (error) {
        case SEC_ERROR_INVALID_ARGS:
        case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */
            return CKR_ARGUMENTS_BAD;
        case SEC_ERROR_INPUT_LEN:
            return CKR_DATA_LEN_RANGE;
        case SEC_ERROR_OUTPUT_LEN:
            return CKR_BUFFER_TOO_SMALL;
        case SEC_ERROR_LIBRARY_FAILURE:
            return CKR_GENERAL_ERROR;
        case SEC_ERROR_NO_MEMORY:
            return CKR_HOST_MEMORY;
        case SEC_ERROR_BAD_SIGNATURE:
            return CKR_SIGNATURE_INVALID;
        case SEC_ERROR_INVALID_KEY:
            return CKR_KEY_SIZE_RANGE;
        case SEC_ERROR_BAD_KEY:        /* an EC public key that fails validation */
            return CKR_KEY_SIZE_RANGE; /* the closest error code */
        case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM:
            return CKR_TEMPLATE_INCONSISTENT;
        case SEC_ERROR_UNSUPPORTED_KEYALG:
            return CKR_MECHANISM_INVALID;
        case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE:
            return CKR_DOMAIN_PARAMS_INVALID;
        /* key pair generation failed after max number of attempts */
        case SEC_ERROR_NEED_RANDOM:
            return CKR_FUNCTION_FAILED;
    }
    return CKR_DEVICE_ERROR;
}

/* used by Decrypt and UnwrapKey (indirectly) */
static CK_RV
sftk_MapDecryptError(int error)
{
    switch (error) {
        case SEC_ERROR_BAD_DATA:
            return CKR_ENCRYPTED_DATA_INVALID;
        default:
            return sftk_MapCryptError(error);
    }
}

/*
 * return CKR_SIGNATURE_INVALID instead of CKR_DEVICE_ERROR by default for
 * backward compatibilty.
 */
static CK_RV
sftk_MapVerifyError(int error)
{
    CK_RV crv = sftk_MapCryptError(error);
    if (crv == CKR_DEVICE_ERROR)
        crv = CKR_SIGNATURE_INVALID;
    return crv;
}

/*
 * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
 * Deprecating a full des key to 40 bit key strenth.
 */
static CK_RV
sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
{
    unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae };
    unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 };
    unsigned char enc_src[8];
    unsigned char enc_dest[8];
    unsigned int leng, i;
    DESContext *descx;
    SECStatus rv;

    /* zero the parity bits */
    for (i = 0; i < 8; i++) {
        enc_src[i] = cdmfkey[i] & 0xfe;
    }

    /* encrypt with key 1 */
    descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE);
    if (descx == NULL)
        return CKR_HOST_MEMORY;
    rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8);
    DES_DestroyContext(descx, PR_TRUE);
    if (rv != SECSuccess)
        return sftk_MapCryptError(PORT_GetError());

    /* xor source with des, zero the parity bits and deprecate the key*/
    for (i = 0; i < 8; i++) {
        if (i & 1) {
            enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe;
        } else {
            enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e;
        }
    }

    /* encrypt with key 2 */
    descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE);
    if (descx == NULL)
        return CKR_HOST_MEMORY;
    rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8);
    DES_DestroyContext(descx, PR_TRUE);
    if (rv != SECSuccess)
        return sftk_MapCryptError(PORT_GetError());

    /* set the corret parity on our new des key */
    sftk_FormatDESKey(deskey, 8);
    return CKR_OK;
}

/* NSC_DestroyObject destroys an object. */
CK_RV
NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
{
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    SFTKSession *session;
    SFTKObject *object;
    SFTKFreeStatus status;

    CHECK_FORK();

    if (slot == NULL) {
        return CKR_SESSION_HANDLE_INVALID;
    }
    /*
     * This whole block just makes sure we really can destroy the
     * requested object.
     */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
        return CKR_SESSION_HANDLE_INVALID;
    }

    object = sftk_ObjectFromHandle(hObject, session);
    if (object == NULL) {
        sftk_FreeSession(session);
        return CKR_OBJECT_HANDLE_INVALID;
    }

    /* don't destroy a private object if we aren't logged in */
    if ((!slot->isLoggedIn) && (slot->needLogin) &&
        (sftk_isTrue(object, CKA_PRIVATE))) {
        sftk_FreeSession(session);
        sftk_FreeObject(object);
        return CKR_USER_NOT_LOGGED_IN;
    }

    /* don't destroy a token object if we aren't in a rw session */

    if (((session->info.flags & CKF_RW_SESSION) == 0) &&
        (sftk_isTrue(object, CKA_TOKEN))) {
        sftk_FreeSession(session);
        sftk_FreeObject(object);
        return CKR_SESSION_READ_ONLY;
    }

    sftk_DeleteObject(session, object);

    sftk_FreeSession(session);

    /*
     * get some indication if the object is destroyed. Note: this is not
     * 100%. Someone may have an object reference outstanding (though that
     * should not be the case by here. Also note that the object is "half"
     * destroyed. Our internal representation is destroyed, but it may still
     * be in the data base.
     */
    status = sftk_FreeObject(object);

    return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
}

/*
 ************** Crypto Functions:     Utilities ************************
 */
/*
 * Utility function for converting PSS/OAEP parameter types into
 * HASH_HashTypes. Note: Only SHA family functions are defined in RFC 3447.
 */
static HASH_HashType
GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
{
    switch (mech) {
        case CKM_SHA_1:
        case CKG_MGF1_SHA1:
            return HASH_AlgSHA1;
        case CKM_SHA224:
        case CKG_MGF1_SHA224:
            return HASH_AlgSHA224;
        case CKM_SHA256:
        case CKG_MGF1_SHA256:
            return HASH_AlgSHA256;
        case CKM_SHA384:
        case CKG_MGF1_SHA384:
            return HASH_AlgSHA384;
        case CKM_SHA512:
        case CKG_MGF1_SHA512:
            return HASH_AlgSHA512;
        default:
            return HASH_AlgNULL;
    }
}

/*
 * Returns true if "params" contains a valid set of PSS parameters
 */
static PRBool
sftk_ValidatePssParams(const CK_RSA_PKCS_PSS_PARAMS *params)
{
    if (!params) {
        return PR_FALSE;
    }
    if (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL ||
        GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) {
        return PR_FALSE;
    }
    return PR_TRUE;
}

/*
 * Returns true if "params" contains a valid set of OAEP parameters
 */
static PRBool
sftk_ValidateOaepParams(const CK_RSA_PKCS_OAEP_PARAMS *params)
{
    if (!params) {
        return PR_FALSE;
    }
    /* The requirements of ulSourceLen/pSourceData come from PKCS #11, which
     * state:
     *   If the parameter is empty, pSourceData must be NULL and
     *   ulSourceDataLen must be zero.
     */
    if (params->source != CKZ_DATA_SPECIFIED ||
        (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) ||
        (GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) ||
        (params->ulSourceDataLen == 0 && params->pSourceData != NULL) ||
        (params->ulSourceDataLen != 0 && params->pSourceData == NULL)) {
        return PR_FALSE;
    }
    return PR_TRUE;
}

/*
 * return a context based on the SFTKContext type.
 */
SFTKSessionContext *
sftk_ReturnContextByType(SFTKSession *session, SFTKContextType type)
{
    switch (type) {
        case SFTK_ENCRYPT:
        case SFTK_DECRYPT:
            return session->enc_context;
        case SFTK_HASH:
            return session->hash_context;
        case SFTK_SIGN:
        case SFTK_SIGN_RECOVER:
        case SFTK_VERIFY:
        case SFTK_VERIFY_RECOVER:
            return session->hash_context;
    }
    return NULL;
}

/*
 * change a context based on the SFTKContext type.
 */
void
sftk_SetContextByType(SFTKSession *session, SFTKContextType type,
                      SFTKSessionContext *context)
{
    switch (type) {
        case SFTK_ENCRYPT:
        case SFTK_DECRYPT:
            session->enc_context = context;
            break;
        case SFTK_HASH:
            session->hash_context = context;
            break;
        case SFTK_SIGN:
        case SFTK_SIGN_RECOVER:
        case SFTK_VERIFY:
        case SFTK_VERIFY_RECOVER:
            session->hash_context = context;
            break;
    }
    return;
}

/*
 * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal,
 * and C_XXX function. The function takes a session handle, the context type,
 * and wether or not the session needs to be multipart. It returns the context,
 * and optionally returns the session pointer (if sessionPtr != NULL) if session
 * pointer is returned, the caller is responsible for freeing it.
 */
static CK_RV
sftk_GetContext(CK_SESSION_HANDLE handle, SFTKSessionContext **contextPtr,
                SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr)
{
    SFTKSession *session;
    SFTKSessionContext *context;

    session = sftk_SessionFromHandle(handle);
    if (session == NULL)
        return CKR_SESSION_HANDLE_INVALID;
    context = sftk_ReturnContextByType(session, type);
    /* make sure the context is valid */
    if ((context == NULL) || (context->type != type) || (needMulti && !(context->multi))) {
        sftk_FreeSession(session);
        return CKR_OPERATION_NOT_INITIALIZED;
    }
    *contextPtr = context;
    if (sessionPtr != NULL) {
        *sessionPtr = session;
    } else {
        sftk_FreeSession(session);
    }
    return CKR_OK;
}

/** Terminate operation (in the PKCS#11 spec sense).
 *  Intuitive name for FreeContext/SetNullContext pair.
 */
static void
sftk_TerminateOp(SFTKSession *session, SFTKContextType ctype,
                 SFTKSessionContext *context)
{
    sftk_FreeContext(context);
    sftk_SetContextByType(session, ctype, NULL);
}

/*
 ************** Crypto Functions:     Encrypt ************************
 */

/*
 * All the NSC_InitXXX functions have a set of common checks and processing they
 * all need to do at the beginning. This is done here.
 */
static CK_RV
sftk_InitGeneric(SFTKSession *session, SFTKSessionContext **contextPtr,
                 SFTKContextType ctype, SFTKObject **keyPtr,
                 CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr,
                 CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation)
{
    SFTKObject *key = NULL;
    SFTKAttribute *att;
    SFTKSessionContext *context;

    /* We can only init if there is not current context active */
    if (sftk_ReturnContextByType(session, ctype) != NULL) {
        return CKR_OPERATION_ACTIVE;
    }

    /* find the key */
    if (keyPtr) {
        key = sftk_ObjectFromHandle(hKey, session);
        if (key == NULL) {
            return CKR_KEY_HANDLE_INVALID;
        }

        /* make sure it's a valid  key for this operation */
        if (((key->objclass != CKO_SECRET_KEY) && (key->objclass != pubKeyType)) || !sftk_isTrue(key, operation)) {
            sftk_FreeObject(key);
            return CKR_KEY_TYPE_INCONSISTENT;
        }
        /* get the key type */
        att = sftk_FindAttribute(key, CKA_KEY_TYPE);
        if (att == NULL) {
            sftk_FreeObject(key);
            return CKR_KEY_TYPE_INCONSISTENT;
        }
        PORT_Assert(att->attrib.ulValueLen == sizeof(CK_KEY_TYPE));
        if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) {
            sftk_FreeAttribute(att);
            sftk_FreeObject(key);
            return CKR_ATTRIBUTE_VALUE_INVALID;
        }
        PORT_Memcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE));
        sftk_FreeAttribute(att);
        *keyPtr = key;
    }

    /* allocate the context structure */
    context = (SFTKSessionContext *)PORT_Alloc(sizeof(SFTKSessionContext));
    if (context == NULL) {
        if (key)
            sftk_FreeObject(key);
        return CKR_HOST_MEMORY;
    }
    context->type = ctype;
    context->multi = PR_TRUE;
    context->rsa = PR_FALSE;
    context->cipherInfo = NULL;
    context->hashInfo = NULL;
    context->doPad = PR_FALSE;
    context->padDataLength = 0;
    context->key = key;
    context->blockSize = 0;
    context->maxLen = 0;

    *contextPtr = context;
    return CKR_OK;
}

static int
sftk_aes_mode(CK_MECHANISM_TYPE mechanism)
{
    switch (mechanism) {
        case CKM_AES_CBC_PAD:
        case CKM_AES_CBC:
            return NSS_AES_CBC;
        case CKM_AES_ECB:
            return NSS_AES;
        case CKM_AES_CTS:
            return NSS_AES_CTS;
        case CKM_AES_CTR:
            return NSS_AES_CTR;
        case CKM_AES_GCM:
            return NSS_AES_GCM;
    }
    return -1;
}

static SECStatus
sftk_RSAEncryptRaw(NSSLOWKEYPublicKey *key, unsigned char *output,
                   unsigned int *outputLen, unsigned int maxLen,
                   const unsigned char *input, unsigned int inputLen)
{
    SECStatus rv = SECFailure;

    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    rv = RSA_EncryptRaw(&key->u.rsa, output, outputLen, maxLen, input,
                        inputLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }

    return rv;
}

static SECStatus
sftk_RSADecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output,
                   unsigned int *outputLen, unsigned int maxLen,
                   const unsigned char *input, unsigned int inputLen)
{
    SECStatus rv = SECFailure;

    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    rv = RSA_DecryptRaw(&key->u.rsa, output, outputLen, maxLen, input,
                        inputLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }

    return rv;
}

static SECStatus
sftk_RSAEncrypt(NSSLOWKEYPublicKey *key, unsigned char *output,
                unsigned int *outputLen, unsigned int maxLen,
                const unsigned char *input, unsigned int inputLen)
{
    SECStatus rv = SECFailure;

    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    rv = RSA_EncryptBlock(&key->u.rsa, output, outputLen, maxLen, input,
                          inputLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }

    return rv;
}

static SECStatus
sftk_RSADecrypt(NSSLOWKEYPrivateKey *key, unsigned char *output,
                unsigned int *outputLen, unsigned int maxLen,
                const unsigned char *input, unsigned int inputLen)
{
    SECStatus rv = SECFailure;

    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    rv = RSA_DecryptBlock(&key->u.rsa, output, outputLen, maxLen, input,
                          inputLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }

    return rv;
}

static SECStatus
sftk_RSAEncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned char *output,
                    unsigned int *outputLen, unsigned int maxLen,
                    const unsigned char *input, unsigned int inputLen)
{
    HASH_HashType hashAlg;
    HASH_HashType maskHashAlg;

    PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
    if (info->key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    hashAlg = GetHashTypeFromMechanism(info->params->hashAlg);
    maskHashAlg = GetHashTypeFromMechanism(info->params->mgf);

    return RSA_EncryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg,
                           (const unsigned char *)info->params->pSourceData,
                           info->params->ulSourceDataLen, NULL, 0,
                           output, outputLen, maxLen, input, inputLen);
}

static SECStatus
sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output,
                    unsigned int *outputLen, unsigned int maxLen,
                    const unsigned char *input, unsigned int inputLen)
{
    SECStatus rv = SECFailure;
    HASH_HashType hashAlg;
    HASH_HashType maskHashAlg;

    PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
    if (info->key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    hashAlg = GetHashTypeFromMechanism(info->params->hashAlg);
    maskHashAlg = GetHashTypeFromMechanism(info->params->mgf);

    rv = RSA_DecryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg,
                         (const unsigned char *)info->params->pSourceData,
                         info->params->ulSourceDataLen,
                         output, outputLen, maxLen, input, inputLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }
    return rv;
}

static SFTKChaCha20Poly1305Info *
sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
                                    unsigned int keyLen,
                                    const CK_NSS_AEAD_PARAMS *params)
{
    SFTKChaCha20Poly1305Info *ctx;

    if (params->ulNonceLen != sizeof(ctx->nonce)) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        return NULL;
    }

    ctx = PORT_New(SFTKChaCha20Poly1305Info);
    if (ctx == NULL) {
        return NULL;
    }

    if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
                                     params->ulTagLen) != SECSuccess) {
        PORT_Free(ctx);
        return NULL;
    }

    PORT_Memcpy(ctx->nonce, params->pNonce, sizeof(ctx->nonce));

    /* AAD data and length must both be null, or both non-null. */
    PORT_Assert((params->pAAD == NULL) == (params->ulAADLen == 0));

    if (params->ulAADLen > sizeof(ctx->ad)) {
        /* Need to allocate an overflow buffer for the additional data. */
        ctx->adOverflow = (unsigned char *)PORT_Alloc(params->ulAADLen);
        if (!ctx->adOverflow) {
            PORT_Free(ctx);
            return NULL;
        }
        PORT_Memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
    } else {
        ctx->adOverflow = NULL;
        if (params->pAAD) {
            PORT_Memcpy(ctx->ad, params->pAAD, params->ulAADLen);
        }
    }
    ctx->adLen = params->ulAADLen;

    return ctx;
}

static void
sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx,
                                     PRBool freeit)
{
    ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE);
    if (ctx->adOverflow != NULL) {
        PORT_Free(ctx->adOverflow);
        ctx->adOverflow = NULL;
    }
    ctx->adLen = 0;
    if (freeit) {
        PORT_Free(ctx);
    }
}

static SECStatus
sftk_ChaCha20Poly1305_Encrypt(const SFTKChaCha20Poly1305Info *ctx,
                              unsigned char *output, unsigned int *outputLen,
                              unsigned int maxOutputLen,
                              const unsigned char *input, unsigned int inputLen)
{
    const unsigned char *ad = ctx->adOverflow;

    if (ad == NULL) {
        ad = ctx->ad;
    }

    return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
                                 maxOutputLen, input, inputLen, ctx->nonce,
                                 sizeof(ctx->nonce), ad, ctx->adLen);
}

static SECStatus
sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
                              unsigned char *output, unsigned int *outputLen,
                              unsigned int maxOutputLen,
                              const unsigned char *input, unsigned int inputLen)
{
    const unsigned char *ad = ctx->adOverflow;

    if (ad == NULL) {
        ad = ctx->ad;
    }

    return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
                                 maxOutputLen, input, inputLen, ctx->nonce,
                                 sizeof(ctx->nonce), ad, ctx->adLen);
}

/** NSC_CryptInit initializes an encryption/Decryption operation.
 *
 * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
 * Called by NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac) only for block
 *  ciphers MAC'ing.
 */
static CK_RV
sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
               CK_OBJECT_HANDLE hKey,
               CK_ATTRIBUTE_TYPE mechUsage, CK_ATTRIBUTE_TYPE keyUsage,
               SFTKContextType contextType, PRBool isEncrypt)
{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    SFTKAttribute *att;
    CK_RC2_CBC_PARAMS *rc2_param;
#if NSS_SOFTOKEN_DOES_RC5
    CK_RC5_CBC_PARAMS *rc5_param;
    SECItem rc5Key;
#endif
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    unsigned effectiveKeyLength;
    unsigned char newdeskey[24];
    PRBool useNewKey = PR_FALSE;
    int t;

    crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage);
    if (crv != CKR_OK)
        return crv;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL)
        return CKR_SESSION_HANDLE_INVALID;

    crv = sftk_InitGeneric(session, &context, contextType, &key, hKey, &key_type,
                           isEncrypt ? CKO_PUBLIC_KEY : CKO_PRIVATE_KEY, keyUsage);

    if (crv != CKR_OK) {
        sftk_FreeSession(session);
        return crv;
    }

    context->doPad = PR_FALSE;
    switch (pMechanism->mechanism) {
        case CKM_RSA_PKCS:
        case CKM_RSA_X_509:
            if (key_type != CKK_RSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            context->multi = PR_FALSE;
            context->rsa = PR_TRUE;
            if (isEncrypt) {
                NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key, CKK_RSA, &crv);
                if (pubKey == NULL) {
                    crv = CKR_KEY_HANDLE_INVALID;
                    break;
                }
                context->maxLen = nsslowkey_PublicModulusLen(pubKey);
                context->cipherInfo = (void *)pubKey;
                context->update = (SFTKCipher)(pMechanism->mechanism == CKM_RSA_X_509
                                                   ? sftk_RSAEncryptRaw
                                                   : sftk_RSAEncrypt);
            } else {
                NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key, CKK_RSA, &crv);
                if (privKey == NULL) {
                    crv = CKR_KEY_HANDLE_INVALID;
                    break;
                }
                context->maxLen = nsslowkey_PrivateModulusLen(privKey);
                context->cipherInfo = (void *)privKey;
                context->update = (SFTKCipher)(pMechanism->mechanism == CKM_RSA_X_509
                                                   ? sftk_RSADecryptRaw
                                                   : sftk_RSADecrypt);
            }
            context->destroy = sftk_Null;
            break;
        case CKM_RSA_PKCS_OAEP:
            if (key_type != CKK_RSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS) ||
                !sftk_ValidateOaepParams((CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter)) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            context->multi = PR_FALSE;
            context->rsa = PR_TRUE;
            if (isEncrypt) {
                SFTKOAEPEncryptInfo *info = PORT_New(SFTKOAEPEncryptInfo);
                if (info == NULL) {
                    crv = CKR_HOST_MEMORY;
                    break;
                }
                info->params = pMechanism->pParameter;
                info->key = sftk_GetPubKey(key, CKK_RSA, &crv);
                if (info->key == NULL) {
                    PORT_Free(info);
                    crv = CKR_KEY_HANDLE_INVALID;
                    break;
                }
                context->update = (SFTKCipher)sftk_RSAEncryptOAEP;
                context->maxLen = nsslowkey_PublicModulusLen(info->key);
                context->cipherInfo = info;
            } else {
                SFTKOAEPDecryptInfo *info = PORT_New(SFTKOAEPDecryptInfo);
                if (info == NULL) {
                    crv = CKR_HOST_MEMORY;
                    break;
                }
                info->params = pMechanism->pParameter;
                info->key = sftk_GetPrivKey(key, CKK_RSA, &crv);
                if (info->key == NULL) {
                    PORT_Free(info);
                    crv = CKR_KEY_HANDLE_INVALID;
                    break;
                }
                context->update = (SFTKCipher)sftk_RSADecryptOAEP;
                context->maxLen = nsslowkey_PrivateModulusLen(info->key);
                context->cipherInfo = info;
            }
            context->destroy = (SFTKDestroy)sftk_Space;
            break;
        case CKM_RC2_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_RC2_ECB:
        case CKM_RC2_CBC:
            context->blockSize = 8;
            if (key_type != CKK_RC2) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
            effectiveKeyLength = (rc2_param->ulEffectiveBits + 7) / 8;
            context->cipherInfo =
                RC2_CreateContext((unsigned char *)att->attrib.pValue,
                                  att->attrib.ulValueLen, rc2_param->iv,
                                  pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 : NSS_RC2_CBC, effectiveKeyLength);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? RC2_Encrypt : RC2_Decrypt);
            context->destroy = (SFTKDestroy)RC2_DestroyContext;
            break;
#if NSS_SOFTOKEN_DOES_RC5
        case CKM_RC5_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_RC5_ECB:
        case CKM_RC5_CBC:
            if (key_type != CKK_RC5) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
            context->blockSize = rc5_param->ulWordsize * 2;
            rc5Key.data = (unsigned char *)att->attrib.pValue;
            rc5Key.len = att->attrib.ulValueLen;
            context->cipherInfo = RC5_CreateContext(&rc5Key, rc5_param->ulRounds,
                                                    rc5_param->ulWordsize, rc5_param->pIv,
                                                    pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? RC5_Encrypt : RC5_Decrypt);
            context->destroy = (SFTKDestroy)RC5_DestroyContext;
            break;
#endif
        case CKM_RC4:
            if (key_type != CKK_RC4) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            context->cipherInfo =
                RC4_CreateContext((unsigned char *)att->attrib.pValue,
                                  att->attrib.ulValueLen);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY; /* WRONG !!! */
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? RC4_Encrypt : RC4_Decrypt);
            context->destroy = (SFTKDestroy)RC4_DestroyContext;
            break;
        case CKM_CDMF_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_CDMF_ECB:
        case CKM_CDMF_CBC:
            if (key_type != CKK_CDMF) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
            goto finish_des;
        case CKM_DES_ECB:
            if (key_type != CKK_DES) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            t = NSS_DES;
            goto finish_des;
        case CKM_DES_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_DES_CBC:
            if (key_type != CKK_DES) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            t = NSS_DES_CBC;
            goto finish_des;
        case CKM_DES3_ECB:
            if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            t = NSS_DES_EDE3;
            goto finish_des;
        case CKM_DES3_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_DES3_CBC:
            if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            t = NSS_DES_EDE3_CBC;
        finish_des:
            context->blockSize = 8;
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            if (key_type == CKK_DES2 &&
                (t == NSS_DES_EDE3_CBC || t == NSS_DES_EDE3)) {
                /* extend DES2 key to DES3 key. */
                memcpy(newdeskey, att->attrib.pValue, 16);
                memcpy(newdeskey + 16, newdeskey, 8);
                useNewKey = PR_TRUE;
            } else if (key_type == CKK_CDMF) {
                crv = sftk_cdmf2des((unsigned char *)att->attrib.pValue, newdeskey);
                if (crv != CKR_OK) {
                    sftk_FreeAttribute(att);
                    break;
                }
                useNewKey = PR_TRUE;
            }
            context->cipherInfo = DES_CreateContext(
                useNewKey ? newdeskey : (unsigned char *)att->attrib.pValue,
                (unsigned char *)pMechanism->pParameter, t, isEncrypt);
            if (useNewKey)
                memset(newdeskey, 0, sizeof newdeskey);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? DES_Encrypt : DES_Decrypt);
            context->destroy = (SFTKDestroy)DES_DestroyContext;
            break;
        case CKM_SEED_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_SEED_CBC:
            if (!pMechanism->pParameter ||
                pMechanism->ulParameterLen != 16) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
        /* fall thru */
        case CKM_SEED_ECB:
            context->blockSize = 16;
            if (key_type != CKK_SEED) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            context->cipherInfo = SEED_CreateContext(
                (unsigned char *)att->attrib.pValue,
                (unsigned char *)pMechanism->pParameter,
                pMechanism->mechanism == CKM_SEED_ECB ? NSS_SEED : NSS_SEED_CBC,
                isEncrypt);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? SEED_Encrypt : SEED_Decrypt);
            context->destroy = (SFTKDestroy)SEED_DestroyContext;
            break;

        case CKM_CAMELLIA_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_CAMELLIA_CBC:
            if (!pMechanism->pParameter ||
                pMechanism->ulParameterLen != 16) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
        /* fall thru */
        case CKM_CAMELLIA_ECB:
            context->blockSize = 16;
            if (key_type != CKK_CAMELLIA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            context->cipherInfo = Camellia_CreateContext(
                (unsigned char *)att->attrib.pValue,
                (unsigned char *)pMechanism->pParameter,
                pMechanism->mechanism ==
                        CKM_CAMELLIA_ECB
                    ? NSS_CAMELLIA
                    : NSS_CAMELLIA_CBC,
                isEncrypt, att->attrib.ulValueLen);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? Camellia_Encrypt : Camellia_Decrypt);
            context->destroy = (SFTKDestroy)Camellia_DestroyContext;
            break;

        case CKM_AES_CBC_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_AES_ECB:
        case CKM_AES_CBC:
            context->blockSize = 16;
        case CKM_AES_CTS:
        case CKM_AES_CTR:
        case CKM_AES_GCM:
            if (pMechanism->mechanism == CKM_AES_GCM) {
                context->multi = PR_FALSE;
            }
            if (key_type != CKK_AES) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            context->cipherInfo = AES_CreateContext(
                (unsigned char *)att->attrib.pValue,
                (unsigned char *)pMechanism->pParameter,
                sftk_aes_mode(pMechanism->mechanism),
                isEncrypt, att->attrib.ulValueLen, 16);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? AES_Encrypt : AES_Decrypt);
            context->destroy = (SFTKDestroy)AES_DestroyContext;
            break;

        case CKM_NSS_CHACHA20_POLY1305:
            if (pMechanism->ulParameterLen != sizeof(CK_NSS_AEAD_PARAMS)) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            context->multi = PR_FALSE;
            if (key_type != CKK_NSS_CHACHA20) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            context->cipherInfo = sftk_ChaCha20Poly1305_CreateContext(
                (unsigned char *)att->attrib.pValue, att->attrib.ulValueLen,
                (CK_NSS_AEAD_PARAMS *)pMechanism->pParameter);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = sftk_MapCryptError(PORT_GetError());
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? sftk_ChaCha20Poly1305_Encrypt : sftk_ChaCha20Poly1305_Decrypt);
            context->destroy = (SFTKDestroy)sftk_ChaCha20Poly1305_DestroyContext;
            break;

        case CKM_NSS_AES_KEY_WRAP_PAD:
            context->doPad = PR_TRUE;
        /* fall thru */
        case CKM_NSS_AES_KEY_WRAP:
            context->multi = PR_FALSE;
            context->blockSize = 8;
            if (key_type != CKK_AES) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att = sftk_FindAttribute(key, CKA_VALUE);
            if (att == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            context->cipherInfo = AESKeyWrap_CreateContext(
                (unsigned char *)att->attrib.pValue,
                (unsigned char *)pMechanism->pParameter,
                isEncrypt, att->attrib.ulValueLen);
            sftk_FreeAttribute(att);
            if (context->cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->update = (SFTKCipher)(isEncrypt ? AESKeyWrap_Encrypt
                                                     : AESKeyWrap_Decrypt);
            context->destroy = (SFTKDestroy)AESKeyWrap_DestroyContext;
            break;

        default:
            crv = CKR_MECHANISM_INVALID;
            break;
    }

    if (crv != CKR_OK) {
        sftk_FreeContext(context);
        sftk_FreeSession(session);
        return crv;
    }
    sftk_SetContextByType(session, contextType, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

/* NSC_EncryptInit initializes an encryption operation. */
CK_RV
NSC_EncryptInit(CK_SESSION_HANDLE hSession,
                CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
    CHECK_FORK();
    return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT, CKA_ENCRYPT,
                          SFTK_ENCRYPT, PR_TRUE);
}

/* NSC_EncryptUpdate continues a multiple-part encryption operation. */
CK_RV
NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
                  CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
                  CK_ULONG_PTR pulEncryptedPartLen)
{
    SFTKSessionContext *context;
    unsigned int outlen, i;
    unsigned int padoutlen = 0;
    unsigned int maxout = *pulEncryptedPartLen;
    CK_RV crv;
    SECStatus rv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE, NULL);
    if (crv != CKR_OK)
        return crv;

    if (!pEncryptedPart) {
        if (context->doPad) {
            CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength;
            CK_ULONG blocksToSend = totalDataAvailable / context->blockSize;

            *pulEncryptedPartLen = blocksToSend * context->blockSize;
            return CKR_OK;
        }
        *pulEncryptedPartLen = ulPartLen;
        return CKR_OK;
    }

    /* do padding */
    if (context->doPad) {
        /* deal with previous buffered data */
        if (context->padDataLength != 0) {
            /* fill in the padded to a full block size */
            for (i = context->padDataLength;
                 (ulPartLen != 0) && i < context->blockSize; i++) {
                context->padBuf[i] = *pPart++;
                ulPartLen--;
                context->padDataLength++;
            }

            /* not enough data to encrypt yet? then return */
            if (context->padDataLength != context->blockSize) {
                *pulEncryptedPartLen = 0;
                return CKR_OK;
            }
            /* encrypt the current padded data */
            rv = (*context->update)(context->cipherInfo, pEncryptedPart,
                                    &padoutlen, context->blockSize, context->padBuf,
                                    context->blockSize);
            if (rv != SECSuccess) {
                return sftk_MapCryptError(PORT_GetError());
            }
            pEncryptedPart += padoutlen;
            maxout -= padoutlen;
        }
        /* save the residual */
        context->padDataLength = ulPartLen % context->blockSize;
        if (context->padDataLength) {
            PORT_Memcpy(context->padBuf,
                        &pPart[ulPartLen - context->padDataLength],
                        context->padDataLength);
            ulPartLen -= context->padDataLength;
        }
        /* if we've exhausted our new buffer, we're done */
        if (ulPartLen == 0) {
            *pulEncryptedPartLen = padoutlen;
            return CKR_OK;
        }
    }

    /* do it: NOTE: this assumes buf size in is >= buf size out! */
    rv = (*context->update)(context->cipherInfo, pEncryptedPart,
                            &outlen, maxout, pPart, ulPartLen);
    *pulEncryptedPartLen = (CK_ULONG)(outlen + padoutlen);
    return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/* NSC_EncryptFinal finishes a multiple-part encryption operation. */
CK_RV
NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
                 CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen, i;
    unsigned int maxout = *pulLastEncryptedPartLen;
    CK_RV crv;
    SECStatus rv = SECSuccess;
    PRBool contextFinished = PR_TRUE;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE, &session);
    if (crv != CKR_OK)
        return crv;

    *pulLastEncryptedPartLen = 0;
    if (!pLastEncryptedPart) {
        /* caller is checking the amount of remaining data */
        if (context->blockSize > 0 && context->doPad) {
            *pulLastEncryptedPartLen = context->blockSize;
            contextFinished = PR_FALSE; /* still have padding to go */
        }
        goto finish;
    }

    /* do padding */
    if (context->doPad) {
        unsigned char padbyte = (unsigned char)(context->blockSize - context->padDataLength);
        /* fill out rest of pad buffer with pad magic*/
        for (i = context->padDataLength; i < context->blockSize; i++) {
            context->padBuf[i] = padbyte;
        }
        rv = (*context->update)(context->cipherInfo, pLastEncryptedPart,
                                &outlen, maxout, context->padBuf, context->blockSize);
        if (rv == SECSuccess)
            *pulLastEncryptedPartLen = (CK_ULONG)outlen;
    }

finish:
    if (contextFinished)
        sftk_TerminateOp(session, SFTK_ENCRYPT, context);
    sftk_FreeSession(session);
    return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/* NSC_Encrypt encrypts single-part data. */
CK_RV
NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
            CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
            CK_ULONG_PTR pulEncryptedDataLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulEncryptedDataLen;
    CK_RV crv;
    CK_RV crv2;
    SECStatus rv = SECSuccess;
    SECItem pText;

    pText.type = siBuffer;
    pText.data = pData;
    pText.len = ulDataLen;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_FALSE, &session);
    if (crv != CKR_OK)
        return crv;

    if (!pEncryptedData) {
        *pulEncryptedDataLen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize;
        goto finish;
    }

    if (context->doPad) {
        if (context->multi) {
            CK_ULONG finalLen;
            /* padding is fairly complicated, have the update and final
             * code deal with it */
            sftk_FreeSession(session);
            crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData,
                                    pulEncryptedDataLen);
            if (crv != CKR_OK)
                *pulEncryptedDataLen = 0;
            maxoutlen -= *pulEncryptedDataLen;
            pEncryptedData += *pulEncryptedDataLen;
            finalLen = maxoutlen;
            crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
            if (crv2 == CKR_OK)
                *pulEncryptedDataLen += finalLen;
            return crv == CKR_OK ? crv2 : crv;
        }
        /* doPad without multi means that padding must be done on the first
        ** and only update.  There will be no final.
        */
        PORT_Assert(context->blockSize > 1);
        if (context->blockSize > 1) {
            CK_ULONG remainder = ulDataLen % context->blockSize;
            CK_ULONG padding = context->blockSize - remainder;
            pText.len += padding;
            pText.data = PORT_ZAlloc(pText.len);
            if (pText.data) {
                memcpy(pText.data, pData, ulDataLen);
                memset(pText.data + ulDataLen, padding, padding);
            } else {
                crv = CKR_HOST_MEMORY;
                goto fail;
            }
        }
    }

    /* do it: NOTE: this assumes buf size is big enough. */
    rv = (*context->update)(context->cipherInfo, pEncryptedData,
                            &outlen, maxoutlen, pText.data, pText.len);
    crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
    *pulEncryptedDataLen = (CK_ULONG)outlen;
    if (pText.data != pData)
        PORT_ZFree(pText.data, pText.len);
fail:
    sftk_TerminateOp(session, SFTK_ENCRYPT, context);
finish:
    sftk_FreeSession(session);

    return crv;
}

/*
 ************** Crypto Functions:     Decrypt ************************
 */

/* NSC_DecryptInit initializes a decryption operation. */
CK_RV
NSC_DecryptInit(CK_SESSION_HANDLE hSession,
                CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
    CHECK_FORK();
    return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT, CKA_DECRYPT,
                          SFTK_DECRYPT, PR_FALSE);
}

/* NSC_DecryptUpdate continues a multiple-part decryption operation. */
CK_RV
NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
                  CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
                  CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
{
    SFTKSessionContext *context;
    unsigned int padoutlen = 0;
    unsigned int outlen;
    unsigned int maxout = *pulPartLen;
    CK_RV crv;
    SECStatus rv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE, NULL);
    if (crv != CKR_OK)
        return crv;

    /* this can only happen on an NSS programming error */
    PORT_Assert((context->padDataLength == 0) || context->padDataLength == context->blockSize);

    if (context->doPad) {
        /* Check the data length for block ciphers. If we are padding,
         * then we must be using a block cipher. In the non-padding case
         * the error will be returned by the underlying decryption
         * function when we do the actual decrypt. We need to do the
         * check here to avoid returning a negative length to the caller
         * or reading before the beginning of the pEncryptedPart buffer.
         */
        if ((ulEncryptedPartLen == 0) ||
            (ulEncryptedPartLen % context->blockSize) != 0) {
            return CKR_ENCRYPTED_DATA_LEN_RANGE;
        }
    }

    if (!pPart) {
        if (context->doPad) {
            *pulPartLen =
                ulEncryptedPartLen + context->padDataLength - context->blockSize;
            return CKR_OK;
        }
        /* for stream ciphers there is are no constraints on ulEncryptedPartLen.
         * for block ciphers, it must be a multiple of blockSize. The error is
         * detected when this function is called again do decrypt the output.
         */
        *pulPartLen = ulEncryptedPartLen;
        return CKR_OK;
    }

    if (context->doPad) {
        /* first decrypt our saved buffer */
        if (context->padDataLength != 0) {
            rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
                                    maxout, context->padBuf, context->blockSize);
            if (rv != SECSuccess)
                return sftk_MapDecryptError(PORT_GetError());
            pPart += padoutlen;
            maxout -= padoutlen;
        }
        /* now save the final block for the next decrypt or the final */
        PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize],
                    context->blockSize);
        context->padDataLength = context->blockSize;
        ulEncryptedPartLen -= context->padDataLength;
    }

    /* do it: NOTE: this assumes buf size in is >= buf size out! */
    rv = (*context->update)(context->cipherInfo, pPart, &outlen,
                            maxout, pEncryptedPart, ulEncryptedPartLen);
    *pulPartLen = (CK_ULONG)(outlen + padoutlen);
    return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
}

/* NSC_DecryptFinal finishes a multiple-part decryption operation. */
CK_RV
NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
                 CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxout = *pulLastPartLen;
    CK_RV crv;
    SECStatus rv = SECSuccess;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE, &session);
    if (crv != CKR_OK)
        return crv;

    *pulLastPartLen = 0;
    if (!pLastPart) {
        /* caller is checking the amount of remaining data */
        if (context->padDataLength > 0) {
            *pulLastPartLen = context->padDataLength;
        }
        goto finish;
    }

    if (context->doPad) {
        /* decrypt our saved buffer */
        if (context->padDataLength != 0) {
            /* this assumes that pLastPart is big enough to hold the *whole*
             * buffer!!! */
            rv = (*context->update)(context->cipherInfo, pLastPart, &outlen,
                                    maxout, context->padBuf, context->blockSize);
            if (rv != SECSuccess) {
                crv = sftk_MapDecryptError(PORT_GetError());
            } else {
                unsigned int padSize =
                    (unsigned int)pLastPart[context->blockSize - 1];
                if ((padSize > context->blockSize) || (padSize == 0)) {
                    crv = CKR_ENCRYPTED_DATA_INVALID;
                } else {
                    unsigned int i;
                    unsigned int badPadding = 0; /* used as a boolean */
                    for (i = 0; i < padSize; i++) {
                        badPadding |=
                            (unsigned int)pLastPart[context->blockSize - 1 - i] ^
                            padSize;
                    }
                    if (badPadding) {
                        crv = CKR_ENCRYPTED_DATA_INVALID;
                    } else {
                        *pulLastPartLen = outlen - padSize;
                    }
                }
            }
        }
    }

    sftk_TerminateOp(session, SFTK_DECRYPT, context);
finish:
    sftk_FreeSession(session);
    return crv;
}

/* NSC_Decrypt decrypts encrypted data in a single part. */
CK_RV
NSC_Decrypt(CK_SESSION_HANDLE hSession,
            CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,
            CK_ULONG_PTR pulDataLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulDataLen;
    CK_RV crv;
    CK_RV crv2;
    SECStatus rv = SECSuccess;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_FALSE, &session);
    if (crv != CKR_OK)
        return crv;

    if (!pData) {
        *pulDataLen = ulEncryptedDataLen + context->blockSize;
        goto finish;
    }

    if (context->doPad && context->multi) {
        CK_ULONG finalLen;
        /* padding is fairly complicated, have the update and final
         * code deal with it */
        sftk_FreeSession(session);
        crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
                                pData, pulDataLen);
        if (crv != CKR_OK)
            *pulDataLen = 0;
        maxoutlen -= *pulDataLen;
        pData += *pulDataLen;
        finalLen = maxoutlen;
        crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
        if (crv2 == CKR_OK)
            *pulDataLen += finalLen;
        return crv == CKR_OK ? crv2 : crv;
    }

    rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
                            pEncryptedData, ulEncryptedDataLen);
    /* XXX need to do MUCH better error mapping than this. */
    crv = (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
    if (rv == SECSuccess && context->doPad) {
        unsigned int padding = pData[outlen - 1];
        if (padding > context->blockSize || !padding) {
            crv = CKR_ENCRYPTED_DATA_INVALID;
        } else {
            unsigned int i;
            unsigned int badPadding = 0; /* used as a boolean */
            for (i = 0; i < padding; i++) {
                badPadding |= (unsigned int)pData[outlen - 1 - i] ^ padding;
            }
            if (badPadding) {
                crv = CKR_ENCRYPTED_DATA_INVALID;
            } else {
                outlen -= padding;
            }
        }
    }
    *pulDataLen = (CK_ULONG)outlen;
    sftk_TerminateOp(session, SFTK_DECRYPT, context);
finish:
    sftk_FreeSession(session);
    return crv;
}

/*
 ************** Crypto Functions:     Digest (HASH)  ************************
 */

/* NSC_DigestInit initializes a message-digesting operation. */
CK_RV
NSC_DigestInit(CK_SESSION_HANDLE hSession,
               CK_MECHANISM_PTR pMechanism)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    CK_RV crv = CKR_OK;

    CHECK_FORK();

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL)
        return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session, &context, SFTK_HASH, NULL, 0, NULL, 0, 0);
    if (crv != CKR_OK) {
        sftk_FreeSession(session);
        return crv;
    }

#define INIT_MECH(mech, mmm)                                   \
    case mech: {                                               \
        mmm##Context *mmm##_ctx = mmm##_NewContext();          \
        context->cipherInfo = (void *)mmm##_ctx;               \
        context->cipherInfoLen = mmm##_FlattenSize(mmm##_ctx); \
        context->currentMech = mech;                           \
        context->hashUpdate = (SFTKHash)mmm##_Update;          \
        context->end = (SFTKEnd)mmm##_End;                     \
        context->destroy = (SFTKDestroy)mmm##_DestroyContext;  \
        context->maxLen = mmm##_LENGTH;                        \
        if (mmm##_ctx)                                         \
            mmm##_Begin(mmm##_ctx);                            \
        else                                                   \
            crv = CKR_HOST_MEMORY;                             \
        break;                                                 \
    }

    switch (pMechanism->mechanism) {
        INIT_MECH(CKM_MD2, MD2)
        INIT_MECH(CKM_MD5, MD5)
        INIT_MECH(CKM_SHA_1, SHA1)
        INIT_MECH(CKM_SHA224, SHA224)
        INIT_MECH(CKM_SHA256, SHA256)
        INIT_MECH(CKM_SHA384, SHA384)
        INIT_MECH(CKM_SHA512, SHA512)

        default:
            crv = CKR_MECHANISM_INVALID;
            break;
    }

    if (crv != CKR_OK) {
        sftk_FreeContext(context);
        sftk_FreeSession(session);
        return crv;
    }
    sftk_SetContextByType(session, SFTK_HASH, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

/* NSC_Digest digests data in a single part. */
CK_RV
NSC_Digest(CK_SESSION_HANDLE hSession,
           CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest,
           CK_ULONG_PTR pulDigestLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int digestLen;
    unsigned int maxout = *pulDigestLen;
    CK_RV crv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_FALSE, &session);
    if (crv != CKR_OK)
        return crv;

    if (pDigest == NULL) {
        *pulDigestLen = context->maxLen;
        goto finish;
    }

    /* do it: */
    (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen);
    /*  NOTE: this assumes buf size is bigenough for the algorithm */
    (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
    *pulDigestLen = digestLen;

    sftk_TerminateOp(session, SFTK_HASH, context);
finish:
    sftk_FreeSession(session);
    return CKR_OK;
}

/* NSC_DigestUpdate continues a multiple-part message-digesting operation. */
CK_RV
NSC_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
                 CK_ULONG ulPartLen)
{
    SFTKSessionContext *context;
    CK_RV crv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, NULL);
    if (crv != CKR_OK)
        return crv;
    /* do it: */
    (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen);
    return CKR_OK;
}

/* NSC_DigestFinal finishes a multiple-part message-digesting operation. */
CK_RV
NSC_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
                CK_ULONG_PTR pulDigestLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int maxout = *pulDigestLen;
    unsigned int digestLen;
    CK_RV crv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
    if (crv != CKR_OK)
        return crv;

    if (pDigest != NULL) {
        (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
        *pulDigestLen = digestLen;
        sftk_TerminateOp(session, SFTK_HASH, context);
    } else {
        *pulDigestLen = context->maxLen;
    }

    sftk_FreeSession(session);
    return CKR_OK;
}

/*
 * these helper functions are used by Generic Macing and Signing functions
 * that use hashes as part of their operations.
 */
#define DOSUB(mmm)                                                \
    static CK_RV                                                  \
        sftk_doSub##mmm(SFTKSessionContext *context)              \
    {                                                             \
        mmm##Context *mmm##_ctx = mmm##_NewContext();             \
        context->hashInfo = (void *)mmm##_ctx;                    \
        context->hashUpdate = (SFTKHash)mmm##_Update;             \
        context->end = (SFTKEnd)mmm##_End;                        \
        context->hashdestroy = (SFTKDestroy)mmm##_DestroyContext; \
        if (!context->hashInfo) {                                 \
            return CKR_HOST_MEMORY;                               \
        }                                                         \
        mmm##_Begin(mmm##_ctx);                                   \
        return CKR_OK;                                            \
    }

DOSUB(MD2)
DOSUB(MD5)
DOSUB(SHA1)
DOSUB(SHA224)
DOSUB(SHA256)
DOSUB(SHA384)
DOSUB(SHA512)

static SECStatus
sftk_SignCopy(
    CK_ULONG *copyLen,
    void *out, unsigned int *outLength,
    unsigned int maxLength,
    const unsigned char *hashResult,
    unsigned int hashResultLength)
{
    unsigned int toCopy = *copyLen;
    if (toCopy > maxLength) {
        toCopy = maxLength;
    }
    if (toCopy > hashResultLength) {
        toCopy = hashResultLength;
    }
    memcpy(out, hashResult, toCopy);
    if (outLength) {
        *outLength = toCopy;
    }
    return SECSuccess;
}

/* Verify is just a compare for HMAC */
static SECStatus
sftk_HMACCmp(CK_ULONG *copyLen, unsigned char *sig, unsigned int sigLen,
             unsigned char *hash, unsigned int hashLen)
{
    return (PORT_Memcmp(sig, hash, *copyLen) == 0) ? SECSuccess : SECFailure;
}

/*
 * common HMAC initalization routine
 */
static CK_RV
sftk_doHMACInit(SFTKSessionContext *context, HASH_HashType hash,
                SFTKObject *key, CK_ULONG mac_size)
{
    SFTKAttribute *keyval;
    HMACContext *HMACcontext;
    CK_ULONG *intpointer;
    const SECHashObject *hashObj = HASH_GetRawHashObject(hash);
    PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);

    /* required by FIPS 198 Section 4 */
    if (isFIPS && (mac_size < 4 || mac_size < hashObj->length / 2)) {
        return CKR_BUFFER_TOO_SMALL;
    }

    keyval = sftk_FindAttribute(key, CKA_VALUE);
    if (keyval == NULL)
        return CKR_KEY_SIZE_RANGE;

    HMACcontext = HMAC_Create(hashObj,
                              (const unsigned char *)keyval->attrib.pValue,
                              keyval->attrib.ulValueLen, isFIPS);
    context->hashInfo = HMACcontext;
    context->multi = PR_TRUE;
    sftk_FreeAttribute(keyval);
    if (context->hashInfo == NULL) {
        if (PORT_GetError() == SEC_ERROR_INVALID_ARGS) {
            return CKR_KEY_SIZE_RANGE;
        }
        return CKR_HOST_MEMORY;
    }
    context->hashUpdate = (SFTKHash)HMAC_Update;
    context->end = (SFTKEnd)HMAC_Finish;

    context->hashdestroy = (SFTKDestroy)HMAC_Destroy;
    intpointer = PORT_New(CK_ULONG);
    if (intpointer == NULL) {
        return CKR_HOST_MEMORY;
    }
    *intpointer = mac_size;
    context->cipherInfo = intpointer;
    context->destroy = (SFTKDestroy)sftk_Space;
    context->update = (SFTKCipher)sftk_SignCopy;
    context->verify = (SFTKVerify)sftk_HMACCmp;
    context->maxLen = hashObj->length;
    HMAC_Begin(HMACcontext);
    return CKR_OK;
}

/*
 *  SSL Macing support. SSL Macs are inited, then update with the base
 * hashing algorithm, then finalized in sign and verify
 */

/*
 * FROM SSL:
 * 60 bytes is 3 times the maximum length MAC size that is supported.
 * We probably should have one copy of this table. We still need this table
 * in ssl to 'sign' the handshake hashes.
 */
static unsigned char ssl_pad_1[60] = {
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36
};
static unsigned char ssl_pad_2[60] = {
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c
};

static SECStatus
sftk_SSLMACSign(SFTKSSLMACInfo *info, unsigned char *sig, unsigned int *sigLen,
                unsigned int maxLen, unsigned char *hash, unsigned int hashLen)
{
    unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
    unsigned int out;

    info->begin(info->hashContext);
    info->update(info->hashContext, info->key, info->keySize);
    info->update(info->hashContext, ssl_pad_2, info->padSize);
    info->update(info->hashContext, hash, hashLen);
    info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH);
    PORT_Memcpy(sig, tmpBuf, info->macSize);
    *sigLen = info->macSize;
    return SECSuccess;
}

static SECStatus
sftk_SSLMACVerify(SFTKSSLMACInfo *info, unsigned char *sig, unsigned int sigLen,
                  unsigned char *hash, unsigned int hashLen)
{
    unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
    unsigned int out;

    info->begin(info->hashContext);
    info->update(info->hashContext, info->key, info->keySize);
    info->update(info->hashContext, ssl_pad_2, info->padSize);
    info->update(info->hashContext, hash, hashLen);
    info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH);
    return (PORT_Memcmp(sig, tmpBuf, info->macSize) == 0) ? SECSuccess : SECFailure;
}

/*
 * common HMAC initalization routine
 */
static CK_RV
sftk_doSSLMACInit(SFTKSessionContext *context, SECOidTag oid,
                  SFTKObject *key, CK_ULONG mac_size)
{
    SFTKAttribute *keyval;
    SFTKBegin begin;
    int padSize;
    SFTKSSLMACInfo *sslmacinfo;
    CK_RV crv = CKR_MECHANISM_INVALID;

    if (oid == SEC_OID_SHA1) {
        crv = sftk_doSubSHA1(context);
        if (crv != CKR_OK)
            return crv;
        begin = (SFTKBegin)SHA1_Begin;
        padSize = 40;
    } else {
        crv = sftk_doSubMD5(context);
        if (crv != CKR_OK)
            return crv;
        begin = (SFTKBegin)MD5_Begin;
        padSize = 48;
    }
    context->multi = PR_TRUE;

    keyval = sftk_FindAttribute(key, CKA_VALUE);
    if (keyval == NULL)
        return CKR_KEY_SIZE_RANGE;

    context->hashUpdate(context->hashInfo, keyval->attrib.pValue,
                        keyval->attrib.ulValueLen);
    context->hashUpdate(context->hashInfo, ssl_pad_1, padSize);
    sslmacinfo = (SFTKSSLMACInfo *)PORT_Alloc(sizeof(SFTKSSLMACInfo));
    if (sslmacinfo == NULL) {
        sftk_FreeAttribute(keyval);
        return CKR_HOST_MEMORY;
    }
    sslmacinfo->macSize = mac_size;
    sslmacinfo->hashContext = context->hashInfo;
    PORT_Memcpy(sslmacinfo->key, keyval->attrib.pValue,
                keyval->attrib.ulValueLen);
    sslmacinfo->keySize = keyval->attrib.ulValueLen;
    sslmacinfo->begin = begin;
    sslmacinfo->end = context->end;
    sslmacinfo->update = context->hashUpdate;
    sslmacinfo->padSize = padSize;
    sftk_FreeAttribute(keyval);
    context->cipherInfo = (void *)sslmacinfo;
    context->destroy = (SFTKDestroy)sftk_Space;
    context->update = (SFTKCipher)sftk_SSLMACSign;
    context->verify = (SFTKVerify)sftk_SSLMACVerify;
    context->maxLen = mac_size;
    return CKR_OK;
}

/*
 ************** Crypto Functions:     Sign  ************************
 */

/**
 * Check if We're using CBCMacing and initialize the session context if we are.
 *  @param contextType SFTK_SIGN or SFTK_VERIFY
 *  @param keyUsage    check whether key allows this usage
 */
static CK_RV
sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
                CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage,
                SFTKContextType contextType)

{
    CK_MECHANISM cbc_mechanism;
    CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE;
    CK_RC2_CBC_PARAMS rc2_params;
#if NSS_SOFTOKEN_DOES_RC5
    CK_RC5_CBC_PARAMS rc5_params;
    CK_RC5_MAC_GENERAL_PARAMS *rc5_mac;
#endif
    unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE];
    SFTKSessionContext *context;
    CK_RV crv;
    unsigned int blockSize;

    switch (pMechanism->mechanism) {
        case CKM_RC2_MAC_GENERAL:
            if (!pMechanism->pParameter) {
                return CKR_MECHANISM_PARAM_INVALID;
            }
            mac_bytes =
                ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
        /* fall through */
        case CKM_RC2_MAC:
            /* this works because ulEffectiveBits is in the same place in both the
             * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */
            rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *)
                                              pMechanism->pParameter)
                                             ->ulEffectiveBits;
            PORT_Memset(rc2_params.iv, 0, sizeof(rc2_params.iv));
            cbc_mechanism.mechanism = CKM_RC2_CBC;
            cbc_mechanism.pParameter = &rc2_params;
            cbc_mechanism.ulParameterLen = sizeof(rc2_params);
            blockSize = 8;
            break;
#if NSS_SOFTOKEN_DOES_RC5
        case CKM_RC5_MAC_GENERAL:
            mac_bytes =
                ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
        /* fall through */
        case CKM_RC5_MAC:
            /* this works because ulEffectiveBits is in the same place in both the
             * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */
            rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter;
            rc5_params.ulWordsize = rc5_mac->ulWordsize;
            rc5_params.ulRounds = rc5_mac->ulRounds;
            rc5_params.pIv = ivBlock;
            if ((blockSize = rc5_mac->ulWordsize * 2) > SFTK_MAX_BLOCK_SIZE)
                return CKR_MECHANISM_PARAM_INVALID;
            rc5_params.ulIvLen = blockSize;
            PORT_Memset(ivBlock, 0, blockSize);
            cbc_mechanism.mechanism = CKM_RC5_CBC;
            cbc_mechanism.pParameter = &rc5_params;
            cbc_mechanism.ulParameterLen = sizeof(rc5_params);
            break;
#endif
        /* add cast and idea later */
        case CKM_DES_MAC_GENERAL:
            mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
        /* fall through */
        case CKM_DES_MAC:
            blockSize = 8;
            PORT_Memset(ivBlock, 0, blockSize);
            cbc_mechanism.mechanism = CKM_DES_CBC;
            cbc_mechanism.pParameter = &ivBlock;
            cbc_mechanism.ulParameterLen = blockSize;
            break;
        case CKM_DES3_MAC_GENERAL:
            mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
        /* fall through */
        case CKM_DES3_MAC:
            blockSize = 8;
            PORT_Memset(ivBlock, 0, blockSize);
            cbc_mechanism.mechanism = CKM_DES3_CBC;
            cbc_mechanism.pParameter = &ivBlock;
            cbc_mechanism.ulParameterLen = blockSize;
            break;
        case CKM_CDMF_MAC_GENERAL:
            mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
        /* fall through */
        case CKM_CDMF_MAC:
            blockSize = 8;
            PORT_Memset(ivBlock, 0, blockSize);
            cbc_mechanism.mechanism = CKM_CDMF_CBC;
            cbc_mechanism.pParameter = &ivBlock;
            cbc_mechanism.ulParameterLen = blockSize;
            break;
        case CKM_SEED_MAC_GENERAL:
            mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
        /* fall through */
        case CKM_SEED_MAC:
            blockSize = 16;
            PORT_Memset(ivBlock, 0, blockSize);
            cbc_mechanism.mechanism = CKM_SEED_CBC;
            cbc_mechanism.pParameter = &ivBlock;
            cbc_mechanism.ulParameterLen = blockSize;
            break;
        case CKM_CAMELLIA_MAC_GENERAL:
            mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
        /* fall through */
        case CKM_CAMELLIA_MAC:
            blockSize = 16;
            PORT_Memset(ivBlock, 0, blockSize);
            cbc_mechanism.mechanism = CKM_CAMELLIA_CBC;
            cbc_mechanism.pParameter = &ivBlock;
            cbc_mechanism.ulParameterLen = blockSize;
            break;
        case CKM_AES_MAC_GENERAL:
            mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
        /* fall through */
        case CKM_AES_MAC:
            blockSize = 16;
            PORT_Memset(ivBlock, 0, blockSize);
            cbc_mechanism.mechanism = CKM_AES_CBC;
            cbc_mechanism.pParameter = &ivBlock;
            cbc_mechanism.ulParameterLen = blockSize;
            break;
        default:
            return CKR_FUNCTION_NOT_SUPPORTED;
    }

    /* if MAC size is externally supplied, it should be checked.
     */
    if (mac_bytes == SFTK_INVALID_MAC_SIZE)
        mac_bytes = blockSize >> 1;
    else {
        if (mac_bytes > blockSize)
            return CKR_MECHANISM_PARAM_INVALID;
    }

    crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey,
                         CKA_ENCRYPT, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */
                         keyUsage, contextType, PR_TRUE);
    if (crv != CKR_OK)
        return crv;
    crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL);

    /* this shouldn't happen! */
    PORT_Assert(crv == CKR_OK);
    if (crv != CKR_OK)
        return crv;
    context->blockSize = blockSize;
    context->macSize = mac_bytes;
    return CKR_OK;
}

/*
 * encode RSA PKCS #1 Signature data before signing...
 */
static SECStatus
sftk_RSAHashSign(SFTKHashSignInfo *info, unsigned char *sig,
                 unsigned int *sigLen, unsigned int maxLen,
                 const unsigned char *hash, unsigned int hashLen)
{
    PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
    if (info->key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    return RSA_HashSign(info->hashOid, info->key, sig, sigLen, maxLen,
                        hash, hashLen);
}

/* XXX Old template; want to expunge it eventually. */
static DERTemplate SECAlgorithmIDTemplate[] = {
    { DER_SEQUENCE,
      0, NULL, sizeof(SECAlgorithmID) },
    { DER_OBJECT_ID,
      offsetof(SECAlgorithmID, algorithm) },
    { DER_OPTIONAL | DER_ANY,
      offsetof(SECAlgorithmID, parameters) },
    { 0 }
};

/*
 * XXX OLD Template.  Once all uses have been switched over to new one,
 * remove this.
 */
static DERTemplate SGNDigestInfoTemplate[] = {
    { DER_SEQUENCE,
      0, NULL, sizeof(SGNDigestInfo) },
    { DER_INLINE,
      offsetof(SGNDigestInfo, digestAlgorithm),
      SECAlgorithmIDTemplate },
    { DER_OCTET_STRING,
      offsetof(SGNDigestInfo, digest) },
    { 0 }
};

/*
 * encode RSA PKCS #1 Signature data before signing...
 */
SECStatus
RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
             unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
             const unsigned char *hash, unsigned int hashLen)
{
    SECStatus rv = SECFailure;
    SECItem digder;
    PLArenaPool *arena = NULL;
    SGNDigestInfo *di = NULL;

    digder.data = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        goto loser;
    }

    /* Construct digest info */
    di = SGN_CreateDigestInfo(hashOid, hash, hashLen);
    if (!di) {
        goto loser;
    }

    /* Der encode the digest as a DigestInfo */
    rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di);
    if (rv != SECSuccess) {
        goto loser;
    }

    /*
    ** Encrypt signature after constructing appropriate PKCS#1 signature
    ** block
    */
    rv = RSA_Sign(&key->u.rsa, sig, sigLen, maxLen, digder.data,
                  digder.len);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }

loser:
    SGN_DestroyDigestInfo(di);
    if (arena != NULL) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return rv;
}

static SECStatus
sftk_RSASign(NSSLOWKEYPrivateKey *key, unsigned char *output,
             unsigned int *outputLen, unsigned int maxOutputLen,
             const unsigned char *input, unsigned int inputLen)
{
    SECStatus rv = SECFailure;

    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    rv = RSA_Sign(&key->u.rsa, output, outputLen, maxOutputLen, input,
                  inputLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }
    return rv;
}

static SECStatus
sftk_RSASignRaw(NSSLOWKEYPrivateKey *key, unsigned char *output,
                unsigned int *outputLen, unsigned int maxOutputLen,
                const unsigned char *input, unsigned int inputLen)
{
    SECStatus rv = SECFailure;

    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    rv = RSA_SignRaw(&key->u.rsa, output, outputLen, maxOutputLen, input,
                     inputLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }
    return rv;
}

static SECStatus
sftk_RSASignPSS(SFTKHashSignInfo *info, unsigned char *sig,
                unsigned int *sigLen, unsigned int maxLen,
                const unsigned char *hash, unsigned int hashLen)
{
    SECStatus rv = SECFailure;
    HASH_HashType hashAlg;
    HASH_HashType maskHashAlg;
    CK_RSA_PKCS_PSS_PARAMS *params = (CK_RSA_PKCS_PSS_PARAMS *)info->params;

    PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
    if (info->key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    hashAlg = GetHashTypeFromMechanism(params->hashAlg);
    maskHashAlg = GetHashTypeFromMechanism(params->mgf);

    rv = RSA_SignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, NULL,
                     params->sLen, sig, sigLen, maxLen, hash, hashLen);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }
    return rv;
}

static SECStatus
nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen,
                    void *dataBuf, unsigned int dataLen)
{
    SECItem signature, digest;
    NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;

    signature.data = (unsigned char *)sigBuf;
    signature.len = sigLen;
    digest.data = (unsigned char *)dataBuf;
    digest.len = dataLen;
    return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest);
}

static SECStatus
nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
                  unsigned int *sigLen, unsigned int maxSigLen,
                  void *dataBuf, unsigned int dataLen)
{
    SECItem signature, digest;
    SECStatus rv;
    NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;

    signature.data = (unsigned char *)sigBuf;
    signature.len = maxSigLen;
    digest.data = (unsigned char *)dataBuf;
    digest.len = dataLen;
    rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }
    *sigLen = signature.len;
    return rv;
}

static SECStatus
nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
                    void *dataBuf, unsigned int dataLen)
{
    SECItem signature, digest;
    NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;

    signature.data = (unsigned char *)sigBuf;
    signature.len = sigLen;
    digest.data = (unsigned char *)dataBuf;
    digest.len = dataLen;
    return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest);
}

static SECStatus
nsc_ECDSASignStub(void *ctx, void *sigBuf,
                  unsigned int *sigLen, unsigned int maxSigLen,
                  void *dataBuf, unsigned int dataLen)
{
    SECItem signature, digest;
    SECStatus rv;
    NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;

    signature.data = (unsigned char *)sigBuf;
    signature.len = maxSigLen;
    digest.data = (unsigned char *)dataBuf;
    digest.len = dataLen;
    rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
        sftk_fatalError = PR_TRUE;
    }
    *sigLen = signature.len;
    return rv;
}

/* NSC_SignInit setups up the signing operations. There are three basic
 * types of signing:
 *      (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
 *  to data in a single Sign operation (which often looks a lot like an
 *  encrypt, with data coming in and data going out).
 *      (2) Hash based signing, where we continually hash the data, then apply
 *  some sort of signature to the end.
 *      (3) Block Encryption CBC MAC's, where the Data is encrypted with a key,
 *  and only the final block is part of the mac.
 *
 *  For case number 3, we initialize a context much like the Encryption Context
 *  (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and
 *  C_Final by the following method... if it's not multi-part, and it's doesn't
 *  have a hash context, it must be a block Encryption CBC MAC.
 *
 *  For case number 2, we initialize a hash structure, as well as make it
 *  multi-part. Updates are simple calls to the hash update function. Final
 *  calls the hashend, then passes the result to the 'update' function (which
 *  operates as a final signature function). In some hash based MAC'ing (as
 *  opposed to hash base signatures), the update function is can be simply a
 *  copy (as is the case with HMAC).
 */
CK_RV
NSC_SignInit(CK_SESSION_HANDLE hSession,
             CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPrivateKey *privKey;
    SFTKHashSignInfo *info = NULL;

    CHECK_FORK();

    /* Block Cipher MACing Algorithms use a different Context init method..*/
    crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, SFTK_SIGN);
    if (crv != CKR_FUNCTION_NOT_SUPPORTED)
        return crv;

    /* we're not using a block cipher mac */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL)
        return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session, &context, SFTK_SIGN, &key, hKey, &key_type,
                           CKO_PRIVATE_KEY, CKA_SIGN);
    if (crv != CKR_OK) {
        sftk_FreeSession(session);
        return crv;
    }

    context->multi = PR_FALSE;

#define INIT_RSA_SIGN_MECH(mmm)                         \
    case CKM_##mmm##_RSA_PKCS:                          \
        context->multi = PR_TRUE;                       \
        crv = sftk_doSub##mmm(context);                 \
        if (crv != CKR_OK)                              \
            break;                                      \
        context->update = (SFTKCipher)sftk_RSAHashSign; \
        info = PORT_New(SFTKHashSignInfo);              \
        if (info == NULL) {                             \
            crv = CKR_HOST_MEMORY;                      \
            break;                                      \
        }                                               \
        info->hashOid = SEC_OID_##mmm;                  \
        goto finish_rsa;

    switch (pMechanism->mechanism) {
        INIT_RSA_SIGN_MECH(MD5)
        INIT_RSA_SIGN_MECH(MD2)
        INIT_RSA_SIGN_MECH(SHA1)
        INIT_RSA_SIGN_MECH(SHA224)
        INIT_RSA_SIGN_MECH(SHA256)
        INIT_RSA_SIGN_MECH(SHA384)
        INIT_RSA_SIGN_MECH(SHA512)

        case CKM_RSA_PKCS:
            context->update = (SFTKCipher)sftk_RSASign;
            goto finish_rsa;
        case CKM_RSA_X_509:
            context->update = (SFTKCipher)sftk_RSASignRaw;
        finish_rsa:
            if (key_type != CKK_RSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            context->rsa = PR_TRUE;
            privKey = sftk_GetPrivKey(key, CKK_RSA, &crv);
            if (privKey == NULL) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            /* OK, info is allocated only if we're doing hash and sign mechanism.
             * It's necessary to be able to set the correct OID in the final
             * signature.
             */
            if (info) {
                info->key = privKey;
                context->cipherInfo = info;
                context->destroy = (SFTKDestroy)sftk_Space;
            } else {
                context->cipherInfo = privKey;
                context->destroy = (SFTKDestroy)sftk_Null;
            }
            context->maxLen = nsslowkey_PrivateModulusLen(privKey);
            break;
        case CKM_RSA_PKCS_PSS:
            if (key_type != CKK_RSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            context->rsa = PR_TRUE;
            if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
                !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            info = PORT_New(SFTKHashSignInfo);
            if (info == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            info->params = pMechanism->pParameter;
            info->key = sftk_GetPrivKey(key, CKK_RSA, &crv);
            if (info->key == NULL) {
                PORT_Free(info);
                break;
            }
            context->cipherInfo = info;
            context->destroy = (SFTKDestroy)sftk_Space;
            context->update = (SFTKCipher)sftk_RSASignPSS;
            context->maxLen = nsslowkey_PrivateModulusLen(info->key);
            break;

        case CKM_DSA_SHA1:
            context->multi = PR_TRUE;
            crv = sftk_doSubSHA1(context);
            if (crv != CKR_OK)
                break;
        /* fall through */
        case CKM_DSA:
            if (key_type != CKK_DSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            privKey = sftk_GetPrivKey(key, CKK_DSA, &crv);
            if (privKey == NULL) {
                break;
            }
            context->cipherInfo = privKey;
            context->update = (SFTKCipher)nsc_DSA_Sign_Stub;
            context->destroy = (privKey == key->objectInfo) ? (SFTKDestroy)sftk_Null : (SFTKDestroy)sftk_FreePrivKey;
            context->maxLen = DSA_MAX_SIGNATURE_LEN;

            break;

        case CKM_ECDSA_SHA1:
            context->multi = PR_TRUE;
            crv = sftk_doSubSHA1(context);
            if (crv != CKR_OK)
                break;
        /* fall through */
        case CKM_ECDSA:
            if (key_type != CKK_EC) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            privKey = sftk_GetPrivKey(key, CKK_EC, &crv);
            if (privKey == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->cipherInfo = privKey;
            context->update = (SFTKCipher)nsc_ECDSASignStub;
            context->destroy = (privKey == key->objectInfo) ? (SFTKDestroy)sftk_Null : (SFTKDestroy)sftk_FreePrivKey;
            context->maxLen = MAX_ECKEY_LEN * 2;

            break;

#define INIT_HMAC_MECH(mmm)                                               \
    case CKM_##mmm##_HMAC_GENERAL:                                        \
        PORT_Assert(pMechanism->pParameter);                              \
        if (!pMechanism->pParameter) {                                    \
            crv = CKR_MECHANISM_PARAM_INVALID;                            \
            break;                                                        \
        }                                                                 \
        crv = sftk_doHMACInit(context, HASH_Alg##mmm, key,                \
                              *(CK_ULONG *)pMechanism->pParameter);       \
        break;                                                            \
    case CKM_##mmm##_HMAC:                                                \
        crv = sftk_doHMACInit(context, HASH_Alg##mmm, key, mmm##_LENGTH); \
        break;

            INIT_HMAC_MECH(MD2)
            INIT_HMAC_MECH(MD5)
            INIT_HMAC_MECH(SHA224)
            INIT_HMAC_MECH(SHA256)
            INIT_HMAC_MECH(SHA384)
            INIT_HMAC_MECH(SHA512)

        case CKM_SHA_1_HMAC_GENERAL:
            PORT_Assert(pMechanism->pParameter);
            if (!pMechanism->pParameter) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            crv = sftk_doHMACInit(context, HASH_AlgSHA1, key,
                                  *(CK_ULONG *)pMechanism->pParameter);
            break;
        case CKM_SHA_1_HMAC:
            crv = sftk_doHMACInit(context, HASH_AlgSHA1, key, SHA1_LENGTH);
            break;

        case CKM_SSL3_MD5_MAC:
            PORT_Assert(pMechanism->pParameter);
            if (!pMechanism->pParameter) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key,
                                    *(CK_ULONG *)pMechanism->pParameter);
            break;
        case CKM_SSL3_SHA1_MAC:
            PORT_Assert(pMechanism->pParameter);
            if (!pMechanism->pParameter) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key,
                                    *(CK_ULONG *)pMechanism->pParameter);
            break;
        case CKM_TLS_PRF_GENERAL:
            crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0);
            break;
        case CKM_TLS_MAC: {
            CK_TLS_MAC_PARAMS *tls12_mac_params;
            HASH_HashType tlsPrfHash;
            const char *label;

            if (pMechanism->ulParameterLen != sizeof(CK_TLS_MAC_PARAMS)) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            tls12_mac_params = (CK_TLS_MAC_PARAMS *)pMechanism->pParameter;
            if (tls12_mac_params->prfMechanism == CKM_TLS_PRF) {
                /* The TLS 1.0 and 1.1 PRF */
                tlsPrfHash = HASH_AlgNULL;
                if (tls12_mac_params->ulMacLength != 12) {
                    crv = CKR_MECHANISM_PARAM_INVALID;
                    break;
                }
            } else {
                /* The hash function for the TLS 1.2 PRF */
                tlsPrfHash =
                    GetHashTypeFromMechanism(tls12_mac_params->prfMechanism);
                if (tlsPrfHash == HASH_AlgNULL ||
                    tls12_mac_params->ulMacLength < 12) {
                    crv = CKR_MECHANISM_PARAM_INVALID;
                    break;
                }
            }
            if (tls12_mac_params->ulServerOrClient == 1) {
                label = "server finished";
            } else if (tls12_mac_params->ulServerOrClient == 2) {
                label = "client finished";
            } else {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            crv = sftk_TLSPRFInit(context, key, key_type, tlsPrfHash,
                                  tls12_mac_params->ulMacLength);
            if (crv == CKR_OK) {
                context->hashUpdate(context->hashInfo, label, 15);
            }
            break;
        }
        case CKM_NSS_TLS_PRF_GENERAL_SHA256:
            crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
            break;

        case CKM_NSS_HMAC_CONSTANT_TIME: {
            sftk_MACConstantTimeCtx *ctx =
                sftk_HMACConstantTime_New(pMechanism, key);
            CK_ULONG *intpointer;

            if (ctx == NULL) {
                crv = CKR_ARGUMENTS_BAD;
                break;
            }
            intpointer = PORT_New(CK_ULONG);
            if (intpointer == NULL) {
                PORT_Free(ctx);
                crv = CKR_HOST_MEMORY;
                break;
            }
            *intpointer = ctx->hash->length;

            context->cipherInfo = intpointer;
            context->hashInfo = ctx;
            context->currentMech = pMechanism->mechanism;
            context->hashUpdate = sftk_HMACConstantTime_Update;
            context->hashdestroy = sftk_MACConstantTime_DestroyContext;
            context->end = sftk_MACConstantTime_EndHash;
            context->update = (SFTKCipher)sftk_SignCopy;
            context->destroy = sftk_Space;
            context->maxLen = 64;
            context->multi = PR_TRUE;
            break;
        }

        case CKM_NSS_SSL3_MAC_CONSTANT_TIME: {
            sftk_MACConstantTimeCtx *ctx =
                sftk_SSLv3MACConstantTime_New(pMechanism, key);
            CK_ULONG *intpointer;

            if (ctx == NULL) {
                crv = CKR_ARGUMENTS_BAD;
                break;
            }
            intpointer = PORT_New(CK_ULONG);
            if (intpointer == NULL) {
                PORT_Free(ctx);
                crv = CKR_HOST_MEMORY;
                break;
            }
            *intpointer = ctx->hash->length;

            context->cipherInfo = intpointer;
            context->hashInfo = ctx;
            context->currentMech = pMechanism->mechanism;
            context->hashUpdate = sftk_SSLv3MACConstantTime_Update;
            context->hashdestroy = sftk_MACConstantTime_DestroyContext;
            context->end = sftk_MACConstantTime_EndHash;
            context->update = (SFTKCipher)sftk_SignCopy;
            context->destroy = sftk_Space;
            context->maxLen = 64;
            context->multi = PR_TRUE;
            break;
        }

        default:
            crv = CKR_MECHANISM_INVALID;
            break;
    }

    if (crv != CKR_OK) {
        if (info)
            PORT_Free(info);
        sftk_FreeContext(context);
        sftk_FreeSession(session);
        return crv;
    }
    sftk_SetContextByType(session, SFTK_SIGN, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

/** MAC one block of data by block cipher
 */
static CK_RV
sftk_MACBlock(SFTKSessionContext *ctx, void *blk)
{
    unsigned int outlen;
    return (SECSuccess == (ctx->update)(ctx->cipherInfo, ctx->macBuf, &outlen,
                                        SFTK_MAX_BLOCK_SIZE, blk, ctx->blockSize))
               ? CKR_OK
               : sftk_MapCryptError(PORT_GetError());
}

/** MAC last (incomplete) block of data by block cipher
 *
 *  Call once, then terminate MACing operation.
 */
static CK_RV
sftk_MACFinal(SFTKSessionContext *ctx)
{
    unsigned int padLen = ctx->padDataLength;
    /* pad and proceed the residual */
    if (padLen) {
        /* shd clr ctx->padLen to make sftk_MACFinal idempotent */
        PORT_Memset(ctx->padBuf + padLen, 0, ctx->blockSize - padLen);
        return sftk_MACBlock(ctx, ctx->padBuf);
    } else
        return CKR_OK;
}

/** The common implementation for {Sign,Verify}Update. (S/V only vary in their
 * setup and final operations).
 *
 * A call which results in an error terminates the operation [PKCS#11,v2.11]
 */
static CK_RV
sftk_MACUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
               CK_ULONG ulPartLen, SFTKContextType type)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    CK_RV crv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, type, PR_TRUE, &session);
    if (crv != CKR_OK)
        return crv;

    if (context->hashInfo) {
        (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen);
    } else {
        /* must be block cipher MACing */

        unsigned int blkSize = context->blockSize;
        unsigned char *residual = /* free room in context->padBuf */
            context->padBuf + context->padDataLength;
        unsigned int minInput = /* min input for MACing at least one block */
            blkSize - context->padDataLength;

        /* not enough data even for one block */
        if (ulPartLen < minInput) {
            PORT_Memcpy(residual, pPart, ulPartLen);
            context->padDataLength += ulPartLen;
            goto cleanup;
        }
        /* MACing residual */
        if (context->padDataLength) {
            PORT_Memcpy(residual, pPart, minInput);
            ulPartLen -= minInput;
            pPart += minInput;
            if (CKR_OK != (crv = sftk_MACBlock(context, context->padBuf)))
                goto terminate;
        }
        /* MACing full blocks */
        while (ulPartLen >= blkSize) {
            if (CKR_OK != (crv = sftk_MACBlock(context, pPart)))
                goto terminate;
            ulPartLen -= blkSize;
            pPart += blkSize;
        }
        /* save the residual */
        if ((context->padDataLength = ulPartLen))
            PORT_Memcpy(context->padBuf, pPart, ulPartLen);
    } /* blk cipher MACing */

    goto cleanup;

terminate:
    sftk_TerminateOp(session, type, context);
cleanup:
    sftk_FreeSession(session);
    return crv;
}

/* NSC_SignUpdate continues a multiple-part signature operation,
 * where the signature is (will be) an appendix to the data,
 * and plaintext cannot be recovered from the signature
 *
 * A call which results in an error terminates the operation [PKCS#11,v2.11]
 */
CK_RV
NSC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
               CK_ULONG ulPartLen)
{
    CHECK_FORK();
    return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN);
}

/* NSC_SignFinal finishes a multiple-part signature operation,
 * returning the signature. */
CK_RV
NSC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
              CK_ULONG_PTR pulSignatureLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulSignatureLen;
    CK_RV crv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_TRUE, &session);
    if (crv != CKR_OK)
        return crv;

    if (context->hashInfo) {
        unsigned int digestLen;
        unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];

        if (!pSignature) {
            outlen = context->maxLen;
            goto finish;
        }
        (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
        if (SECSuccess != (context->update)(context->cipherInfo, pSignature,
                                            &outlen, maxoutlen, tmpbuf, digestLen))
            crv = sftk_MapCryptError(PORT_GetError());
        /* CKR_BUFFER_TOO_SMALL here isn't continuable, let operation terminate.
         * Keeping "too small" CK_RV intact is a standard violation, but allows
         * application read EXACT signature length */
    } else {
        /* must be block cipher MACing */
        outlen = context->macSize;
        /* null or "too small" buf doesn't terminate operation [PKCS#11,v2.11]*/
        if (!pSignature || maxoutlen < outlen) {
            if (pSignature)
                crv = CKR_BUFFER_TOO_SMALL;
            goto finish;
        }
        if (CKR_OK == (crv = sftk_MACFinal(context)))
            PORT_Memcpy(pSignature, context->macBuf, outlen);
    }

    sftk_TerminateOp(session, SFTK_SIGN, context);
finish:
    *pulSignatureLen = outlen;
    sftk_FreeSession(session);
    return crv;
}

/* NSC_Sign signs (encrypts with private key) data in a single part,
 * where the signature is (will be) an appendix to the data,
 * and plaintext cannot be recovered from the signature */
CK_RV
NSC_Sign(CK_SESSION_HANDLE hSession,
         CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
         CK_ULONG_PTR pulSignatureLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    CK_RV crv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_FALSE, &session);
    if (crv != CKR_OK)
        return crv;

    if (!pSignature) {
        /* see also how C_SignUpdate implements this */
        *pulSignatureLen = (!context->multi || context->hashInfo)
                               ? context->maxLen
                               : context->macSize; /* must be block cipher MACing */
        goto finish;
    }

    /* multi part Signing are completely implemented by SignUpdate and
     * sign Final */
    if (context->multi) {
        /* SignFinal can't follow failed SignUpdate */
        if (CKR_OK == (crv = NSC_SignUpdate(hSession, pData, ulDataLen)))
            crv = NSC_SignFinal(hSession, pSignature, pulSignatureLen);
    } else {
        /* single-part PKC signature (e.g. CKM_ECDSA) */
        unsigned int outlen;
        unsigned int maxoutlen = *pulSignatureLen;
        if (SECSuccess != (*context->update)(context->cipherInfo, pSignature,
                                             &outlen, maxoutlen, pData, ulDataLen))
            crv = sftk_MapCryptError(PORT_GetError());
        *pulSignatureLen = (CK_ULONG)outlen;
        /*  "too small" here is certainly continuable */
        if (crv != CKR_BUFFER_TOO_SMALL)
            sftk_TerminateOp(session, SFTK_SIGN, context);
    } /* single-part */

finish:
    sftk_FreeSession(session);
    return crv;
}

/*
 ************** Crypto Functions:     Sign Recover  ************************
 */
/* NSC_SignRecoverInit initializes a signature operation,
 * where the (digest) data can be recovered from the signature.
 * E.g. encryption with the user's private key */
CK_RV
NSC_SignRecoverInit(CK_SESSION_HANDLE hSession,
                    CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
    CHECK_FORK();

    switch (pMechanism->mechanism) {
        case CKM_RSA_PKCS:
        case CKM_RSA_X_509:
            return NSC_SignInit(hSession, pMechanism, hKey);
        default:
            break;
    }
    return CKR_MECHANISM_INVALID;
}

/* NSC_SignRecover signs data in a single operation
 * where the (digest) data can be recovered from the signature.
 * E.g. encryption with the user's private key */
CK_RV
NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
                CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
{
    CHECK_FORK();

    return NSC_Sign(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
}

/*
 ************** Crypto Functions:     verify  ************************
 */

/* Handle RSA Signature formatting */
static SECStatus
sftk_hashCheckSign(SFTKHashVerifyInfo *info, const unsigned char *sig,
                   unsigned int sigLen, const unsigned char *digest,
                   unsigned int digestLen)
{
    PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
    if (info->key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, digest,
                             digestLen);
}

SECStatus
RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key,
                  const unsigned char *sig, unsigned int sigLen,
                  const unsigned char *digestData, unsigned int digestLen)
{
    unsigned char *pkcs1DigestInfoData;
    SECItem pkcs1DigestInfo;
    SECItem digest;
    unsigned int bufferSize;
    SECStatus rv;

    /* pkcs1DigestInfo.data must be less than key->u.rsa.modulus.len */
    bufferSize = key->u.rsa.modulus.len;
    pkcs1DigestInfoData = PORT_ZAlloc(bufferSize);
    if (!pkcs1DigestInfoData) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    pkcs1DigestInfo.data = pkcs1DigestInfoData;
    pkcs1DigestInfo.len = bufferSize;

    /* decrypt the block */
    rv = RSA_CheckSignRecover(&key->u.rsa, pkcs1DigestInfo.data,
                              &pkcs1DigestInfo.len, pkcs1DigestInfo.len,
                              sig, sigLen);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
    } else {
        digest.data = (PRUint8 *)digestData;
        digest.len = digestLen;
        rv = _SGN_VerifyPKCS1DigestInfo(
            digestOid, &digest, &pkcs1DigestInfo,
            PR_FALSE /*XXX: unsafeAllowMissingParameters*/);
    }

    PORT_Free(pkcs1DigestInfoData);
    return rv;
}

static SECStatus
sftk_RSACheckSign(NSSLOWKEYPublicKey *key, const unsigned char *sig,
                  unsigned int sigLen, const unsigned char *digest,
                  unsigned int digestLen)
{
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    return RSA_CheckSign(&key->u.rsa, sig, sigLen, digest, digestLen);
}

static SECStatus
sftk_RSACheckSignRaw(NSSLOWKEYPublicKey *key, const unsigned char *sig,
                     unsigned int sigLen, const unsigned char *digest,
                     unsigned int digestLen)
{
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    return RSA_CheckSignRaw(&key->u.rsa, sig, sigLen, digest, digestLen);
}

static SECStatus
sftk_RSACheckSignPSS(SFTKHashVerifyInfo *info, const unsigned char *sig,
                     unsigned int sigLen, const unsigned char *digest,
                     unsigned int digestLen)
{
    HASH_HashType hashAlg;
    HASH_HashType maskHashAlg;
    CK_RSA_PKCS_PSS_PARAMS *params = (CK_RSA_PKCS_PSS_PARAMS *)info->params;

    PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
    if (info->key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    hashAlg = GetHashTypeFromMechanism(params->hashAlg);
    maskHashAlg = GetHashTypeFromMechanism(params->mgf);

    return RSA_CheckSignPSS(&info->key->u.rsa, hashAlg, maskHashAlg,
                            params->sLen, sig, sigLen, digest, digestLen);
}

/* NSC_VerifyInit initializes a verification operation,
 * where the signature is an appendix to the data,
 * and plaintext cannot be recovered from the signature (e.g. DSA) */
CK_RV
NSC_VerifyInit(CK_SESSION_HANDLE hSession,
               CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPublicKey *pubKey;
    SFTKHashVerifyInfo *info = NULL;

    CHECK_FORK();

    /* Block Cipher MACing Algorithms use a different Context init method..*/
    crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY, SFTK_VERIFY);
    if (crv != CKR_FUNCTION_NOT_SUPPORTED)
        return crv;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL)
        return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session, &context, SFTK_VERIFY, &key, hKey, &key_type,
                           CKO_PUBLIC_KEY, CKA_VERIFY);
    if (crv != CKR_OK) {
        sftk_FreeSession(session);
        return crv;
    }

    context->multi = PR_FALSE;

#define INIT_RSA_VFY_MECH(mmm)                            \
    case CKM_##mmm##_RSA_PKCS:                            \
        context->multi = PR_TRUE;                         \
        crv = sftk_doSub##mmm(context);                   \
        if (crv != CKR_OK)                                \
            break;                                        \
        context->verify = (SFTKVerify)sftk_hashCheckSign; \
        info = PORT_New(SFTKHashVerifyInfo);              \
        if (info == NULL) {                               \
            crv = CKR_HOST_MEMORY;                        \
            break;                                        \
        }                                                 \
        info->hashOid = SEC_OID_##mmm;                    \
        goto finish_rsa;

    switch (pMechanism->mechanism) {
        INIT_RSA_VFY_MECH(MD5)
        INIT_RSA_VFY_MECH(MD2)
        INIT_RSA_VFY_MECH(SHA1)
        INIT_RSA_VFY_MECH(SHA224)
        INIT_RSA_VFY_MECH(SHA256)
        INIT_RSA_VFY_MECH(SHA384)
        INIT_RSA_VFY_MECH(SHA512)

        case CKM_RSA_PKCS:
            context->verify = (SFTKVerify)sftk_RSACheckSign;
            goto finish_rsa;
        case CKM_RSA_X_509:
            context->verify = (SFTKVerify)sftk_RSACheckSignRaw;
        finish_rsa:
            if (key_type != CKK_RSA) {
                if (info)
                    PORT_Free(info);
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            context->rsa = PR_TRUE;
            pubKey = sftk_GetPubKey(key, CKK_RSA, &crv);
            if (pubKey == NULL) {
                if (info)
                    PORT_Free(info);
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            if (info) {
                info->key = pubKey;
                context->cipherInfo = info;
                context->destroy = sftk_Space;
            } else {
                context->cipherInfo = pubKey;
                context->destroy = sftk_Null;
            }
            break;
        case CKM_RSA_PKCS_PSS:
            if (key_type != CKK_RSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            context->rsa = PR_TRUE;
            if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
                !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            info = PORT_New(SFTKHashVerifyInfo);
            if (info == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            info->params = pMechanism->pParameter;
            info->key = sftk_GetPubKey(key, CKK_RSA, &crv);
            if (info->key == NULL) {
                PORT_Free(info);
                break;
            }
            context->cipherInfo = info;
            context->destroy = (SFTKDestroy)sftk_Space;
            context->verify = (SFTKVerify)sftk_RSACheckSignPSS;
            break;
        case CKM_DSA_SHA1:
            context->multi = PR_TRUE;
            crv = sftk_doSubSHA1(context);
            if (crv != CKR_OK)
                break;
        /* fall through */
        case CKM_DSA:
            if (key_type != CKK_DSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            pubKey = sftk_GetPubKey(key, CKK_DSA, &crv);
            if (pubKey == NULL) {
                break;
            }
            context->cipherInfo = pubKey;
            context->verify = (SFTKVerify)nsc_DSA_Verify_Stub;
            context->destroy = sftk_Null;
            break;
        case CKM_ECDSA_SHA1:
            context->multi = PR_TRUE;
            crv = sftk_doSubSHA1(context);
            if (crv != CKR_OK)
                break;
        /* fall through */
        case CKM_ECDSA:
            if (key_type != CKK_EC) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            pubKey = sftk_GetPubKey(key, CKK_EC, &crv);
            if (pubKey == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            context->cipherInfo = pubKey;
            context->verify = (SFTKVerify)nsc_ECDSAVerifyStub;
            context->destroy = sftk_Null;
            break;

            INIT_HMAC_MECH(MD2)
            INIT_HMAC_MECH(MD5)
            INIT_HMAC_MECH(SHA224)
            INIT_HMAC_MECH(SHA256)
            INIT_HMAC_MECH(SHA384)
            INIT_HMAC_MECH(SHA512)

        case CKM_SHA_1_HMAC_GENERAL:
            PORT_Assert(pMechanism->pParameter);
            if (!pMechanism->pParameter) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            crv = sftk_doHMACInit(context, HASH_AlgSHA1, key,
                                  *(CK_ULONG *)pMechanism->pParameter);
            break;
        case CKM_SHA_1_HMAC:
            crv = sftk_doHMACInit(context, HASH_AlgSHA1, key, SHA1_LENGTH);
            break;

        case CKM_SSL3_MD5_MAC:
            PORT_Assert(pMechanism->pParameter);
            if (!pMechanism->pParameter) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key,
                                    *(CK_ULONG *)pMechanism->pParameter);
            break;
        case CKM_SSL3_SHA1_MAC:
            PORT_Assert(pMechanism->pParameter);
            if (!pMechanism->pParameter) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key,
                                    *(CK_ULONG *)pMechanism->pParameter);
            break;
        case CKM_TLS_PRF_GENERAL:
            crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0);
            break;
        case CKM_NSS_TLS_PRF_GENERAL_SHA256:
            crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
            break;

        default:
            crv = CKR_MECHANISM_INVALID;
            break;
    }

    if (crv != CKR_OK) {
        if (info)
            PORT_Free(info);
        sftk_FreeContext(context);
        sftk_FreeSession(session);
        return crv;
    }
    sftk_SetContextByType(session, SFTK_VERIFY, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

/* NSC_Verify verifies a signature in a single-part operation,
 * where the signature is an appendix to the data,
 * and plaintext cannot be recovered from the signature */
CK_RV
NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
           CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    CK_RV crv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE, &session);
    if (crv != CKR_OK)
        return crv;

    /* multi part Verifying are completely implemented by VerifyUpdate and
     * VerifyFinal */
    if (context->multi) {
        /* VerifyFinal can't follow failed VerifyUpdate */
        if (CKR_OK == (crv = NSC_VerifyUpdate(hSession, pData, ulDataLen)))
            crv = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen);
    } else {
        if (SECSuccess != (*context->verify)(context->cipherInfo, pSignature,
                                             ulSignatureLen, pData, ulDataLen))
            crv = sftk_MapCryptError(PORT_GetError());

        sftk_TerminateOp(session, SFTK_VERIFY, context);
    }
    sftk_FreeSession(session);
    return crv;
}

/* NSC_VerifyUpdate continues a multiple-part verification operation,
 * where the signature is an appendix to the data,
 * and plaintext cannot be recovered from the signature
 *
 * A call which results in an error terminates the operation [PKCS#11,v2.11]
 */
CK_RV
NSC_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
                 CK_ULONG ulPartLen)
{
    CHECK_FORK();
    return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY);
}

/* NSC_VerifyFinal finishes a multiple-part verification operation,
 * checking the signature. */
CK_RV
NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
                CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    CK_RV crv;

    CHECK_FORK();

    if (!pSignature)
        return CKR_ARGUMENTS_BAD;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE, &session);
    if (crv != CKR_OK)
        return crv;

    if (context->hashInfo) {
        unsigned int digestLen;
        unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];

        (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
        if (SECSuccess != (context->verify)(context->cipherInfo, pSignature,
                                            ulSignatureLen, tmpbuf, digestLen))
            crv = sftk_MapCryptError(PORT_GetError());
    } else if (ulSignatureLen != context->macSize) {
        /* must be block cipher MACing */
        crv = CKR_SIGNATURE_LEN_RANGE;
    } else if (CKR_OK == (crv = sftk_MACFinal(context))) {
        if (PORT_Memcmp(pSignature, context->macBuf, ulSignatureLen))
            crv = CKR_SIGNATURE_INVALID;
    }

    sftk_TerminateOp(session, SFTK_VERIFY, context);
    sftk_FreeSession(session);
    return crv;
}

/*
 ************** Crypto Functions:     Verify  Recover ************************
 */
static SECStatus
sftk_RSACheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data,
                         unsigned int *dataLen, unsigned int maxDataLen,
                         const unsigned char *sig, unsigned int sigLen)
{
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    return RSA_CheckSignRecover(&key->u.rsa, data, dataLen, maxDataLen,
                                sig, sigLen);
}

static SECStatus
sftk_RSACheckSignRecoverRaw(NSSLOWKEYPublicKey *key, unsigned char *data,
                            unsigned int *dataLen, unsigned int maxDataLen,
                            const unsigned char *sig, unsigned int sigLen)
{
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    return RSA_CheckSignRecoverRaw(&key->u.rsa, data, dataLen, maxDataLen,
                                   sig, sigLen);
}

/* NSC_VerifyRecoverInit initializes a signature verification operation,
 * where the data is recovered from the signature.
 * E.g. Decryption with the user's public key */
CK_RV
NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
                      CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPublicKey *pubKey;

    CHECK_FORK();

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL)
        return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session, &context, SFTK_VERIFY_RECOVER,
                           &key, hKey, &key_type, CKO_PUBLIC_KEY, CKA_VERIFY_RECOVER);
    if (crv != CKR_OK) {
        sftk_FreeSession(session);
        return crv;
    }

    context->multi = PR_TRUE;

    switch (pMechanism->mechanism) {
        case CKM_RSA_PKCS:
        case CKM_RSA_X_509:
            if (key_type != CKK_RSA) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            context->multi = PR_FALSE;
            context->rsa = PR_TRUE;
            pubKey = sftk_GetPubKey(key, CKK_RSA, &crv);
            if (pubKey == NULL) {
                break;
            }
            context->cipherInfo = pubKey;
            context->update = (SFTKCipher)(pMechanism->mechanism == CKM_RSA_X_509
                                               ? sftk_RSACheckSignRecoverRaw
                                               : sftk_RSACheckSignRecover);
            context->destroy = sftk_Null;
            break;
        default:
            crv = CKR_MECHANISM_INVALID;
            break;
    }

    if (crv != CKR_OK) {
        PORT_Free(context);
        sftk_FreeSession(session);
        return crv;
    }
    sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

/* NSC_VerifyRecover verifies a signature in a single-part operation,
 * where the data is recovered from the signature.
 * E.g. Decryption with the user's public key */
CK_RV
NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
                  CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen,
                  CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulDataLen;
    CK_RV crv;
    SECStatus rv;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_VERIFY_RECOVER,
                          PR_FALSE, &session);
    if (crv != CKR_OK)
        return crv;
    if (pData == NULL) {
        /* to return the actual size, we need  to do the decrypt, just return
         * the max size, which is the size of the input signature. */
        *pulDataLen = ulSignatureLen;
        rv = SECSuccess;
        goto finish;
    }

    rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
                            pSignature, ulSignatureLen);
    *pulDataLen = (CK_ULONG)outlen;

    sftk_TerminateOp(session, SFTK_VERIFY_RECOVER, context);
finish:
    sftk_FreeSession(session);
    return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError());
}

/*
 **************************** Random Functions:  ************************
 */

/* NSC_SeedRandom mixes additional seed material into the token's random number
 * generator. */
CK_RV
NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
               CK_ULONG ulSeedLen)
{
    SECStatus rv;

    CHECK_FORK();

    rv = RNG_RandomUpdate(pSeed, ulSeedLen);
    return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/* NSC_GenerateRandom generates random data. */
CK_RV
NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
                   CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
{
    SECStatus rv;

    CHECK_FORK();

    rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen);
    /*
     * This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't
     * seeded with enough entropy.
     */
    return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/*
 **************************** Key Functions:  ************************
 */

/*
 * generate a password based encryption key. This code uses
 * PKCS5 to do the work.
 */
static CK_RV
nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
                void *buf, CK_ULONG *key_length, PRBool faulty3DES)
{
    SECItem *pbe_key = NULL, iv, pwitem;
    CK_PBE_PARAMS *pbe_params = NULL;
    CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;

    *key_length = 0;
    iv.data = NULL;
    iv.len = 0;

    if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
        pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
        pwitem.data = (unsigned char *)pbkd2_params->pPassword;
        /* was this a typo in the PKCS #11 spec? */
        pwitem.len = *pbkd2_params->ulPasswordLen;
    } else {
        pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
        pwitem.data = (unsigned char *)pbe_params->pPassword;
        pwitem.len = pbe_params->ulPasswordLen;
    }
    pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES);
    if (pbe_key == NULL) {
        return CKR_HOST_MEMORY;
    }

    PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
    *key_length = pbe_key->len;
    SECITEM_ZfreeItem(pbe_key, PR_TRUE);
    pbe_key = NULL;

    if (iv.data) {
        if (pbe_params && pbe_params->pInitVector != NULL) {
            PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
        }
        PORT_Free(iv.data);
    }

    return CKR_OK;
}

/*
 * this is coded for "full" support. These selections will be limitted to
 * the official subset by freebl.
 */
static unsigned int
sftk_GetSubPrimeFromPrime(unsigned int primeBits)
{
    if (primeBits <= 1024) {
        return 160;
    } else if (primeBits <= 2048) {
        return 224;
    } else if (primeBits <= 3072) {
        return 256;
    } else if (primeBits <= 7680) {
        return 384;
    } else {
        return 512;
    }
}

static CK_RV
nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
{
    SFTKAttribute *attribute;
    CK_ULONG counter;
    unsigned int seedBits = 0;
    unsigned int subprimeBits = 0;
    unsigned int primeBits;
    unsigned int j = 8; /* default to 1024 bits */
    CK_RV crv = CKR_OK;
    PQGParams *params = NULL;
    PQGVerify *vfy = NULL;
    SECStatus rv;

    attribute = sftk_FindAttribute(key, CKA_PRIME_BITS);
    if (attribute == NULL) {
        attribute = sftk_FindAttribute(key, CKA_PRIME);
        if (attribute == NULL) {
            return CKR_TEMPLATE_INCOMPLETE;
        } else {
            primeBits = attribute->attrib.ulValueLen;
            sftk_FreeAttribute(attribute);
        }
    } else {
        primeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
        sftk_FreeAttribute(attribute);
    }
    if (primeBits < 1024) {
        j = PQG_PBITS_TO_INDEX(primeBits);
        if (j == (unsigned int)-1) {
            return CKR_ATTRIBUTE_VALUE_INVALID;
        }
    }

    attribute = sftk_FindAttribute(key, CKA_NSS_PQG_SEED_BITS);
    if (attribute != NULL) {
        seedBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
        sftk_FreeAttribute(attribute);
    }

    attribute = sftk_FindAttribute(key, CKA_SUBPRIME_BITS);
    if (attribute != NULL) {
        subprimeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
        sftk_FreeAttribute(attribute);
    }

    /* if P and Q are supplied, we want to generate a new G */
    attribute = sftk_FindAttribute(key, CKA_PRIME);
    if (attribute != NULL) {
        PLArenaPool *arena;

        sftk_FreeAttribute(attribute);
        arena = PORT_NewArena(1024);
        if (arena == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        params = PORT_ArenaAlloc(arena, sizeof(*params));
        if (params == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        params->arena = arena;
        crv = sftk_Attribute2SSecItem(arena, &params->prime, key, CKA_PRIME);
        if (crv != CKR_OK) {
            goto loser;
        }
        crv = sftk_Attribute2SSecItem(arena, &params->subPrime,
                                      key, CKA_SUBPRIME);
        if (crv != CKR_OK) {
            goto loser;
        }

        arena = PORT_NewArena(1024);
        if (arena == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        vfy = PORT_ArenaAlloc(arena, sizeof(*vfy));
        if (vfy == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        vfy->arena = arena;
        crv = sftk_Attribute2SSecItem(arena, &vfy->seed, key, CKA_NSS_PQG_SEED);
        if (crv != CKR_OK) {
            goto loser;
        }
        crv = sftk_Attribute2SSecItem(arena, &vfy->h, key, CKA_NSS_PQG_H);
        if (crv != CKR_OK) {
            goto loser;
        }
        sftk_DeleteAttributeType(key, CKA_PRIME);
        sftk_DeleteAttributeType(key, CKA_SUBPRIME);
        sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED);
        sftk_DeleteAttributeType(key, CKA_NSS_PQG_H);
    }

    sftk_DeleteAttributeType(key, CKA_PRIME_BITS);
    sftk_DeleteAttributeType(key, CKA_SUBPRIME_BITS);
    sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED_BITS);

    /* use the old PQG interface if we have old input data */
    if ((primeBits < 1024) || ((primeBits == 1024) && (subprimeBits == 0))) {
        if (seedBits == 0) {
            rv = PQG_ParamGen(j, &params, &vfy);
        } else {
            rv = PQG_ParamGenSeedLen(j, seedBits / 8, &params, &vfy);
        }
    } else {
        if (subprimeBits == 0) {
            subprimeBits = sftk_GetSubPrimeFromPrime(primeBits);
        }
        if (seedBits == 0) {
            seedBits = primeBits;
        }
        rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits / 8, &params, &vfy);
    }

    if (rv != SECSuccess) {
        if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
            sftk_fatalError = PR_TRUE;
        }
        return sftk_MapCryptError(PORT_GetError());
    }
    crv = sftk_AddAttributeType(key, CKA_PRIME,
                                params->prime.data, params->prime.len);
    if (crv != CKR_OK)
        goto loser;
    crv = sftk_AddAttributeType(key, CKA_SUBPRIME,
                                params->subPrime.data, params->subPrime.len);
    if (crv != CKR_OK)
        goto loser;
    crv = sftk_AddAttributeType(key, CKA_BASE,
                                params->base.data, params->base.len);
    if (crv != CKR_OK)
        goto loser;
    counter = vfy->counter;
    crv = sftk_AddAttributeType(key, CKA_NSS_PQG_COUNTER,
                                &counter, sizeof(counter));
    crv = sftk_AddAttributeType(key, CKA_NSS_PQG_SEED,
                                vfy->seed.data, vfy->seed.len);
    if (crv != CKR_OK)
        goto loser;
    crv = sftk_AddAttributeType(key, CKA_NSS_PQG_H,
                                vfy->h.data, vfy->h.len);
    if (crv != CKR_OK)
        goto loser;

loser:
    if (params) {
        PQG_DestroyParams(params);
    }

    if (vfy) {
        PQG_DestroyVerify(vfy);
    }
    return crv;
}

static CK_RV
nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
                    CK_ULONG *key_length)
{
    CK_RV crv = CKR_OK;

    switch (mechanism) {
        case CKM_RC2_KEY_GEN:
            *key_type = CKK_RC2;
            if (*key_length == 0)
                crv = CKR_TEMPLATE_INCOMPLETE;
            break;
#if NSS_SOFTOKEN_DOES_RC5
        case CKM_RC5_KEY_GEN:
            *key_type = CKK_RC5;
            if (*key_length == 0)
                crv = CKR_TEMPLATE_INCOMPLETE;
            break;
#endif
        case CKM_RC4_KEY_GEN:
            *key_type = CKK_RC4;
            if (*key_length == 0)
                crv = CKR_TEMPLATE_INCOMPLETE;
            break;
        case CKM_GENERIC_SECRET_KEY_GEN:
            *key_type = CKK_GENERIC_SECRET;
            if (*key_length == 0)
                crv = CKR_TEMPLATE_INCOMPLETE;
            break;
        case CKM_CDMF_KEY_GEN:
            *key_type = CKK_CDMF;
            *key_length = 8;
            break;
        case CKM_DES_KEY_GEN:
            *key_type = CKK_DES;
            *key_length = 8;
            break;
        case CKM_DES2_KEY_GEN:
            *key_type = CKK_DES2;
            *key_length = 16;
            break;
        case CKM_DES3_KEY_GEN:
            *key_type = CKK_DES3;
            *key_length = 24;
            break;
        case CKM_SEED_KEY_GEN:
            *key_type = CKK_SEED;
            *key_length = 16;
            break;
        case CKM_CAMELLIA_KEY_GEN:
            *key_type = CKK_CAMELLIA;
            if (*key_length == 0)
                crv = CKR_TEMPLATE_INCOMPLETE;
            break;
        case CKM_AES_KEY_GEN:
            *key_type = CKK_AES;
            if (*key_length == 0)
                crv = CKR_TEMPLATE_INCOMPLETE;
            break;
        case CKM_NSS_CHACHA20_KEY_GEN:
            *key_type = CKK_NSS_CHACHA20;
            if (*key_length == 0)
                crv = CKR_TEMPLATE_INCOMPLETE;
            break;
        default:
            PORT_Assert(0);
            crv = CKR_MECHANISM_INVALID;
            break;
    }

    return crv;
}

CK_RV
nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
{
    SECItem salt;
    CK_PBE_PARAMS *pbe_params = NULL;
    NSSPKCS5PBEParameter *params;
    PLArenaPool *arena = NULL;
    SECStatus rv;

    *pbe = NULL;

    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (arena == NULL) {
        return CKR_HOST_MEMORY;
    }

    params = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena,
                                                      sizeof(NSSPKCS5PBEParameter));
    if (params == NULL) {
        PORT_FreeArena(arena, PR_TRUE);
        return CKR_HOST_MEMORY;
    }

    params->poolp = arena;
    params->ivLen = 0;
    params->pbeType = NSSPKCS5_PKCS12_V2;
    params->hashType = HASH_AlgSHA1;
    params->encAlg = SEC_OID_SHA1; /* any invalid value */
    params->is2KeyDES = PR_FALSE;
    params->keyID = pbeBitGenIntegrityKey;
    pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
    params->iter = pbe_params->ulIteration;

    salt.data = (unsigned char *)pbe_params->pSalt;
    salt.len = (unsigned int)pbe_params->ulSaltLen;
    salt.type = siBuffer;
    rv = SECITEM_CopyItem(arena, &params->salt, &salt);
    if (rv != SECSuccess) {
        PORT_FreeArena(arena, PR_TRUE);
        return CKR_HOST_MEMORY;
    }
    switch (pMechanism->mechanism) {
        case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
        case CKM_PBA_SHA1_WITH_SHA1_HMAC:
            params->hashType = HASH_AlgSHA1;
            params->keyLen = 20;
            break;
        case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
            params->hashType = HASH_AlgMD5;
            params->keyLen = 16;
            break;
        case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
            params->hashType = HASH_AlgMD2;
            params->keyLen = 16;
            break;
        case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
            params->hashType = HASH_AlgSHA224;
            params->keyLen = 28;
            break;
        case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
            params->hashType = HASH_AlgSHA256;
            params->keyLen = 32;
            break;
        case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
            params->hashType = HASH_AlgSHA384;
            params->keyLen = 48;
            break;
        case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
            params->hashType = HASH_AlgSHA512;
            params->keyLen = 64;
            break;
        default:
            PORT_FreeArena(arena, PR_TRUE);
            return CKR_MECHANISM_INVALID;
    }
    *pbe = params;
    return CKR_OK;
}

/* maybe this should be table driven? */
static CK_RV
nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
                   CK_KEY_TYPE *key_type, CK_ULONG *key_length)
{
    CK_RV crv = CKR_OK;
    SECOidData *oid;
    CK_PBE_PARAMS *pbe_params = NULL;
    NSSPKCS5PBEParameter *params = NULL;
    HASH_HashType hashType = HASH_AlgSHA1;
    CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;
    SECItem salt;
    CK_ULONG iteration = 0;

    *pbe = NULL;

    oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
    if (oid == NULL) {
        return CKR_MECHANISM_INVALID;
    }

    if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
        pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
        if (pbkd2_params == NULL) {
            return CKR_MECHANISM_PARAM_INVALID;
        }
        switch (pbkd2_params->prf) {
            case CKP_PKCS5_PBKD2_HMAC_SHA1:
                hashType = HASH_AlgSHA1;
                break;
            case CKP_PKCS5_PBKD2_HMAC_SHA224:
                hashType = HASH_AlgSHA224;
                break;
            case CKP_PKCS5_PBKD2_HMAC_SHA256:
                hashType = HASH_AlgSHA256;
                break;
            case CKP_PKCS5_PBKD2_HMAC_SHA384:
                hashType = HASH_AlgSHA384;
                break;
            case CKP_PKCS5_PBKD2_HMAC_SHA512:
                hashType = HASH_AlgSHA512;
                break;
            default:
                return CKR_MECHANISM_PARAM_INVALID;
        }
        if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED) {
            return CKR_MECHANISM_PARAM_INVALID;
        }
        salt.data = (unsigned char *)pbkd2_params->pSaltSourceData;
        salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen;
        iteration = pbkd2_params->iterations;
    } else {
        pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
        salt.data = (unsigned char *)pbe_params->pSalt;
        salt.len = (unsigned int)pbe_params->ulSaltLen;
        iteration = pbe_params->ulIteration;
    }
    params = nsspkcs5_NewParam(oid->offset, hashType, &salt, iteration);
    if (params == NULL) {
        return CKR_MECHANISM_INVALID;
    }

    switch (params->encAlg) {
        case SEC_OID_DES_CBC:
            *key_type = CKK_DES;
            *key_length = params->keyLen;
            break;
        case SEC_OID_DES_EDE3_CBC:
            *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3;
            *key_length = params->keyLen;
            break;
        case SEC_OID_RC2_CBC:
            *key_type = CKK_RC2;
            *key_length = params->keyLen;
            break;
        case SEC_OID_RC4:
            *key_type = CKK_RC4;
            *key_length = params->keyLen;
            break;
        case SEC_OID_PKCS5_PBKDF2:
            /* key type must already be set */
            if (*key_type == CKK_INVALID_KEY_TYPE) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                break;
            }
            /* PBKDF2 needs to calculate the key length from the other parameters
             */
            if (*key_length == 0) {
                *key_length = sftk_MapKeySize(*key_type);
            }
            if (*key_length == 0) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                break;
            }
            params->keyLen = *key_length;
            break;
        default:
            crv = CKR_MECHANISM_INVALID;
            nsspkcs5_DestroyPBEParameter(params);
            break;
    }
    if (crv == CKR_OK) {
        *pbe = params;
    }
    return crv;
}

/* NSC_GenerateKey generates a secret key, creating a new key object. */
CK_RV
NSC_GenerateKey(CK_SESSION_HANDLE hSession,
                CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
                CK_OBJECT_HANDLE_PTR phKey)
{
    SFTKObject *key;
    SFTKSession *session;
    PRBool checkWeak = PR_FALSE;
    CK_ULONG key_length = 0;
    CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE;
    CK_OBJECT_CLASS objclass = CKO_SECRET_KEY;
    CK_RV crv = CKR_OK;
    CK_BBOOL cktrue = CK_TRUE;
    int i;
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    unsigned char buf[MAX_KEY_LEN];
    enum { nsc_pbe,
           nsc_ssl,
           nsc_bulk,
           nsc_param,
           nsc_jpake } key_gen_type;
    NSSPKCS5PBEParameter *pbe_param;
    SSL3RSAPreMasterSecret *rsa_pms;
    CK_VERSION *version;
    /* in very old versions of NSS, there were implementation errors with key
     * generation methods.  We want to beable to read these, but not
     * produce them any more.  The affected algorithm was 3DES.
     */
    PRBool faultyPBE3DES = PR_FALSE;
    HASH_HashType hashType = HASH_AlgNULL;

    CHECK_FORK();

    if (!slot) {
        return CKR_SESSION_HANDLE_INVALID;
    }
    /*
     * now lets create an object to hang the attributes off of
     */
    key = sftk_NewObject(slot); /* fill in the handle later */
    if (key == NULL) {
        return CKR_HOST_MEMORY;
    }

    /*
     * load the template values into the object
     */
    for (i = 0; i < (int)ulCount; i++) {
        if (pTemplate[i].type == CKA_VALUE_LEN) {
            key_length = *(CK_ULONG *)pTemplate[i].pValue;
            continue;
        }
        /* some algorithms need keytype specified */
        if (pTemplate[i].type == CKA_KEY_TYPE) {
            key_type = *(CK_ULONG *)pTemplate[i].pValue;
            continue;
        }

        crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i]));
        if (crv != CKR_OK)
            break;
    }
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }

    /* make sure we don't have any class, key_type, or value fields */
    sftk_DeleteAttributeType(key, CKA_CLASS);
    sftk_DeleteAttributeType(key, CKA_KEY_TYPE);
    sftk_DeleteAttributeType(key, CKA_VALUE);

    /* Now Set up the parameters to generate the key (based on mechanism) */
    key_gen_type = nsc_bulk; /* bulk key by default */
    switch (pMechanism->mechanism) {
        case CKM_CDMF_KEY_GEN:
        case CKM_DES_KEY_GEN:
        case CKM_DES2_KEY_GEN:
        case CKM_DES3_KEY_GEN:
            checkWeak = PR_TRUE;
        /* fall through */
        case CKM_RC2_KEY_GEN:
        case CKM_RC4_KEY_GEN:
        case CKM_GENERIC_SECRET_KEY_GEN:
        case CKM_SEED_KEY_GEN:
        case CKM_CAMELLIA_KEY_GEN:
        case CKM_AES_KEY_GEN:
        case CKM_NSS_CHACHA20_KEY_GEN:
#if NSS_SOFTOKEN_DOES_RC5
        case CKM_RC5_KEY_GEN:
#endif
            crv = nsc_SetupBulkKeyGen(pMechanism->mechanism, &key_type, &key_length);
            break;
        case CKM_SSL3_PRE_MASTER_KEY_GEN:
            key_type = CKK_GENERIC_SECRET;
            key_length = 48;
            key_gen_type = nsc_ssl;
            break;
        case CKM_PBA_SHA1_WITH_SHA1_HMAC:
        case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
        case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
        case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
        case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
        case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
        case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
        case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
            key_gen_type = nsc_pbe;
            key_type = CKK_GENERIC_SECRET;
            crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
            break;
        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
            faultyPBE3DES = PR_TRUE;
        /* fall through */
        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
        case CKM_PBE_SHA1_DES3_EDE_CBC:
        case CKM_PBE_SHA1_DES2_EDE_CBC:
        case CKM_PBE_SHA1_RC2_128_CBC:
        case CKM_PBE_SHA1_RC2_40_CBC:
        case CKM_PBE_SHA1_RC4_128:
        case CKM_PBE_SHA1_RC4_40:
        case CKM_PBE_MD5_DES_CBC:
        case CKM_PBE_MD2_DES_CBC:
        case CKM_PKCS5_PBKD2:
            key_gen_type = nsc_pbe;
            crv = nsc_SetupPBEKeyGen(pMechanism, &pbe_param, &key_type, &key_length);
            break;
        case CKM_DSA_PARAMETER_GEN:
            key_gen_type = nsc_param;
            key_type = CKK_DSA;
            objclass = CKO_KG_PARAMETERS;
            crv = CKR_OK;
            break;
        case CKM_NSS_JPAKE_ROUND1_SHA1:
            hashType = HASH_AlgSHA1;
            goto jpake1;
        case CKM_NSS_JPAKE_ROUND1_SHA256:
            hashType = HASH_AlgSHA256;
            goto jpake1;
        case CKM_NSS_JPAKE_ROUND1_SHA384:
            hashType = HASH_AlgSHA384;
            goto jpake1;
        case CKM_NSS_JPAKE_ROUND1_SHA512:
            hashType = HASH_AlgSHA512;
            goto jpake1;
        jpake1:
            key_gen_type = nsc_jpake;
            key_type = CKK_NSS_JPAKE_ROUND1;
            objclass = CKO_PRIVATE_KEY;
            if (pMechanism->pParameter == NULL ||
                pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound1Params)) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            if (sftk_isTrue(key, CKA_TOKEN)) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            crv = CKR_OK;
            break;
        default:
            crv = CKR_MECHANISM_INVALID;
            break;
    }

    /* make sure we aren't going to overflow the buffer */
    if (sizeof(buf) < key_length) {
        /* someone is getting pretty optimistic about how big their key can
         * be... */
        crv = CKR_TEMPLATE_INCONSISTENT;
    }

    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }

    /* if there was no error,
     * key_type *MUST* be set in the switch statement above */
    PORT_Assert(key_type != CKK_INVALID_KEY_TYPE);

    /*
     * now to the actual key gen.
     */
    switch (key_gen_type) {
        case nsc_pbe:
            crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length,
                                  faultyPBE3DES);
            nsspkcs5_DestroyPBEParameter(pbe_param);
            break;
        case nsc_ssl:
            rsa_pms = (SSL3RSAPreMasterSecret *)buf;
            version = (CK_VERSION *)pMechanism->pParameter;
            rsa_pms->client_version[0] = version->major;
            rsa_pms->client_version[1] = version->minor;
            crv =
                NSC_GenerateRandom(0, &rsa_pms->random[0], sizeof(rsa_pms->random));
            break;
        case nsc_bulk:
            /* get the key, check for weak keys and repeat if found */
            do {
                crv = NSC_GenerateRandom(0, buf, key_length);
            } while (crv == CKR_OK && checkWeak && sftk_IsWeakKey(buf, key_type));
            break;
        case nsc_param:
            /* generate parameters */
            *buf = 0;
            crv = nsc_parameter_gen(key_type, key);
            break;
        case nsc_jpake:
            crv = jpake_Round1(hashType,
                               (CK_NSS_JPAKERound1Params *)pMechanism->pParameter,
                               key);
            break;
    }

    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }

    /* Add the class, key_type, and value */
    crv = sftk_AddAttributeType(key, CKA_CLASS, &objclass, sizeof(CK_OBJECT_CLASS));
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }
    crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &key_type, sizeof(CK_KEY_TYPE));
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }
    if (key_length != 0) {
        crv = sftk_AddAttributeType(key, CKA_VALUE, buf, key_length);
        if (crv != CKR_OK) {
            sftk_FreeObject(key);
            return crv;
        }
    }

    /* get the session */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
        sftk_FreeObject(key);
        return CKR_SESSION_HANDLE_INVALID;
    }

    /*
     * handle the base object stuff
     */
    crv = sftk_handleObject(key, session);
    sftk_FreeSession(session);
    if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
        crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL));
    }
    if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) {
        crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
    }
    if (crv == CKR_OK) {
        *phKey = key->handle;
    }
    sftk_FreeObject(key);
    return crv;
}

#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
#define PAIRWISE_MESSAGE_LENGTH 20         /* 160-bits */

/*
 * FIPS 140-2 pairwise consistency check utilized to validate key pair.
 *
 * This function returns
 *   CKR_OK               if pairwise consistency check passed
 *   CKR_GENERAL_ERROR    if pairwise consistency check failed
 *   other error codes    if paiswise consistency check could not be
 *                        performed, for example, CKR_HOST_MEMORY.
 */
static CK_RV
sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
                              SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
{
    /*
     *                      Key type    Mechanism type
     *                      --------------------------------
     * For encrypt/decrypt: CKK_RSA  => CKM_RSA_PKCS
     *                      others   => CKM_INVALID_MECHANISM
     *
     * For sign/verify:     CKK_RSA  => CKM_RSA_PKCS
     *                      CKK_DSA  => CKM_DSA
     *                      CKK_EC   => CKM_ECDSA
     *                      others   => CKM_INVALID_MECHANISM
     *
     * None of these mechanisms has a parameter.
     */
    CK_MECHANISM mech = { 0, NULL, 0 };

    CK_ULONG modulusLen = 0;
    CK_ULONG subPrimeLen = 0;
    PRBool isEncryptable = PR_FALSE;
    PRBool canSignVerify = PR_FALSE;
    PRBool isDerivable = PR_FALSE;
    CK_RV crv;

    /* Variables used for Encrypt/Decrypt functions. */
    unsigned char *known_message = (unsigned char *)"Known Crypto Message";
    unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH];
    CK_ULONG bytes_decrypted;
    unsigned char *ciphertext;
    unsigned char *text_compared;
    CK_ULONG bytes_encrypted;
    CK_ULONG bytes_compared;
    CK_ULONG pairwise_digest_length = PAIRWISE_DIGEST_LENGTH;

    /* Variables used for Signature/Verification functions. */
    /* Must be at least 256 bits for DSA2 digest */
    unsigned char *known_digest = (unsigned char *)"Mozilla Rules the World through NSS!";
    unsigned char *signature;
    CK_ULONG signature_length;

    if (keyType == CKK_RSA) {
        SFTKAttribute *attribute;

        /* Get modulus length of private key. */
        attribute = sftk_FindAttribute(privateKey, CKA_MODULUS);
        if (attribute == NULL) {
            return CKR_DEVICE_ERROR;
        }
        modulusLen = attribute->attrib.ulValueLen;
        if (*(unsigned char *)attribute->attrib.pValue == 0) {
            modulusLen--;
        }
        sftk_FreeAttribute(attribute);
    } else if (keyType == CKK_DSA) {
        SFTKAttribute *attribute;

        /* Get subprime length of private key. */
        attribute = sftk_FindAttribute(privateKey, CKA_SUBPRIME);
        if (attribute == NULL) {
            return CKR_DEVICE_ERROR;
        }
        subPrimeLen = attribute->attrib.ulValueLen;
        if (subPrimeLen > 1 && *(unsigned char *)attribute->attrib.pValue == 0) {
            subPrimeLen--;
        }
        sftk_FreeAttribute(attribute);
    }

    /**************************************************/
    /* Pairwise Consistency Check of Encrypt/Decrypt. */
    /**************************************************/

    isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT);

    /*
     * If the decryption attribute is set, attempt to encrypt
     * with the public key and decrypt with the private key.
     */
    if (isEncryptable) {
        if (keyType != CKK_RSA) {
            return CKR_DEVICE_ERROR;
        }
        bytes_encrypted = modulusLen;
        mech.mechanism = CKM_RSA_PKCS;

        /* Allocate space for ciphertext. */
        ciphertext = (unsigned char *)PORT_ZAlloc(bytes_encrypted);
        if (ciphertext == NULL) {
            return CKR_HOST_MEMORY;
        }

        /* Prepare for encryption using the public key. */
        crv = NSC_EncryptInit(hSession, &mech, publicKey->handle);
        if (crv != CKR_OK) {
            PORT_Free(ciphertext);
            return crv;
        }

        /* Encrypt using the public key. */
        crv = NSC_Encrypt(hSession,
                          known_message,
                          PAIRWISE_MESSAGE_LENGTH,
                          ciphertext,
                          &bytes_encrypted);
        if (crv != CKR_OK) {
            PORT_Free(ciphertext);
            return crv;
        }

        /* Always use the smaller of these two values . . . */
        bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH);

        /*
         * If there was a failure, the plaintext
         * goes at the end, therefore . . .
         */
        text_compared = ciphertext + bytes_encrypted - bytes_compared;

        /*
         * Check to ensure that ciphertext does
         * NOT EQUAL known input message text
         * per FIPS PUB 140-2 directive.
         */
        if (PORT_Memcmp(text_compared, known_message,
                        bytes_compared) == 0) {
            /* Set error to Invalid PRIVATE Key. */
            PORT_SetError(SEC_ERROR_INVALID_KEY);
            PORT_Free(ciphertext);
            return CKR_GENERAL_ERROR;
        }

        /* Prepare for decryption using the private key. */
        crv = NSC_DecryptInit(hSession, &mech, privateKey->handle);
        if (crv != CKR_OK) {
            PORT_Free(ciphertext);
            return crv;
        }

        memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH);

        /*
         * Initialize bytes decrypted to be the
         * expected PAIRWISE_MESSAGE_LENGTH.
         */
        bytes_decrypted = PAIRWISE_MESSAGE_LENGTH;

        /*
         * Decrypt using the private key.
         * NOTE:  No need to reset the
         *        value of bytes_encrypted.
         */
        crv = NSC_Decrypt(hSession,
                          ciphertext,
                          bytes_encrypted,
                          plaintext,
                          &bytes_decrypted);

        /* Finished with ciphertext; free it. */
        PORT_Free(ciphertext);

        if (crv != CKR_OK) {
            return crv;
        }

        /*
         * Check to ensure that the output plaintext
         * does EQUAL known input message text.
         */
        if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH) ||
            (PORT_Memcmp(plaintext, known_message,
                         PAIRWISE_MESSAGE_LENGTH) != 0)) {
            /* Set error to Bad PUBLIC Key. */
            PORT_SetError(SEC_ERROR_BAD_KEY);
            return CKR_GENERAL_ERROR;
        }
    }

    /**********************************************/
    /* Pairwise Consistency Check of Sign/Verify. */
    /**********************************************/

    canSignVerify = sftk_isTrue(privateKey, CKA_SIGN);
    /* Unfortunately CKA_SIGN is always true in lg dbs. We have to check the
     * actual curve to determine if we can do sign/verify. */
    if (canSignVerify && keyType == CKK_EC) {
        NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(privateKey, CKK_EC, &crv);
        if (privKey && privKey->u.ec.ecParams.name == ECCurve25519) {
            canSignVerify = PR_FALSE;
        }
    }

    if (canSignVerify) {
        /* Determine length of signature. */
        switch (keyType) {
            case CKK_RSA:
                signature_length = modulusLen;
                mech.mechanism = CKM_RSA_PKCS;
                break;
            case CKK_DSA:
                signature_length = DSA_MAX_SIGNATURE_LEN;
                pairwise_digest_length = subPrimeLen;
                mech.mechanism = CKM_DSA;
                break;
            case CKK_EC:
                signature_length = MAX_ECKEY_LEN * 2;
                mech.mechanism = CKM_ECDSA;
                break;
            default:
                return CKR_DEVICE_ERROR;
        }

        /* Allocate space for signature data. */
        signature = (unsigned char *)PORT_ZAlloc(signature_length);
        if (signature == NULL) {
            return CKR_HOST_MEMORY;
        }

        /* Sign the known hash using the private key. */
        crv = NSC_SignInit(hSession, &mech, privateKey->handle);
        if (crv != CKR_OK) {
            PORT_Free(signature);
            return crv;
        }

        crv = NSC_Sign(hSession,
                       known_digest,
                       pairwise_digest_length,
                       signature,
                       &signature_length);
        if (crv != CKR_OK) {
            PORT_Free(signature);
            return crv;
        }

        /* Verify the known hash using the public key. */
        crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
        if (crv != CKR_OK) {
            PORT_Free(signature);
            return crv;
        }

        crv = NSC_Verify(hSession,
                         known_digest,
                         pairwise_digest_length,
                         signature,
                         signature_length);

        /* Free signature data. */
        PORT_Free(signature);

        if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
            (crv == CKR_SIGNATURE_INVALID)) {
            return CKR_GENERAL_ERROR;
        }
        if (crv != CKR_OK) {
            return crv;
        }
    }

    /**********************************************/
    /* Pairwise Consistency Check for Derivation  */
    /**********************************************/

    isDerivable = sftk_isTrue(privateKey, CKA_DERIVE);

    if (isDerivable) {
        /*
         * We are not doing consistency check for Diffie-Hellman Key -
         * otherwise it would be here
         * This is also true for Elliptic Curve Diffie-Hellman keys
         * NOTE: EC keys are currently subjected to pairwise
         * consistency check for signing/verification.
         */
        /*
         * FIPS 140-2 had the following pairwise consistency test for
         * public and private keys used for key agreement:
         *   If the keys are used to perform key agreement, then the
         *   cryptographic module shall create a second, compatible
         *   key pair.  The cryptographic module shall perform both
         *   sides of the key agreement algorithm and shall compare
         *   the resulting shared values.  If the shared values are
         *   not equal, the test shall fail.
         * This test was removed in Change Notice 3.
         */
    }

    return CKR_OK;
}

/* NSC_GenerateKeyPair generates a public-key/private-key pair,
 * creating new key objects. */
CK_RV
NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession,
                    CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
                    CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
                    CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
                    CK_OBJECT_HANDLE_PTR phPrivateKey)
{
    SFTKObject *publicKey, *privateKey;
    SFTKSession *session;
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    CK_BBOOL cktrue = CK_TRUE;
    SECStatus rv;
    CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
    CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
    int i;
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    unsigned int bitSize;

    /* RSA */
    int public_modulus_bits = 0;
    SECItem pubExp;
    RSAPrivateKey *rsaPriv;

    /* DSA */
    PQGParams pqgParam;
    DHParams dhParam;
    DSAPrivateKey *dsaPriv;

    /* Diffie Hellman */
    DHPrivateKey *dhPriv;

    /* Elliptic Curve Cryptography */
    SECItem ecEncodedParams; /* DER Encoded parameters */
    ECPrivateKey *ecPriv;
    ECParams *ecParams;

    CHECK_FORK();

    if (!slot) {
        return CKR_SESSION_HANDLE_INVALID;
    }
    /*
     * now lets create an object to hang the attributes off of
     */
    publicKey = sftk_NewObject(slot); /* fill in the handle later */
    if (publicKey == NULL) {
        return CKR_HOST_MEMORY;
    }

    /*
     * load the template values into the publicKey
     */
    for (i = 0; i < (int)ulPublicKeyAttributeCount; i++) {
        if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS) {
            public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue;
            continue;
        }

        crv = sftk_AddAttributeType(publicKey,
                                    sftk_attr_expand(&pPublicKeyTemplate[i]));
        if (crv != CKR_OK)
            break;
    }

    if (crv != CKR_OK) {
        sftk_FreeObject(publicKey);
        return CKR_HOST_MEMORY;
    }

    privateKey = sftk_NewObject(slot); /* fill in the handle later */
    if (privateKey == NULL) {
        sftk_FreeObject(publicKey);
        return CKR_HOST_MEMORY;
    }
    /*
     * now load the private key template
     */
    for (i = 0; i < (int)ulPrivateKeyAttributeCount; i++) {
        if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) {
            continue;
        }

        crv = sftk_AddAttributeType(privateKey,
                                    sftk_attr_expand(&pPrivateKeyTemplate[i]));
        if (crv != CKR_OK)
            break;
    }

    if (crv != CKR_OK) {
        sftk_FreeObject(publicKey);
        sftk_FreeObject(privateKey);
        return CKR_HOST_MEMORY;
    }
    sftk_DeleteAttributeType(privateKey, CKA_CLASS);
    sftk_DeleteAttributeType(privateKey, CKA_KEY_TYPE);
    sftk_DeleteAttributeType(privateKey, CKA_VALUE);
    sftk_DeleteAttributeType(publicKey, CKA_CLASS);
    sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE);
    sftk_DeleteAttributeType(publicKey, CKA_VALUE);

    /* Now Set up the parameters to generate the key (based on mechanism) */
    switch (pMechanism->mechanism) {
        case CKM_RSA_PKCS_KEY_PAIR_GEN:
            /* format the keys */
            sftk_DeleteAttributeType(publicKey, CKA_MODULUS);
            sftk_DeleteAttributeType(privateKey, CKA_NETSCAPE_DB);
            sftk_DeleteAttributeType(privateKey, CKA_MODULUS);
            sftk_DeleteAttributeType(privateKey, CKA_PRIVATE_EXPONENT);
            sftk_DeleteAttributeType(privateKey, CKA_PUBLIC_EXPONENT);
            sftk_DeleteAttributeType(privateKey, CKA_PRIME_1);
            sftk_DeleteAttributeType(privateKey, CKA_PRIME_2);
            sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_1);
            sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_2);
            sftk_DeleteAttributeType(privateKey, CKA_COEFFICIENT);
            key_type = CKK_RSA;
            if (public_modulus_bits == 0) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                break;
            }
            if (public_modulus_bits < RSA_MIN_MODULUS_BITS) {
                crv = CKR_ATTRIBUTE_VALUE_INVALID;
                break;
            }
            if (public_modulus_bits % 2 != 0) {
                crv = CKR_ATTRIBUTE_VALUE_INVALID;
                break;
            }

            /* extract the exponent */
            crv = sftk_Attribute2SSecItem(NULL, &pubExp, publicKey, CKA_PUBLIC_EXPONENT);
            if (crv != CKR_OK)
                break;
            bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len);
            if (bitSize < 2) {
                crv = CKR_ATTRIBUTE_VALUE_INVALID;
                break;
            }
            crv = sftk_AddAttributeType(privateKey, CKA_PUBLIC_EXPONENT,
                                        sftk_item_expand(&pubExp));
            if (crv != CKR_OK) {
                PORT_Free(pubExp.data);
                break;
            }

            rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
            PORT_Free(pubExp.data);
            if (rsaPriv == NULL) {
                if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
                    sftk_fatalError = PR_TRUE;
                }
                crv = sftk_MapCryptError(PORT_GetError());
                break;
            }
            /* now fill in the RSA dependent paramenters in the public key */
            crv = sftk_AddAttributeType(publicKey, CKA_MODULUS,
                                        sftk_item_expand(&rsaPriv->modulus));
            if (crv != CKR_OK)
                goto kpg_done;
            /* now fill in the RSA dependent paramenters in the private key */
            crv = sftk_AddAttributeType(privateKey, CKA_NETSCAPE_DB,
                                        sftk_item_expand(&rsaPriv->modulus));
            if (crv != CKR_OK)
                goto kpg_done;
            crv = sftk_AddAttributeType(privateKey, CKA_MODULUS,
                                        sftk_item_expand(&rsaPriv->modulus));
            if (crv != CKR_OK)
                goto kpg_done;
            crv = sftk_AddAttributeType(privateKey, CKA_PRIVATE_EXPONENT,
                                        sftk_item_expand(&rsaPriv->privateExponent));
            if (crv != CKR_OK)
                goto kpg_done;
            crv = sftk_AddAttributeType(privateKey, CKA_PRIME_1,
                                        sftk_item_expand(&rsaPriv->prime1));
            if (crv != CKR_OK)
                goto kpg_done;
            crv = sftk_AddAttributeType(privateKey, CKA_PRIME_2,
                                        sftk_item_expand(&rsaPriv->prime2));
            if (crv != CKR_OK)
                goto kpg_done;
            crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_1,
                                        sftk_item_expand(&rsaPriv->exponent1));
            if (crv != CKR_OK)
                goto kpg_done;
            crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_2,
                                        sftk_item_expand(&rsaPriv->exponent2));
            if (crv != CKR_OK)
                goto kpg_done;
            crv = sftk_AddAttributeType(privateKey, CKA_COEFFICIENT,
                                        sftk_item_expand(&rsaPriv->coefficient));
        kpg_done:
            /* Should zeroize the contents first, since this func doesn't. */
            PORT_FreeArena(rsaPriv->arena, PR_TRUE);
            break;
        case CKM_DSA_KEY_PAIR_GEN:
            sftk_DeleteAttributeType(publicKey, CKA_VALUE);
            sftk_DeleteAttributeType(privateKey, CKA_NETSCAPE_DB);
            sftk_DeleteAttributeType(privateKey, CKA_PRIME);
            sftk_DeleteAttributeType(privateKey, CKA_SUBPRIME);
            sftk_DeleteAttributeType(privateKey, CKA_BASE);
            key_type = CKK_DSA;

            /* extract the necessary parameters and copy them to the private key */
            crv = sftk_Attribute2SSecItem(NULL, &pqgParam.prime, publicKey, CKA_PRIME);
            if (crv != CKR_OK)
                break;
            crv = sftk_Attribute2SSecItem(NULL, &pqgParam.subPrime, publicKey,
                                          CKA_SUBPRIME);
            if (crv != CKR_OK) {
                PORT_Free(pqgParam.prime.data);
                break;
            }
            crv = sftk_Attribute2SSecItem(NULL, &pqgParam.base, publicKey, CKA_BASE);
            if (crv != CKR_OK) {
                PORT_Free(pqgParam.prime.data);
                PORT_Free(pqgParam.subPrime.data);
                break;
            }
            crv = sftk_AddAttributeType(privateKey, CKA_PRIME,
                                        sftk_item_expand(&pqgParam.prime));
            if (crv != CKR_OK) {
                PORT_Free(pqgParam.prime.data);
                PORT_Free(pqgParam.subPrime.data);
                PORT_Free(pqgParam.base.data);
                break;
            }
            crv = sftk_AddAttributeType(privateKey, CKA_SUBPRIME,
                                        sftk_item_expand(&pqgParam.subPrime));
            if (crv != CKR_OK) {
                PORT_Free(pqgParam.prime.data);
                PORT_Free(pqgParam.subPrime.data);
                PORT_Free(pqgParam.base.data);
                break;
            }
            crv = sftk_AddAttributeType(privateKey, CKA_BASE,
                                        sftk_item_expand(&pqgParam.base));
            if (crv != CKR_OK) {
                PORT_Free(pqgParam.prime.data);
                PORT_Free(pqgParam.subPrime.data);
                PORT_Free(pqgParam.base.data);
                break;
            }

            /*
             * these are checked by DSA_NewKey
             */
            bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data,
                                           pqgParam.subPrime.len);
            if ((bitSize < DSA_MIN_Q_BITS) || (bitSize > DSA_MAX_Q_BITS)) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                PORT_Free(pqgParam.prime.data);
                PORT_Free(pqgParam.subPrime.data);
                PORT_Free(pqgParam.base.data);
                break;
            }
            bitSize = sftk_GetLengthInBits(pqgParam.prime.data, pqgParam.prime.len);
            if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                PORT_Free(pqgParam.prime.data);
                PORT_Free(pqgParam.subPrime.data);
                PORT_Free(pqgParam.base.data);
                break;
            }
            bitSize = sftk_GetLengthInBits(pqgParam.base.data, pqgParam.base.len);
            if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS)) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                PORT_Free(pqgParam.prime.data);
                PORT_Free(pqgParam.subPrime.data);
                PORT_Free(pqgParam.base.data);
                break;
            }

            /* Generate the key */
            rv = DSA_NewKey(&pqgParam, &dsaPriv);

            PORT_Free(pqgParam.prime.data);
            PORT_Free(pqgParam.subPrime.data);
            PORT_Free(pqgParam.base.data);

            if (rv != SECSuccess) {
                if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
                    sftk_fatalError = PR_TRUE;
                }
                crv = sftk_MapCryptError(PORT_GetError());
                break;
            }

            /* store the generated key into the attributes */
            crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
                                        sftk_item_expand(&dsaPriv->publicValue));
            if (crv != CKR_OK)
                goto dsagn_done;

            /* now fill in the RSA dependent paramenters in the private key */
            crv = sftk_AddAttributeType(privateKey, CKA_NETSCAPE_DB,
                                        sftk_item_expand(&dsaPriv->publicValue));
            if (crv != CKR_OK)
                goto dsagn_done;
            crv = sftk_AddAttributeType(privateKey, CKA_VALUE,
                                        sftk_item_expand(&dsaPriv->privateValue));

        dsagn_done:
            /* should zeroize, since this function doesn't. */
            PORT_FreeArena(dsaPriv->params.arena, PR_TRUE);
            break;

        case CKM_DH_PKCS_KEY_PAIR_GEN:
            sftk_DeleteAttributeType(privateKey, CKA_PRIME);
            sftk_DeleteAttributeType(privateKey, CKA_BASE);
            sftk_DeleteAttributeType(privateKey, CKA_VALUE);
            sftk_DeleteAttributeType(privateKey, CKA_NETSCAPE_DB);
            key_type = CKK_DH;

            /* extract the necessary parameters and copy them to private keys */
            crv = sftk_Attribute2SSecItem(NULL, &dhParam.prime, publicKey,
                                          CKA_PRIME);
            if (crv != CKR_OK)
                break;
            crv = sftk_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE);
            if (crv != CKR_OK) {
                PORT_Free(dhParam.prime.data);
                break;
            }
            crv = sftk_AddAttributeType(privateKey, CKA_PRIME,
                                        sftk_item_expand(&dhParam.prime));
            if (crv != CKR_OK) {
                PORT_Free(dhParam.prime.data);
                PORT_Free(dhParam.base.data);
                break;
            }
            crv = sftk_AddAttributeType(privateKey, CKA_BASE,
                                        sftk_item_expand(&dhParam.base));
            if (crv != CKR_OK) {
                PORT_Free(dhParam.prime.data);
                PORT_Free(dhParam.base.data);
                break;
            }
            bitSize = sftk_GetLengthInBits(dhParam.prime.data, dhParam.prime.len);
            if ((bitSize < DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                PORT_Free(dhParam.prime.data);
                PORT_Free(dhParam.base.data);
                break;
            }
            bitSize = sftk_GetLengthInBits(dhParam.base.data, dhParam.base.len);
            if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS)) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                PORT_Free(dhParam.prime.data);
                PORT_Free(dhParam.base.data);
                break;
            }

            rv = DH_NewKey(&dhParam, &dhPriv);
            PORT_Free(dhParam.prime.data);
            PORT_Free(dhParam.base.data);
            if (rv != SECSuccess) {
                if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
                    sftk_fatalError = PR_TRUE;
                }
                crv = sftk_MapCryptError(PORT_GetError());
                break;
            }

            crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
                                        sftk_item_expand(&dhPriv->publicValue));
            if (crv != CKR_OK)
                goto dhgn_done;

            crv = sftk_AddAttributeType(privateKey, CKA_NETSCAPE_DB,
                                        sftk_item_expand(&dhPriv->publicValue));
            if (crv != CKR_OK)
                goto dhgn_done;

            crv = sftk_AddAttributeType(privateKey, CKA_VALUE,
                                        sftk_item_expand(&dhPriv->privateValue));

        dhgn_done:
            /* should zeroize, since this function doesn't. */
            PORT_FreeArena(dhPriv->arena, PR_TRUE);
            break;

        case CKM_EC_KEY_PAIR_GEN:
            sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS);
            sftk_DeleteAttributeType(privateKey, CKA_VALUE);
            sftk_DeleteAttributeType(privateKey, CKA_NETSCAPE_DB);
            key_type = CKK_EC;

            /* extract the necessary parameters and copy them to private keys */
            crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey,
                                          CKA_EC_PARAMS);
            if (crv != CKR_OK)
                break;

            crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS,
                                        sftk_item_expand(&ecEncodedParams));
            if (crv != CKR_OK) {
                PORT_Free(ecEncodedParams.data);
                break;
            }

            /* Decode ec params before calling EC_NewKey */
            rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
            PORT_Free(ecEncodedParams.data);
            if (rv != SECSuccess) {
                crv = sftk_MapCryptError(PORT_GetError());
                break;
            }
            rv = EC_NewKey(ecParams, &ecPriv);
            if (rv != SECSuccess) {
                if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
                    sftk_fatalError = PR_TRUE;
                }
                PORT_FreeArena(ecParams->arena, PR_TRUE);
                crv = sftk_MapCryptError(PORT_GetError());
                break;
            }

            if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
                ecParams->fieldID.type == ec_field_plain) {
                PORT_FreeArena(ecParams->arena, PR_TRUE);
                crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
                                            sftk_item_expand(&ecPriv->publicValue));
            } else {
                PORT_FreeArena(ecParams->arena, PR_TRUE);
                SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
                                                       &ecPriv->publicValue,
                                                       SEC_ASN1_GET(SEC_OctetStringTemplate));
                if (!pubValue) {
                    crv = CKR_ARGUMENTS_BAD;
                    goto ecgn_done;
                }
                crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
                                            sftk_item_expand(pubValue));
                SECITEM_FreeItem(pubValue, PR_TRUE);
            }
            if (crv != CKR_OK)
                goto ecgn_done;

            crv = sftk_AddAttributeType(privateKey, CKA_VALUE,
                                        sftk_item_expand(&ecPriv->privateValue));
            if (crv != CKR_OK)
                goto ecgn_done;

            crv = sftk_AddAttributeType(privateKey, CKA_NETSCAPE_DB,
                                        sftk_item_expand(&ecPriv->publicValue));
        ecgn_done:
            /* should zeroize, since this function doesn't. */
            PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
            break;

        default:
            crv = CKR_MECHANISM_INVALID;
    }

    if (crv != CKR_OK) {
        sftk_FreeObject(privateKey);
        sftk_FreeObject(publicKey);
        return crv;
    }

    /* Add the class, key_type The loop lets us check errors blow out
     *  on errors and clean up at the bottom */
    session = NULL; /* make pedtantic happy... session cannot leave the*/
                    /* loop below NULL unless an error is set... */
    do {
        crv = sftk_AddAttributeType(privateKey, CKA_CLASS, &privClass,
                                    sizeof(CK_OBJECT_CLASS));
        if (crv != CKR_OK)
            break;
        crv = sftk_AddAttributeType(publicKey, CKA_CLASS, &pubClass,
                                    sizeof(CK_OBJECT_CLASS));
        if (crv != CKR_OK)
            break;
        crv = sftk_AddAttributeType(privateKey, CKA_KEY_TYPE, &key_type,
                                    sizeof(CK_KEY_TYPE));
        if (crv != CKR_OK)
            break;
        crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE, &key_type,
                                    sizeof(CK_KEY_TYPE));
        if (crv != CKR_OK)
            break;
        session = sftk_SessionFromHandle(hSession);
        if (session == NULL)
            crv = CKR_SESSION_HANDLE_INVALID;
    } while (0);

    if (crv != CKR_OK) {
        sftk_FreeObject(privateKey);
        sftk_FreeObject(publicKey);
        return crv;
    }

    /*
     * handle the base object cleanup for the public Key
     */
    crv = sftk_handleObject(privateKey, session);
    if (crv != CKR_OK) {
        sftk_FreeSession(session);
        sftk_FreeObject(privateKey);
        sftk_FreeObject(publicKey);
        return crv;
    }

    /*
     * handle the base object cleanup for the private Key
     * If we have any problems, we destroy the public Key we've
     * created and linked.
     */
    crv = sftk_handleObject(publicKey, session);
    sftk_FreeSession(session);
    if (crv != CKR_OK) {
        sftk_FreeObject(publicKey);
        NSC_DestroyObject(hSession, privateKey->handle);
        sftk_FreeObject(privateKey);
        return crv;
    }
    if (sftk_isTrue(privateKey, CKA_SENSITIVE)) {
        crv = sftk_forceAttribute(privateKey, CKA_ALWAYS_SENSITIVE,
                                  &cktrue, sizeof(CK_BBOOL));
    }
    if (crv == CKR_OK && sftk_isTrue(publicKey, CKA_SENSITIVE)) {
        crv = sftk_forceAttribute(publicKey, CKA_ALWAYS_SENSITIVE,
                                  &cktrue, sizeof(CK_BBOOL));
    }
    if (crv == CKR_OK && !sftk_isTrue(privateKey, CKA_EXTRACTABLE)) {
        crv = sftk_forceAttribute(privateKey, CKA_NEVER_EXTRACTABLE,
                                  &cktrue, sizeof(CK_BBOOL));
    }
    if (crv == CKR_OK && !sftk_isTrue(publicKey, CKA_EXTRACTABLE)) {
        crv = sftk_forceAttribute(publicKey, CKA_NEVER_EXTRACTABLE,
                                  &cktrue, sizeof(CK_BBOOL));
    }

    if (crv == CKR_OK) {
        /* Perform FIPS 140-2 pairwise consistency check. */
        crv = sftk_PairwiseConsistencyCheck(hSession,
                                            publicKey, privateKey, key_type);
        if (crv != CKR_OK) {
            if (sftk_audit_enabled) {
                char msg[128];
                PR_snprintf(msg, sizeof msg,
                            "C_GenerateKeyPair(hSession=0x%08lX, "
                            "pMechanism->mechanism=0x%08lX)=0x%08lX "
                            "self-test: pair-wise consistency test failed",
                            (PRUint32)hSession, (PRUint32)pMechanism->mechanism,
                            (PRUint32)crv);
                sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
            }
        }
    }

    if (crv != CKR_OK) {
        NSC_DestroyObject(hSession, publicKey->handle);
        sftk_FreeObject(publicKey);
        NSC_DestroyObject(hSession, privateKey->handle);
        sftk_FreeObject(privateKey);
        return crv;
    }

    *phPrivateKey = privateKey->handle;
    *phPublicKey = publicKey->handle;
    sftk_FreeObject(publicKey);
    sftk_FreeObject(privateKey);

    return CKR_OK;
}

static SECItem *
sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
{
    NSSLOWKEYPrivateKey *lk = NULL;
    NSSLOWKEYPrivateKeyInfo *pki = NULL;
    SFTKAttribute *attribute = NULL;
    PLArenaPool *arena = NULL;
    SECOidTag algorithm = SEC_OID_UNKNOWN;
    void *dummy, *param = NULL;
    SECStatus rv = SECSuccess;
    SECItem *encodedKey = NULL;
#ifdef EC_DEBUG
    SECItem *fordebug;
#endif
    int savelen;

    if (!key) {
        *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */
        return NULL;
    }

    attribute = sftk_FindAttribute(key, CKA_KEY_TYPE);
    if (!attribute) {
        *crvp = CKR_KEY_TYPE_INCONSISTENT;
        return NULL;
    }

    lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp);
    sftk_FreeAttribute(attribute);
    if (!lk) {
        return NULL;
    }

    arena = PORT_NewArena(2048); /* XXX different size? */
    if (!arena) {
        *crvp = CKR_HOST_MEMORY;
        rv = SECFailure;
        goto loser;
    }

    pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(arena,
                                                      sizeof(NSSLOWKEYPrivateKeyInfo));
    if (!pki) {
        *crvp = CKR_HOST_MEMORY;
        rv = SECFailure;
        goto loser;
    }
    pki->arena = arena;

    param = NULL;
    switch (lk->keyType) {
        case NSSLOWKEYRSAKey:
            prepare_low_rsa_priv_key_for_asn1(lk);
            dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
                                       nsslowkey_RSAPrivateKeyTemplate);

            /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */
            attribute = sftk_FindAttribute(key, CKA_PUBLIC_KEY_INFO);
            if (attribute) {
                NSSLOWKEYSubjectPublicKeyInfo *publicKeyInfo;
                SECItem spki;

                spki.data = attribute->attrib.pValue;
                spki.len = attribute->attrib.ulValueLen;

                publicKeyInfo = PORT_ArenaZAlloc(arena,
                                                 sizeof(NSSLOWKEYSubjectPublicKeyInfo));
                if (!publicKeyInfo) {
                    sftk_FreeAttribute(attribute);
                    *crvp = CKR_HOST_MEMORY;
                    rv = SECFailure;
                    goto loser;
                }
                rv = SEC_QuickDERDecodeItem(arena, publicKeyInfo,
                                            nsslowkey_SubjectPublicKeyInfoTemplate,
                                            &spki);
                if (rv != SECSuccess) {
                    sftk_FreeAttribute(attribute);
                    *crvp = CKR_KEY_TYPE_INCONSISTENT;
                    goto loser;
                }
                algorithm = SECOID_GetAlgorithmTag(&publicKeyInfo->algorithm);
                if (algorithm != SEC_OID_PKCS1_RSA_ENCRYPTION &&
                    algorithm != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
                    sftk_FreeAttribute(attribute);
                    rv = SECFailure;
                    *crvp = CKR_KEY_TYPE_INCONSISTENT;
                    goto loser;
                }
                param = SECITEM_DupItem(&publicKeyInfo->algorithm.parameters);
                if (!param) {
                    sftk_FreeAttribute(attribute);
                    rv = SECFailure;
                    *crvp = CKR_HOST_MEMORY;
                    goto loser;
                }
                sftk_FreeAttribute(attribute);
            } else {
                /* default to PKCS #1 */
                algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
            }
            break;
        case NSSLOWKEYDSAKey:
            prepare_low_dsa_priv_key_export_for_asn1(lk);
            dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
                                       nsslowkey_DSAPrivateKeyExportTemplate);
            prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);
            param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
                                       nsslowkey_PQGParamsTemplate);
            algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
            break;
        case NSSLOWKEYECKey:
            prepare_low_ec_priv_key_for_asn1(lk);
            /* Public value is encoded as a bit string so adjust length
             * to be in bits before ASN encoding and readjust
             * immediately after.
             *
             * Since the SECG specification recommends not including the
             * parameters as part of ECPrivateKey, we zero out the curveOID
             * length before encoding and restore it later.
             */
            lk->u.ec.publicValue.len <<= 3;
            savelen = lk->u.ec.ecParams.curveOID.len;
            lk->u.ec.ecParams.curveOID.len = 0;
            dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
                                       nsslowkey_ECPrivateKeyTemplate);
            lk->u.ec.ecParams.curveOID.len = savelen;
            lk->u.ec.publicValue.len >>= 3;

#ifdef EC_DEBUG
            fordebug = &pki->privateKey;
            SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
                      fordebug);
#endif

            param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);

            algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
            break;
        case NSSLOWKEYDHKey:
        default:
            dummy = NULL;
            break;
    }

    if (!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {
        *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
        rv = SECFailure;
        goto loser;
    }

    rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm,
                               (SECItem *)param);
    if (rv != SECSuccess) {
        *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
        rv = SECFailure;
        goto loser;
    }

    dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
                                  NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
    if (!dummy) {
        *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
        rv = SECFailure;
        goto loser;
    }

    encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
                                    nsslowkey_PrivateKeyInfoTemplate);
    *crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR;

#ifdef EC_DEBUG
    fordebug = encodedKey;
    SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,
              fordebug);
#endif
loser:
    if (arena) {
        PORT_FreeArena(arena, PR_TRUE);
    }

    if (lk && (lk != key->objectInfo)) {
        nsslowkey_DestroyPrivateKey(lk);
    }

    if (param) {
        SECITEM_ZfreeItem((SECItem *)param, PR_TRUE);
    }

    if (rv != SECSuccess) {
        return NULL;
    }

    return encodedKey;
}

/* it doesn't matter yet, since we colapse error conditions in the
 * level above, but we really should map those few key error differences */
static CK_RV
sftk_mapWrap(CK_RV crv)
{
    switch (crv) {
        case CKR_ENCRYPTED_DATA_INVALID:
            crv = CKR_WRAPPED_KEY_INVALID;
            break;
    }
    return crv;
}

/* NSC_WrapKey wraps (i.e., encrypts) a key. */
CK_RV
NSC_WrapKey(CK_SESSION_HANDLE hSession,
            CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
            CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
            CK_ULONG_PTR pulWrappedKeyLen)
{
    SFTKSession *session;
    SFTKAttribute *attribute;
    SFTKObject *key;
    CK_RV crv;

    CHECK_FORK();

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
        return CKR_SESSION_HANDLE_INVALID;
    }

    key = sftk_ObjectFromHandle(hKey, session);
    sftk_FreeSession(session);
    if (key == NULL) {
        return CKR_KEY_HANDLE_INVALID;
    }

    switch (key->objclass) {
        case CKO_SECRET_KEY: {
            SFTKSessionContext *context = NULL;
            SECItem pText;

            attribute = sftk_FindAttribute(key, CKA_VALUE);

            if (attribute == NULL) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
                                 CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
            if (crv != CKR_OK) {
                sftk_FreeAttribute(attribute);
                break;
            }

            pText.type = siBuffer;
            pText.data = (unsigned char *)attribute->attrib.pValue;
            pText.len = attribute->attrib.ulValueLen;

            /* Find out if this is a block cipher. */
            crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_FALSE, NULL);
            if (crv != CKR_OK || !context)
                break;
            if (context->blockSize > 1) {
                unsigned int remainder = pText.len % context->blockSize;
                if (!context->doPad && remainder) {
                    /* When wrapping secret keys with unpadded block ciphers,
                    ** the keys are zero padded, if necessary, to fill out
                    ** a full block.
                    */
                    pText.len += context->blockSize - remainder;
                    pText.data = PORT_ZAlloc(pText.len);
                    if (pText.data)
                        memcpy(pText.data, attribute->attrib.pValue,
                               attribute->attrib.ulValueLen);
                    else {
                        crv = CKR_HOST_MEMORY;
                        break;
                    }
                }
            }

            crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data,
                              pText.len, pWrappedKey, pulWrappedKeyLen);
            /* always force a finalize, both on errors and when
             * we are just getting the size */
            if (crv != CKR_OK || pWrappedKey == NULL) {
                CK_RV lcrv;
                lcrv = sftk_GetContext(hSession, &context,
                                       SFTK_ENCRYPT, PR_FALSE, NULL);
                sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
                if (lcrv == CKR_OK && context) {
                    sftk_FreeContext(context);
                }
            }

            if (pText.data != (unsigned char *)attribute->attrib.pValue)
                PORT_ZFree(pText.data, pText.len);
            sftk_FreeAttribute(attribute);
            break;
        }

        case CKO_PRIVATE_KEY: {
            SECItem *bpki = sftk_PackagePrivateKey(key, &crv);
            SFTKSessionContext *context = NULL;

            if (!bpki) {
                break;
            }

            crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
                                 CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
            if (crv != CKR_OK) {
                SECITEM_ZfreeItem(bpki, PR_TRUE);
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }

            crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
                              pWrappedKey, pulWrappedKeyLen);
            /* always force a finalize */
            if (crv != CKR_OK || pWrappedKey == NULL) {
                CK_RV lcrv;
                lcrv = sftk_GetContext(hSession, &context,
                                       SFTK_ENCRYPT, PR_FALSE, NULL);
                sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
                if (lcrv == CKR_OK && context) {
                    sftk_FreeContext(context);
                }
            }
            SECITEM_ZfreeItem(bpki, PR_TRUE);
            break;
        }

        default:
            crv = CKR_KEY_TYPE_INCONSISTENT;
            break;
    }
    sftk_FreeObject(key);

    return sftk_mapWrap(crv);
}

/*
 * import a pprivate key info into the desired slot
 */
static SECStatus
sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
{
    CK_BBOOL cktrue = CK_TRUE;
    CK_KEY_TYPE keyType = CKK_RSA;
    SECStatus rv = SECFailure;
    const SEC_ASN1Template *keyTemplate, *paramTemplate;
    void *paramDest = NULL;
    PLArenaPool *arena;
    NSSLOWKEYPrivateKey *lpk = NULL;
    NSSLOWKEYPrivateKeyInfo *pki = NULL;
    CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;

    arena = PORT_NewArena(2048);
    if (!arena) {
        return SECFailure;
    }

    pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(arena,
                                                      sizeof(NSSLOWKEYPrivateKeyInfo));
    if (!pki) {
        PORT_FreeArena(arena, PR_FALSE);
        return SECFailure;
    }

    if (SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) != SECSuccess) {
        PORT_FreeArena(arena, PR_TRUE);
        return SECFailure;
    }

    lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena,
                                                  sizeof(NSSLOWKEYPrivateKey));
    if (lpk == NULL) {
        goto loser;
    }
    lpk->arena = arena;

    switch (SECOID_GetAlgorithmTag(&pki->algorithm)) {
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
            keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
            paramTemplate = NULL;
            paramDest = NULL;
            lpk->keyType = NSSLOWKEYRSAKey;
            prepare_low_rsa_priv_key_for_asn1(lpk);
            break;
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
            keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
            paramTemplate = nsslowkey_PQGParamsTemplate;
            paramDest = &(lpk->u.dsa.params);
            lpk->keyType = NSSLOWKEYDSAKey;
            prepare_low_dsa_priv_key_export_for_asn1(lpk);
            prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params);
            break;
        /* case NSSLOWKEYDHKey: */
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
            keyTemplate = nsslowkey_ECPrivateKeyTemplate;
            paramTemplate = NULL;
            paramDest = &(lpk->u.ec.ecParams.DEREncoding);
            lpk->keyType = NSSLOWKEYECKey;
            prepare_low_ec_priv_key_for_asn1(lpk);
            prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams);
            break;
        default:
            keyTemplate = NULL;
            paramTemplate = NULL;
            paramDest = NULL;
            break;
    }

    if (!keyTemplate) {
        goto loser;
    }

    /* decode the private key and any algorithm parameters */
    rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);

    if (lpk->keyType == NSSLOWKEYECKey) {
        /* convert length in bits to length in bytes */
        lpk->u.ec.publicValue.len >>= 3;
        rv = SECITEM_CopyItem(arena,
                              &(lpk->u.ec.ecParams.DEREncoding),
                              &(pki->algorithm.parameters));
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    if (rv != SECSuccess) {
        goto loser;
    }
    if (paramDest && paramTemplate) {
        rv = SEC_QuickDERDecodeItem(arena, paramDest, paramTemplate,
                                    &(pki->algorithm.parameters));
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    rv = SECFailure;

    switch (lpk->keyType) {
        case NSSLOWKEYRSAKey:
            keyType = CKK_RSA;
            if (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) {
                sftk_DeleteAttributeType(key, CKA_NETSCAPE_DB);
            }
            crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
                                        sizeof(keyType));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_UNWRAP, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_DECRYPT, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_MODULUS,
                                        sftk_item_expand(&lpk->u.rsa.modulus));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT,
                                        sftk_item_expand(&lpk->u.rsa.publicExponent));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT,
                                        sftk_item_expand(&lpk->u.rsa.privateExponent));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_PRIME_1,
                                        sftk_item_expand(&lpk->u.rsa.prime1));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_PRIME_2,
                                        sftk_item_expand(&lpk->u.rsa.prime2));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_EXPONENT_1,
                                        sftk_item_expand(&lpk->u.rsa.exponent1));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_EXPONENT_2,
                                        sftk_item_expand(&lpk->u.rsa.exponent2));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_COEFFICIENT,
                                        sftk_item_expand(&lpk->u.rsa.coefficient));
            break;
        case NSSLOWKEYDSAKey:
            keyType = CKK_DSA;
            crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK : CKR_KEY_TYPE_INCONSISTENT;
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
                                        sizeof(keyType));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_PRIME,
                                        sftk_item_expand(&lpk->u.dsa.params.prime));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_SUBPRIME,
                                        sftk_item_expand(&lpk->u.dsa.params.subPrime));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_BASE,
                                        sftk_item_expand(&lpk->u.dsa.params.base));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_VALUE,
                                        sftk_item_expand(&lpk->u.dsa.privateValue));
            if (crv != CKR_OK)
                break;
            break;
#ifdef notdef
        case NSSLOWKEYDHKey:
            template = dhTemplate;
            templateCount = sizeof(dhTemplate) / sizeof(CK_ATTRIBUTE);
            keyType = CKK_DH;
            break;
#endif
        /* what about fortezza??? */
        case NSSLOWKEYECKey:
            keyType = CKK_EC;
            crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK : CKR_KEY_TYPE_INCONSISTENT;
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
                                        sizeof(keyType));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_DERIVE, &cktrue,
                                        sizeof(CK_BBOOL));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_EC_PARAMS,
                                        sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding));
            if (crv != CKR_OK)
                break;
            crv = sftk_AddAttributeType(key, CKA_VALUE,
                                        sftk_item_expand(&lpk->u.ec.privateValue));
            if (crv != CKR_OK)
                break;
            /* XXX Do we need to decode the EC Params here ?? */
            break;
        default:
            crv = CKR_KEY_TYPE_INCONSISTENT;
            break;
    }

    if (crv != CKR_OK) {
        goto loser;
    }

    /* For RSA-PSS, record the original algorithm parameters so
     * they can be encrypted altoghether when wrapping */
    if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
        NSSLOWKEYSubjectPublicKeyInfo spki;
        NSSLOWKEYPublicKey pubk;
        SECItem *publicKeyInfo;

        memset(&spki, 0, sizeof(NSSLOWKEYSubjectPublicKeyInfo));
        rv = SECOID_CopyAlgorithmID(arena, &spki.algorithm, &pki->algorithm);
        if (rv != SECSuccess) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }

        prepare_low_rsa_pub_key_for_asn1(&pubk);

        rv = SECITEM_CopyItem(arena, &pubk.u.rsa.modulus, &lpk->u.rsa.modulus);
        if (rv != SECSuccess) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        rv = SECITEM_CopyItem(arena, &pubk.u.rsa.publicExponent, &lpk->u.rsa.publicExponent);
        if (rv != SECSuccess) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }

        if (SEC_ASN1EncodeItem(arena, &spki.subjectPublicKey,
                               &pubk, nsslowkey_RSAPublicKeyTemplate) == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }

        publicKeyInfo = SEC_ASN1EncodeItem(arena, NULL,
                                           &spki, nsslowkey_SubjectPublicKeyInfoTemplate);
        if (!publicKeyInfo) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        crv = sftk_AddAttributeType(key, CKA_PUBLIC_KEY_INFO,
                                    sftk_item_expand(publicKeyInfo));
    }

loser:
    if (lpk) {
        nsslowkey_DestroyPrivateKey(lpk);
    }

    if (crv != CKR_OK) {
        return SECFailure;
    }

    return SECSuccess;
}

/* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
CK_RV
NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
              CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
              CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
              CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
              CK_OBJECT_HANDLE_PTR phKey)
{
    SFTKObject *key = NULL;
    SFTKSession *session;
    CK_ULONG key_length = 0;
    unsigned char *buf = NULL;
    CK_RV crv = CKR_OK;
    int i;
    CK_ULONG bsize = ulWrappedKeyLen;
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    SECItem bpki;
    CK_OBJECT_CLASS target_type = CKO_SECRET_KEY;

    CHECK_FORK();

    if (!slot) {
        return CKR_SESSION_HANDLE_INVALID;
    }
    /*
     * now lets create an object to hang the attributes off of
     */
    key = sftk_NewObject(slot); /* fill in the handle later */
    if (key == NULL) {
        return CKR_HOST_MEMORY;
    }

    /*
     * load the template values into the object
     */
    for (i = 0; i < (int)ulAttributeCount; i++) {
        if (pTemplate[i].type == CKA_VALUE_LEN) {
            key_length = *(CK_ULONG *)pTemplate[i].pValue;
            continue;
        }
        if (pTemplate[i].type == CKA_CLASS) {
            target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
        }
        crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i]));
        if (crv != CKR_OK)
            break;
    }
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }

    crv = sftk_CryptInit(hSession, pMechanism, hUnwrappingKey, CKA_UNWRAP,
                         CKA_UNWRAP, SFTK_DECRYPT, PR_FALSE);
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return sftk_mapWrap(crv);
    }

    /* allocate the buffer to decrypt into
     * this assumes the unwrapped key is never larger than the
     * wrapped key. For all the mechanisms we support this is true */
    buf = (unsigned char *)PORT_Alloc(ulWrappedKeyLen);
    bsize = ulWrappedKeyLen;

    crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize);
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        PORT_Free(buf);
        return sftk_mapWrap(crv);
    }

    switch (target_type) {
        case CKO_SECRET_KEY:
            if (!sftk_hasAttribute(key, CKA_KEY_TYPE)) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                break;
            }

            if (key_length == 0 || key_length > bsize) {
                key_length = bsize;
            }
            if (key_length > MAX_KEY_LEN) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }

            /* add the value */
            crv = sftk_AddAttributeType(key, CKA_VALUE, buf, key_length);
            break;
        case CKO_PRIVATE_KEY:
            bpki.data = (unsigned char *)buf;
            bpki.len = bsize;
            crv = CKR_OK;
            if (sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) {
                crv = CKR_TEMPLATE_INCOMPLETE;
            }
            break;
        default:
            crv = CKR_TEMPLATE_INCONSISTENT;
            break;
    }

    PORT_ZFree(buf, bsize);
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }

    /* get the session */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
        sftk_FreeObject(key);
        return CKR_SESSION_HANDLE_INVALID;
    }

    /*
     * handle the base object stuff
     */
    crv = sftk_handleObject(key, session);
    *phKey = key->handle;
    sftk_FreeSession(session);
    sftk_FreeObject(key);

    return crv;
}

/*
 * The SSL key gen mechanism create's lots of keys. This function handles the
 * details of each of these key creation.
 */
static CK_RV
sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey,
                 PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize,
                 CK_OBJECT_HANDLE *keyHandle)
{
    SFTKObject *key;
    SFTKSession *session;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_BBOOL cktrue = CK_TRUE;
    CK_BBOOL ckfalse = CK_FALSE;
    CK_RV crv = CKR_HOST_MEMORY;

    /*
     * now lets create an object to hang the attributes off of
     */
    *keyHandle = CK_INVALID_HANDLE;
    key = sftk_NewObject(baseKey->slot);
    if (key == NULL)
        return CKR_HOST_MEMORY;
    sftk_narrowToSessionObject(key)->wasDerived = PR_TRUE;

    crv = sftk_CopyObject(key, baseKey);
    if (crv != CKR_OK)
        goto loser;
    if (isMacKey) {
        crv = sftk_forceAttribute(key, CKA_KEY_TYPE, &keyType, sizeof(keyType));
        if (crv != CKR_OK)
            goto loser;
        crv = sftk_forceAttribute(key, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
        if (crv != CKR_OK)
            goto loser;
        crv = sftk_forceAttribute(key, CKA_ENCRYPT, &ckfalse, sizeof(CK_BBOOL));
        if (crv != CKR_OK)
            goto loser;
        crv = sftk_forceAttribute(key, CKA_DECRYPT, &ckfalse, sizeof(CK_BBOOL));
        if (crv != CKR_OK)
            goto loser;
        crv = sftk_forceAttribute(key, CKA_SIGN, &cktrue, sizeof(CK_BBOOL));
        if (crv != CKR_OK)
            goto loser;
        crv = sftk_forceAttribute(key, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));
        if (crv != CKR_OK)
            goto loser;
        crv = sftk_forceAttribute(key, CKA_WRAP, &ckfalse, sizeof(CK_BBOOL));
        if (crv != CKR_OK)
            goto loser;
        crv = sftk_forceAttribute(key, CKA_UNWRAP, &ckfalse, sizeof(CK_BBOOL));
        if (crv != CKR_OK)
            goto loser;
    }
    crv = sftk_forceAttribute(key, CKA_VALUE, keyBlock, keySize);
    if (crv != CKR_OK)
        goto loser;

    /* get the session */
    crv = CKR_HOST_MEMORY;
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
        goto loser;
    }

    crv = sftk_handleObject(key, session);
    sftk_FreeSession(session);
    *keyHandle = key->handle;
loser:
    if (key)
        sftk_FreeObject(key);
    return crv;
}

/*
 * if there is an error, we need to free the keys we already created in SSL
 * This is the routine that will do it..
 */
static void
sftk_freeSSLKeys(CK_SESSION_HANDLE session,
                 CK_SSL3_KEY_MAT_OUT *returnedMaterial)
{
    if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) {
        NSC_DestroyObject(session, returnedMaterial->hClientMacSecret);
    }
    if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) {
        NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
    }
    if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) {
        NSC_DestroyObject(session, returnedMaterial->hClientKey);
    }
    if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) {
        NSC_DestroyObject(session, returnedMaterial->hServerKey);
    }
}

/*
 * when deriving from sensitive and extractable keys, we need to preserve some
 * of the semantics in the derived key. This helper routine maintains these
 * semantics.
 */
static CK_RV
sftk_DeriveSensitiveCheck(SFTKObject *baseKey, SFTKObject *destKey)
{
    PRBool hasSensitive;
    PRBool sensitive = PR_FALSE;
    PRBool hasExtractable;
    PRBool extractable = PR_TRUE;
    CK_RV crv = CKR_OK;
    SFTKAttribute *att;

    hasSensitive = PR_FALSE;
    att = sftk_FindAttribute(destKey, CKA_SENSITIVE);
    if (att) {
        hasSensitive = PR_TRUE;
        sensitive = (PRBool) * (CK_BBOOL *)att->attrib.pValue;
        sftk_FreeAttribute(att);
    }

    hasExtractable = PR_FALSE;
    att = sftk_FindAttribute(destKey, CKA_EXTRACTABLE);
    if (att) {
        hasExtractable = PR_TRUE;
        extractable = (PRBool) * (CK_BBOOL *)att->attrib.pValue;
        sftk_FreeAttribute(att);
    }

    /* don't make a key more accessible */
    if (sftk_isTrue(baseKey, CKA_SENSITIVE) && hasSensitive &&
        (sensitive == PR_FALSE)) {
        return CKR_KEY_FUNCTION_NOT_PERMITTED;
    }
    if (!sftk_isTrue(baseKey, CKA_EXTRACTABLE) && hasExtractable &&
        (extractable == PR_TRUE)) {
        return CKR_KEY_FUNCTION_NOT_PERMITTED;
    }

    /* inherit parent's sensitivity */
    if (!hasSensitive) {
        att = sftk_FindAttribute(baseKey, CKA_SENSITIVE);
        if (att == NULL)
            return CKR_KEY_TYPE_INCONSISTENT;
        crv = sftk_defaultAttribute(destKey, sftk_attr_expand(&att->attrib));
        sftk_FreeAttribute(att);
        if (crv != CKR_OK)
            return crv;
    }
    if (!hasExtractable) {
        att = sftk_FindAttribute(baseKey, CKA_EXTRACTABLE);
        if (att == NULL)
            return CKR_KEY_TYPE_INCONSISTENT;
        crv = sftk_defaultAttribute(destKey, sftk_attr_expand(&att->attrib));
        sftk_FreeAttribute(att);
        if (crv != CKR_OK)
            return crv;
    }

    /* we should inherit the parent's always extractable/ never sensitive info,
     * but handleObject always forces this attributes, so we would need to do
     * something special. */
    return CKR_OK;
}

/*
 * make known fixed PKCS #11 key types to their sizes in bytes
 */
unsigned long
sftk_MapKeySize(CK_KEY_TYPE keyType)
{
    switch (keyType) {
        case CKK_CDMF:
            return 8;
        case CKK_DES:
            return 8;
        case CKK_DES2:
            return 16;
        case CKK_DES3:
            return 24;
        /* IDEA and CAST need to be added */
        default:
            break;
    }
    return 0;
}

/* Inputs:
 *  key_len: Length of derived key to be generated.
 *  SharedSecret: a shared secret that is the output of a key agreement primitive.
 *  SharedInfo: (Optional) some data shared by the entities computing the secret key.
 *  SharedInfoLen: the length in octets of SharedInfo
 *  Hash: The hash function to be used in the KDF
 *  HashLen: the length in octets of the output of Hash
 * Output:
 *  key: Pointer to a buffer containing derived key, if return value is SECSuccess.
 */
static CK_RV
sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECItem *SharedSecret,
                            CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
                            SECStatus Hash(unsigned char *, const unsigned char *, PRUint32),
                            CK_ULONG HashLen)
{
    unsigned char *buffer = NULL, *output_buffer = NULL;
    PRUint32 buffer_len, max_counter, i;
    SECStatus rv;
    CK_RV crv;

    /* Check that key_len isn't too long.  The maximum key length could be
     * greatly increased if the code below did not limit the 4-byte counter
     * to a maximum value of 255. */
    if (key_len > 254 * HashLen)
        return CKR_ARGUMENTS_BAD;

    if (SharedInfo == NULL)
        SharedInfoLen = 0;

    buffer_len = SharedSecret->len + 4 + SharedInfoLen;
    buffer = (CK_BYTE *)PORT_Alloc(buffer_len);
    if (buffer == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    max_counter = key_len / HashLen;
    if (key_len > max_counter * HashLen)
        max_counter++;

    output_buffer = (CK_BYTE *)PORT_Alloc(max_counter * HashLen);
    if (output_buffer == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    /* Populate buffer with SharedSecret || Counter || [SharedInfo]
     * where Counter is 0x00000001 */
    PORT_Memcpy(buffer, SharedSecret->data, SharedSecret->len);
    buffer[SharedSecret->len] = 0;
    buffer[SharedSecret->len + 1] = 0;
    buffer[SharedSecret->len + 2] = 0;
    buffer[SharedSecret->len + 3] = 1;
    if (SharedInfo) {
        PORT_Memcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen);
    }

    for (i = 0; i < max_counter; i++) {
        rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len);
        if (rv != SECSuccess) {
            /* 'Hash' should not fail. */
            crv = CKR_FUNCTION_FAILED;
            goto loser;
        }

        /* Increment counter (assumes max_counter < 255) */
        buffer[SharedSecret->len + 3]++;
    }

    PORT_ZFree(buffer, buffer_len);
    if (key_len < max_counter * HashLen) {
        PORT_Memset(output_buffer + key_len, 0, max_counter * HashLen - key_len);
    }
    *key = output_buffer;

    return CKR_OK;

loser:
    if (buffer) {
        PORT_ZFree(buffer, buffer_len);
    }
    if (output_buffer) {
        PORT_ZFree(output_buffer, max_counter * HashLen);
    }
    return crv;
}

static CK_RV
sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len,
                    SECItem *SharedSecret,
                    CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
                    CK_EC_KDF_TYPE kdf)
{
    if (kdf == CKD_SHA1_KDF)
        return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
                                           SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH);
    else if (kdf == CKD_SHA224_KDF)
        return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
                                           SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH);
    else if (kdf == CKD_SHA256_KDF)
        return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
                                           SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH);
    else if (kdf == CKD_SHA384_KDF)
        return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
                                           SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH);
    else if (kdf == CKD_SHA512_KDF)
        return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
                                           SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH);
    else
        return CKR_MECHANISM_INVALID;
}

/*
 *  Handle the derive from a block encryption cipher
 */
CK_RV
sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo,
                   int blockSize, SFTKObject *key, CK_ULONG keySize,
                   unsigned char *data, CK_ULONG len)
{
    /* large enough for a 512-bit key */
    unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE];
    SECStatus rv;
    unsigned int outLen;
    CK_RV crv;

    if ((len % blockSize) != 0) {
        return CKR_MECHANISM_PARAM_INVALID;
    }
    if (len > SFTK_MAX_DERIVE_KEY_SIZE) {
        return CKR_MECHANISM_PARAM_INVALID;
    }
    if (keySize && (len < keySize)) {
        return CKR_MECHANISM_PARAM_INVALID;
    }
    if (keySize == 0) {
        keySize = len;
    }

    rv = (*encrypt)(cipherInfo, &tmpdata, &outLen, len, data, len);
    if (rv != SECSuccess) {
        crv = sftk_MapCryptError(PORT_GetError());
        return crv;
    }

    crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize);
    return crv;
}

/*
 * SSL Key generation given pre master secret
 */
#define NUM_MIXERS 9
static const char *const mixers[NUM_MIXERS] = {
    "A",
    "BB",
    "CCC",
    "DDDD",
    "EEEEE",
    "FFFFFF",
    "GGGGGGG",
    "HHHHHHHH",
    "IIIIIIIII"
};
#define SSL3_PMS_LENGTH 48
#define SSL3_MASTER_SECRET_LENGTH 48
#define SSL3_RANDOM_LENGTH 32

/* NSC_DeriveKey derives a key from a base key, creating a new key object. */
CK_RV
NSC_DeriveKey(CK_SESSION_HANDLE hSession,
              CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
              CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
              CK_OBJECT_HANDLE_PTR phKey)
{
    SFTKSession *session;
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    SFTKObject *key;
    SFTKObject *sourceKey;
    SFTKAttribute *att = NULL;
    SFTKAttribute *att2 = NULL;
    unsigned char *buf;
    SHA1Context *sha;
    MD5Context *md5;
    MD2Context *md2;
    CK_ULONG macSize;
    CK_ULONG tmpKeySize;
    CK_ULONG IVSize;
    CK_ULONG keySize = 0;
    CK_RV crv = CKR_OK;
    CK_BBOOL cktrue = CK_TRUE;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
    CK_KEY_DERIVATION_STRING_DATA *stringPtr;
    CK_MECHANISM_TYPE mechanism = pMechanism->mechanism;
    PRBool isTLS = PR_FALSE;
    PRBool isDH = PR_FALSE;
    HASH_HashType tlsPrfHash = HASH_AlgNULL;
    SECStatus rv;
    int i;
    unsigned int outLen;
    unsigned char sha_out[SHA1_LENGTH];
    unsigned char key_block[NUM_MIXERS * SFTK_MAX_MAC_LENGTH];
    PRBool isFIPS;
    HASH_HashType hashType;
    PRBool extractValue = PR_TRUE;

    CHECK_FORK();

    if (!slot) {
        return CKR_SESSION_HANDLE_INVALID;
    }
    /*
     * now lets create an object to hang the attributes off of
     */
    if (phKey)
        *phKey = CK_INVALID_HANDLE;

    key = sftk_NewObject(slot); /* fill in the handle later */
    if (key == NULL) {
        return CKR_HOST_MEMORY;
    }
    isFIPS = (slot->slotID == FIPS_SLOT_ID);

    /*
     * load the template values into the object
     */
    for (i = 0; i < (int)ulAttributeCount; i++) {
        crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i]));
        if (crv != CKR_OK)
            break;

        if (pTemplate[i].type == CKA_KEY_TYPE) {
            keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue;
        }
        if (pTemplate[i].type == CKA_VALUE_LEN) {
            keySize = *(CK_ULONG *)pTemplate[i].pValue;
        }
    }
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }

    if (keySize == 0) {
        keySize = sftk_MapKeySize(keyType);
    }

    switch (mechanism) {
        case CKM_NSS_JPAKE_ROUND2_SHA1:   /* fall through */
        case CKM_NSS_JPAKE_ROUND2_SHA256: /* fall through */
        case CKM_NSS_JPAKE_ROUND2_SHA384: /* fall through */
        case CKM_NSS_JPAKE_ROUND2_SHA512:
            extractValue = PR_FALSE;
            classType = CKO_PRIVATE_KEY;
            break;
        case CKM_NSS_JPAKE_FINAL_SHA1:   /* fall through */
        case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */
        case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */
        case CKM_NSS_JPAKE_FINAL_SHA512:
            extractValue = PR_FALSE;
        /* fall through */
        default:
            classType = CKO_SECRET_KEY;
    }

    crv = sftk_forceAttribute(key, CKA_CLASS, &classType, sizeof(classType));
    if (crv != CKR_OK) {
        sftk_FreeObject(key);
        return crv;
    }

    /* look up the base key we're deriving with */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
        sftk_FreeObject(key);
        return CKR_SESSION_HANDLE_INVALID;
    }

    sourceKey = sftk_ObjectFromHandle(hBaseKey, session);
    sftk_FreeSession(session);
    if (sourceKey == NULL) {
        sftk_FreeObject(key);
        return CKR_KEY_HANDLE_INVALID;
    }

    if (extractValue) {
        /* get the value of the base key */
        att = sftk_FindAttribute(sourceKey, CKA_VALUE);
        if (att == NULL) {
            sftk_FreeObject(key);
            sftk_FreeObject(sourceKey);
            return CKR_KEY_HANDLE_INVALID;
        }
    }

    switch (mechanism) {
        /*
         * generate the master secret
         */
        case CKM_TLS12_MASTER_KEY_DERIVE:
        case CKM_TLS12_MASTER_KEY_DERIVE_DH:
        case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256:
        case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
        case CKM_TLS_MASTER_KEY_DERIVE:
        case CKM_TLS_MASTER_KEY_DERIVE_DH:
        case CKM_SSL3_MASTER_KEY_DERIVE:
        case CKM_SSL3_MASTER_KEY_DERIVE_DH: {
            CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
            SSL3RSAPreMasterSecret *rsa_pms;
            unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];

            if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) ||
                (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
                CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
                    (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter;
                tlsPrfHash = GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
                if (tlsPrfHash == HASH_AlgNULL) {
                    crv = CKR_MECHANISM_PARAM_INVALID;
                    break;
                }
            } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256) ||
                       (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) {
                tlsPrfHash = HASH_AlgSHA256;
            }

            if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE) &&
                (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH)) {
                isTLS = PR_TRUE;
            }
            if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) ||
                (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH) ||
                (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256) ||
                (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
                isDH = PR_TRUE;
            }

            /* first do the consistency checks */
            if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE);
            if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
                                   CKK_GENERIC_SECRET)) {
                if (att2)
                    sftk_FreeAttribute(att2);
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }
            sftk_FreeAttribute(att2);
            if (keyType != CKK_GENERIC_SECRET) {
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }
            if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }

            /* finally do the key gen */
            ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
                              pMechanism->pParameter;

            PORT_Memcpy(crsrdata,
                        ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
            PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
                        ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);

            if (ssl3_master->pVersion) {
                SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
                rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue;
                /* don't leak more key material then necessary for SSL to work */
                if ((sessKey == NULL) || sessKey->wasDerived) {
                    ssl3_master->pVersion->major = 0xff;
                    ssl3_master->pVersion->minor = 0xff;
                } else {
                    ssl3_master->pVersion->major = rsa_pms->client_version[0];
                    ssl3_master->pVersion->minor = rsa_pms->client_version[1];
                }
            }
            if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }

            if (isTLS) {
                SECStatus status;
                SECItem crsr = { siBuffer, NULL, 0 };
                SECItem master = { siBuffer, NULL, 0 };
                SECItem pms = { siBuffer, NULL, 0 };

                crsr.data = crsrdata;
                crsr.len = sizeof crsrdata;
                master.data = key_block;
                master.len = SSL3_MASTER_SECRET_LENGTH;
                pms.data = (unsigned char *)att->attrib.pValue;
                pms.len = att->attrib.ulValueLen;

                if (tlsPrfHash != HASH_AlgNULL) {
                    status = TLS_P_hash(tlsPrfHash, &pms, "master secret",
                                        &crsr, &master, isFIPS);
                } else {
                    status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
                }
                if (status != SECSuccess) {
                    crv = CKR_FUNCTION_FAILED;
                    break;
                }
            } else {
                /* now allocate the hash contexts */
                md5 = MD5_NewContext();
                if (md5 == NULL) {
                    crv = CKR_HOST_MEMORY;
                    break;
                }
                sha = SHA1_NewContext();
                if (sha == NULL) {
                    PORT_Free(md5);
                    crv = CKR_HOST_MEMORY;
                    break;
                }
                for (i = 0; i < 3; i++) {
                    SHA1_Begin(sha);
                    SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i]));
                    SHA1_Update(sha, (const unsigned char *)att->attrib.pValue,
                                att->attrib.ulValueLen);
                    SHA1_Update(sha, crsrdata, sizeof crsrdata);
                    SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
                    PORT_Assert(outLen == SHA1_LENGTH);

                    MD5_Begin(md5);
                    MD5_Update(md5, (const unsigned char *)att->attrib.pValue,
                               att->attrib.ulValueLen);
                    MD5_Update(md5, sha_out, outLen);
                    MD5_End(md5, &key_block[i * MD5_LENGTH], &outLen, MD5_LENGTH);
                    PORT_Assert(outLen == MD5_LENGTH);
                }
                PORT_Free(md5);
                PORT_Free(sha);
            }

            /* store the results */
            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, SSL3_MASTER_SECRET_LENGTH);
            if (crv != CKR_OK)
                break;
            keyType = CKK_GENERIC_SECRET;
            crv = sftk_forceAttribute(key, CKA_KEY_TYPE, &keyType, sizeof(keyType));
            if (isTLS) {
                /* TLS's master secret is used to "sign" finished msgs with PRF. */
                /* XXX This seems like a hack.   But SFTK_Derive only accepts
                 * one "operation" argument. */
                crv = sftk_forceAttribute(key, CKA_SIGN, &cktrue, sizeof(CK_BBOOL));
                if (crv != CKR_OK)
                    break;
                crv = sftk_forceAttribute(key, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));
                if (crv != CKR_OK)
                    break;
                /* While we're here, we might as well force this, too. */
                crv = sftk_forceAttribute(key, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
                if (crv != CKR_OK)
                    break;
            }
            break;
        }

        /* Extended master key derivation [draft-ietf-tls-session-hash] */
        case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
        case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH: {
            CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params;
            SSL3RSAPreMasterSecret *rsa_pms;
            SECStatus status;
            SECItem pms = { siBuffer, NULL, 0 };
            SECItem seed = { siBuffer, NULL, 0 };
            SECItem master = { siBuffer, NULL, 0 };

            ems_params = (CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *)
                             pMechanism->pParameter;

            /* First do the consistency checks */
            if ((mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE) &&
                (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
                crv = CKR_KEY_TYPE_INCONSISTENT;
                break;
            }
            att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE);
            if ((att2 == NULL) ||
                (*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET)) {
                if (att2)
                    sftk_FreeAttribute(att2);
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }
            sftk_FreeAttribute(att2);
            if (keyType != CKK_GENERIC_SECRET) {
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }
            if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }

            /* Do the key derivation */
            pms.data = (unsigned char *)att->attrib.pValue;
            pms.len = att->attrib.ulValueLen;
            seed.data = ems_params->pSessionHash;
            seed.len = ems_params->ulSessionHashLen;
            master.data = key_block;
            master.len = SSL3_MASTER_SECRET_LENGTH;
            if (ems_params->prfHashMechanism == CKM_TLS_PRF) {
                /*
                 * In this case, the session hash is the concatenation of SHA-1
                 * and MD5, so it should be 36 bytes long.
                 */
                if (seed.len != MD5_LENGTH + SHA1_LENGTH) {
                    crv = CKR_TEMPLATE_INCONSISTENT;
                    break;
                }

                status = TLS_PRF(&pms, "extended master secret",
                                 &seed, &master, isFIPS);
            } else {
                const SECHashObject *hashObj;

                tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism);
                if (tlsPrfHash == HASH_AlgNULL) {
                    crv = CKR_MECHANISM_PARAM_INVALID;
                    break;
                }

                hashObj = HASH_GetRawHashObject(tlsPrfHash);
                if (seed.len != hashObj->length) {
                    crv = CKR_TEMPLATE_INCONSISTENT;
                    break;
                }

                status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret",
                                    &seed, &master, isFIPS);
            }
            if (status != SECSuccess) {
                crv = CKR_FUNCTION_FAILED;
                break;
            }

            /* Reflect the version if required */
            if (ems_params->pVersion) {
                SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
                rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue;
                /* don't leak more key material than necessary for SSL to work */
                if ((sessKey == NULL) || sessKey->wasDerived) {
                    ems_params->pVersion->major = 0xff;
                    ems_params->pVersion->minor = 0xff;
                } else {
                    ems_params->pVersion->major = rsa_pms->client_version[0];
                    ems_params->pVersion->minor = rsa_pms->client_version[1];
                }
            }

            /* Store the results */
            crv = sftk_forceAttribute(key, CKA_VALUE, key_block,
                                      SSL3_MASTER_SECRET_LENGTH);
            break;
        }

        case CKM_TLS12_KEY_AND_MAC_DERIVE:
        case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
        case CKM_TLS_KEY_AND_MAC_DERIVE:
        case CKM_SSL3_KEY_AND_MAC_DERIVE: {
            CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
            CK_SSL3_KEY_MAT_OUT *ssl3_keys_out;
            CK_ULONG effKeySize;
            unsigned int block_needed;
            unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
            unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];

            if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) {
                CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
                    (CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter;
                tlsPrfHash = GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
                if (tlsPrfHash == HASH_AlgNULL) {
                    crv = CKR_MECHANISM_PARAM_INVALID;
                    break;
                }
            } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
                tlsPrfHash = HASH_AlgSHA256;
            }

            if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE) {
                isTLS = PR_TRUE;
            }

            crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv != CKR_OK)
                break;

            if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH) {
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }
            att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE);
            if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
                                   CKK_GENERIC_SECRET)) {
                if (att2)
                    sftk_FreeAttribute(att2);
                crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
                break;
            }
            sftk_FreeAttribute(att2);
            md5 = MD5_NewContext();
            if (md5 == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            sha = SHA1_NewContext();
            if (sha == NULL) {
                MD5_DestroyContext(md5, PR_TRUE);
                crv = CKR_HOST_MEMORY;
                break;
            }
            ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter;

            PORT_Memcpy(srcrdata,
                        ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
            PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH,
                        ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);

            PORT_Memcpy(crsrdata,
                        ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
            PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
                        ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);

            /*
             * clear out our returned keys so we can recover on failure
             */
            ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
            ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE;
            ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE;
            ssl3_keys_out->hClientKey = CK_INVALID_HANDLE;
            ssl3_keys_out->hServerKey = CK_INVALID_HANDLE;

            /*
             * How much key material do we need?
             */
            macSize = ssl3_keys->ulMacSizeInBits / 8;
            effKeySize = ssl3_keys->ulKeySizeInBits / 8;
            IVSize = ssl3_keys->ulIVSizeInBits / 8;
            if (keySize == 0) {
                effKeySize = keySize;
            }

            /* bIsExport must be false. */
            if (ssl3_keys->bIsExport) {
                MD5_DestroyContext(md5, PR_TRUE);
                SHA1_DestroyContext(sha, PR_TRUE);
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }

            block_needed = 2 * (macSize + effKeySize + IVSize);
            PORT_Assert(block_needed <= sizeof key_block);
            if (block_needed > sizeof key_block)
                block_needed = sizeof key_block;

            /*
             * generate the key material: This looks amazingly similar to the
             * PMS code, and is clearly crying out for a function to provide it.
             */
            if (isTLS) {
                SECStatus status;
                SECItem srcr = { siBuffer, NULL, 0 };
                SECItem keyblk = { siBuffer, NULL, 0 };
                SECItem master = { siBuffer, NULL, 0 };

                srcr.data = srcrdata;
                srcr.len = sizeof srcrdata;
                keyblk.data = key_block;
                keyblk.len = block_needed;
                master.data = (unsigned char *)att->attrib.pValue;
                master.len = att->attrib.ulValueLen;

                if (tlsPrfHash != HASH_AlgNULL) {
                    status = TLS_P_hash(tlsPrfHash, &master, "key expansion",
                                        &srcr, &keyblk, isFIPS);
                } else {
                    status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
                                     isFIPS);
                }
                if (status != SECSuccess) {
                    goto key_and_mac_derive_fail;
                }
            } else {
                unsigned int block_bytes = 0;
                /* key_block =
                 *     MD5(master_secret + SHA('A' + master_secret +
                 *                      ServerHello.random + ClientHello.random)) +
                 *     MD5(master_secret + SHA('BB' + master_secret +
                 *                      ServerHello.random + ClientHello.random)) +
                 *     MD5(master_secret + SHA('CCC' + master_secret +
                 *                      ServerHello.random + ClientHello.random)) +
                 *     [...];
                 */
                for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) {
                    SHA1_Begin(sha);
                    SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i]));
                    SHA1_Update(sha, (const unsigned char *)att->attrib.pValue,
                                att->attrib.ulValueLen);
                    SHA1_Update(sha, srcrdata, sizeof srcrdata);
                    SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
                    PORT_Assert(outLen == SHA1_LENGTH);
                    MD5_Begin(md5);
                    MD5_Update(md5, (const unsigned char *)att->attrib.pValue,
                               att->attrib.ulValueLen);
                    MD5_Update(md5, sha_out, outLen);
                    MD5_End(md5, &key_block[i * MD5_LENGTH], &outLen, MD5_LENGTH);
                    PORT_Assert(outLen == MD5_LENGTH);
                    block_bytes += outLen;
                }
            }

            /*
             * Put the key material where it goes.
             */
            i = 0; /* now shows how much consumed */

            /*
             * The key_block is partitioned as follows:
             * client_write_MAC_secret[CipherSpec.hash_size]
             */
            crv = sftk_buildSSLKey(hSession, key, PR_TRUE, &key_block[i], macSize,
                                   &ssl3_keys_out->hClientMacSecret);
            if (crv != CKR_OK)
                goto key_and_mac_derive_fail;

            i += macSize;

            /*
             * server_write_MAC_secret[CipherSpec.hash_size]
             */
            crv = sftk_buildSSLKey(hSession, key, PR_TRUE, &key_block[i], macSize,
                                   &ssl3_keys_out->hServerMacSecret);
            if (crv != CKR_OK) {
                goto key_and_mac_derive_fail;
            }
            i += macSize;

            if (keySize) {
                /*
                ** Generate Domestic write keys and IVs.
                ** client_write_key[CipherSpec.key_material]
                */
                crv = sftk_buildSSLKey(hSession, key, PR_FALSE, &key_block[i],
                                       keySize, &ssl3_keys_out->hClientKey);
                if (crv != CKR_OK) {
                    goto key_and_mac_derive_fail;
                }
                i += keySize;

                /*
                ** server_write_key[CipherSpec.key_material]
                */
                crv = sftk_buildSSLKey(hSession, key, PR_FALSE, &key_block[i],
                                       keySize, &ssl3_keys_out->hServerKey);
                if (crv != CKR_OK) {
                    goto key_and_mac_derive_fail;
                }
                i += keySize;

                /*
                ** client_write_IV[CipherSpec.IV_size]
                */
                if (IVSize > 0) {
                    PORT_Memcpy(ssl3_keys_out->pIVClient,
                                &key_block[i], IVSize);
                    i += IVSize;
                }

                /*
                ** server_write_IV[CipherSpec.IV_size]
                */
                if (IVSize > 0) {
                    PORT_Memcpy(ssl3_keys_out->pIVServer,
                                &key_block[i], IVSize);
                    i += IVSize;
                }
                PORT_Assert(i <= sizeof key_block);
            }

            crv = CKR_OK;

            if (0) {
            key_and_mac_derive_fail:
                if (crv == CKR_OK)
                    crv = CKR_FUNCTION_FAILED;
                sftk_freeSSLKeys(hSession, ssl3_keys_out);
            }
            MD5_DestroyContext(md5, PR_TRUE);
            SHA1_DestroyContext(sha, PR_TRUE);
            sftk_FreeObject(key);
            key = NULL;
            break;
        }

        case CKM_DES3_ECB_ENCRYPT_DATA:
        case CKM_DES3_CBC_ENCRYPT_DATA: {
            void *cipherInfo;
            unsigned char des3key[MAX_DES3_KEY_SIZE];
            CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr;
            int mode;
            unsigned char *iv;
            unsigned char *data;
            CK_ULONG len;

            if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA) {
                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
                                pMechanism->pParameter;
                mode = NSS_DES_EDE3;
                iv = NULL;
                data = stringPtr->pData;
                len = stringPtr->ulLen;
            } else {
                mode = NSS_DES_EDE3_CBC;
                desEncryptPtr =
                    (CK_DES_CBC_ENCRYPT_DATA_PARAMS *)
                        pMechanism->pParameter;
                iv = desEncryptPtr->iv;
                data = desEncryptPtr->pData;
                len = desEncryptPtr->length;
            }
            if (att->attrib.ulValueLen == 16) {
                PORT_Memcpy(des3key, att->attrib.pValue, 16);
                PORT_Memcpy(des3key + 16, des3key, 8);
            } else if (att->attrib.ulValueLen == 24) {
                PORT_Memcpy(des3key, att->attrib.pValue, 24);
            } else {
                crv = CKR_KEY_SIZE_RANGE;
                break;
            }
            cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE);
            PORT_Memset(des3key, 0, 24);
            if (cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            crv = sftk_DeriveEncrypt((SFTKCipher)DES_Encrypt,
                                     cipherInfo, 8, key, keySize,
                                     data, len);
            DES_DestroyContext(cipherInfo, PR_TRUE);
            break;
        }

        case CKM_AES_ECB_ENCRYPT_DATA:
        case CKM_AES_CBC_ENCRYPT_DATA: {
            void *cipherInfo;
            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
            int mode;
            unsigned char *iv;
            unsigned char *data;
            CK_ULONG len;

            if (mechanism == CKM_AES_ECB_ENCRYPT_DATA) {
                mode = NSS_AES;
                iv = NULL;
                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
                data = stringPtr->pData;
                len = stringPtr->ulLen;
            } else {
                aesEncryptPtr =
                    (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter;
                mode = NSS_AES_CBC;
                iv = aesEncryptPtr->iv;
                data = aesEncryptPtr->pData;
                len = aesEncryptPtr->length;
            }

            cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue,
                                           iv, mode, PR_TRUE,
                                           att->attrib.ulValueLen, 16);
            if (cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            crv = sftk_DeriveEncrypt((SFTKCipher)AES_Encrypt,
                                     cipherInfo, 16, key, keySize,
                                     data, len);
            AES_DestroyContext(cipherInfo, PR_TRUE);
            break;
        }

        case CKM_CAMELLIA_ECB_ENCRYPT_DATA:
        case CKM_CAMELLIA_CBC_ENCRYPT_DATA: {
            void *cipherInfo;
            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
            int mode;
            unsigned char *iv;
            unsigned char *data;
            CK_ULONG len;

            if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA) {
                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
                                pMechanism->pParameter;
                aesEncryptPtr = NULL;
                mode = NSS_CAMELLIA;
                data = stringPtr->pData;
                len = stringPtr->ulLen;
                iv = NULL;
            } else {
                stringPtr = NULL;
                aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
                                    pMechanism->pParameter;
                mode = NSS_CAMELLIA_CBC;
                iv = aesEncryptPtr->iv;
                data = aesEncryptPtr->pData;
                len = aesEncryptPtr->length;
            }

            cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue,
                                                iv, mode, PR_TRUE,
                                                att->attrib.ulValueLen);
            if (cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            crv = sftk_DeriveEncrypt((SFTKCipher)Camellia_Encrypt,
                                     cipherInfo, 16, key, keySize,
                                     data, len);
            Camellia_DestroyContext(cipherInfo, PR_TRUE);
            break;
        }

        case CKM_SEED_ECB_ENCRYPT_DATA:
        case CKM_SEED_CBC_ENCRYPT_DATA: {
            void *cipherInfo;
            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
            int mode;
            unsigned char *iv;
            unsigned char *data;
            CK_ULONG len;

            if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA) {
                mode = NSS_SEED;
                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
                                pMechanism->pParameter;
                aesEncryptPtr = NULL;
                data = stringPtr->pData;
                len = stringPtr->ulLen;
                iv = NULL;
            } else {
                mode = NSS_SEED_CBC;
                aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
                                    pMechanism->pParameter;
                iv = aesEncryptPtr->iv;
                data = aesEncryptPtr->pData;
                len = aesEncryptPtr->length;
            }

            cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue,
                                            iv, mode, PR_TRUE);
            if (cipherInfo == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            crv = sftk_DeriveEncrypt((SFTKCipher)SEED_Encrypt,
                                     cipherInfo, 16, key, keySize,
                                     data, len);
            SEED_DestroyContext(cipherInfo, PR_TRUE);
            break;
        }

        case CKM_CONCATENATE_BASE_AND_KEY: {
            SFTKObject *newKey;

            crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv != CKR_OK)
                break;

            session = sftk_SessionFromHandle(hSession);
            if (session == NULL) {
                crv = CKR_SESSION_HANDLE_INVALID;
                break;
            }

            newKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *)
                                                pMechanism->pParameter,
                                           session);
            sftk_FreeSession(session);
            if (newKey == NULL) {
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }

            if (sftk_isTrue(newKey, CKA_SENSITIVE)) {
                crv = sftk_forceAttribute(newKey, CKA_SENSITIVE, &cktrue,
                                          sizeof(CK_BBOOL));
                if (crv != CKR_OK) {
                    sftk_FreeObject(newKey);
                    break;
                }
            }

            att2 = sftk_FindAttribute(newKey, CKA_VALUE);
            if (att2 == NULL) {
                sftk_FreeObject(newKey);
                crv = CKR_KEY_HANDLE_INVALID;
                break;
            }
            tmpKeySize = att->attrib.ulValueLen + att2->attrib.ulValueLen;
            if (keySize == 0)
                keySize = tmpKeySize;
            if (keySize > tmpKeySize) {
                sftk_FreeObject(newKey);
                sftk_FreeAttribute(att2);
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            buf = (unsigned char *)PORT_Alloc(tmpKeySize);
            if (buf == NULL) {
                sftk_FreeAttribute(att2);
                sftk_FreeObject(newKey);
                crv = CKR_HOST_MEMORY;
                break;
            }

            PORT_Memcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
            PORT_Memcpy(buf + att->attrib.ulValueLen,
                        att2->attrib.pValue, att2->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize);
            PORT_ZFree(buf, tmpKeySize);
            sftk_FreeAttribute(att2);
            sftk_FreeObject(newKey);
            break;
        }

        case CKM_CONCATENATE_BASE_AND_DATA:
            crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv != CKR_OK)
                break;

            stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
            tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
            if (keySize == 0)
                keySize = tmpKeySize;
            if (keySize > tmpKeySize) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            buf = (unsigned char *)PORT_Alloc(tmpKeySize);
            if (buf == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }

            PORT_Memcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
            PORT_Memcpy(buf + att->attrib.ulValueLen, stringPtr->pData,
                        stringPtr->ulLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize);
            PORT_ZFree(buf, tmpKeySize);
            break;
        case CKM_CONCATENATE_DATA_AND_BASE:
            crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv != CKR_OK)
                break;

            stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
            tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
            if (keySize == 0)
                keySize = tmpKeySize;
            if (keySize > tmpKeySize) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            buf = (unsigned char *)PORT_Alloc(tmpKeySize);
            if (buf == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }

            PORT_Memcpy(buf, stringPtr->pData, stringPtr->ulLen);
            PORT_Memcpy(buf + stringPtr->ulLen, att->attrib.pValue,
                        att->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize);
            PORT_ZFree(buf, tmpKeySize);
            break;
        case CKM_XOR_BASE_AND_DATA:
            crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv != CKR_OK)
                break;

            stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
            tmpKeySize = PR_MIN(att->attrib.ulValueLen, stringPtr->ulLen);
            if (keySize == 0)
                keySize = tmpKeySize;
            if (keySize > tmpKeySize) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            buf = (unsigned char *)PORT_Alloc(keySize);
            if (buf == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }

            PORT_Memcpy(buf, att->attrib.pValue, keySize);
            for (i = 0; i < (int)keySize; i++) {
                buf[i] ^= stringPtr->pData[i];
            }

            crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize);
            PORT_ZFree(buf, keySize);
            break;

        case CKM_EXTRACT_KEY_FROM_KEY: {
            /* the following assumes 8 bits per byte */
            CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
            CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */
            CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */

            crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv != CKR_OK)
                break;

            if (keySize == 0) {
                crv = CKR_TEMPLATE_INCOMPLETE;
                break;
            }
            /* make sure we have enough bits in the original key */
            if (att->attrib.ulValueLen <
                (offset + keySize + ((shift != 0) ? 1 : 0))) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            buf = (unsigned char *)PORT_Alloc(keySize);
            if (buf == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }

            /* copy the bits we need into the new key */
            for (i = 0; i < (int)keySize; i++) {
                unsigned char *value =
                    ((unsigned char *)att->attrib.pValue) + offset + i;
                if (shift) {
                    buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift));
                } else {
                    buf[i] = value[0];
                }
            }

            crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize);
            PORT_ZFree(buf, keySize);
            break;
        }
        case CKM_MD2_KEY_DERIVATION:
            if (keySize == 0)
                keySize = MD2_LENGTH;
            if (keySize > MD2_LENGTH) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            /* now allocate the hash contexts */
            md2 = MD2_NewContext();
            if (md2 == NULL) {
                crv = CKR_HOST_MEMORY;
                break;
            }
            MD2_Begin(md2);
            MD2_Update(md2, (const unsigned char *)att->attrib.pValue,
                       att->attrib.ulValueLen);
            MD2_End(md2, key_block, &outLen, MD2_LENGTH);
            MD2_DestroyContext(md2, PR_TRUE);

            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
            break;
        case CKM_MD5_KEY_DERIVATION:
            if (keySize == 0)
                keySize = MD5_LENGTH;
            if (keySize > MD5_LENGTH) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            MD5_HashBuf(key_block, (const unsigned char *)att->attrib.pValue,
                        att->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
            break;
        case CKM_SHA1_KEY_DERIVATION:
            if (keySize == 0)
                keySize = SHA1_LENGTH;
            if (keySize > SHA1_LENGTH) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            SHA1_HashBuf(key_block, (const unsigned char *)att->attrib.pValue,
                         att->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
            break;

        case CKM_SHA224_KEY_DERIVATION:
            if (keySize == 0)
                keySize = SHA224_LENGTH;
            if (keySize > SHA224_LENGTH) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            SHA224_HashBuf(key_block, (const unsigned char *)att->attrib.pValue,
                           att->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
            break;

        case CKM_SHA256_KEY_DERIVATION:
            if (keySize == 0)
                keySize = SHA256_LENGTH;
            if (keySize > SHA256_LENGTH) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            SHA256_HashBuf(key_block, (const unsigned char *)att->attrib.pValue,
                           att->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
            break;

        case CKM_SHA384_KEY_DERIVATION:
            if (keySize == 0)
                keySize = SHA384_LENGTH;
            if (keySize > SHA384_LENGTH) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            SHA384_HashBuf(key_block, (const unsigned char *)att->attrib.pValue,
                           att->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
            break;

        case CKM_SHA512_KEY_DERIVATION:
            if (keySize == 0)
                keySize = SHA512_LENGTH;
            if (keySize > SHA512_LENGTH) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            SHA512_HashBuf(key_block, (const unsigned char *)att->attrib.pValue,
                           att->attrib.ulValueLen);

            crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
            break;

        case CKM_DH_PKCS_DERIVE: {
            SECItem derived, dhPublic;
            SECItem dhPrime, dhValue;
            /* sourceKey - values for the local existing low key */
            /* get prime and value attributes */
            crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME);
            if (crv != SECSuccess)
                break;
            crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE);
            if (crv != SECSuccess) {
                PORT_Free(dhPrime.data);
                break;
            }

            dhPublic.data = pMechanism->pParameter;
            dhPublic.len = pMechanism->ulParameterLen;

            /* calculate private value - oct */
            rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);

            PORT_Free(dhPrime.data);
            PORT_Free(dhValue.data);

            if (rv == SECSuccess) {
                sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
                PORT_ZFree(derived.data, derived.len);
            } else
                crv = CKR_HOST_MEMORY;

            break;
        }

        case CKM_ECDH1_DERIVE:
        case CKM_ECDH1_COFACTOR_DERIVE: {
            SECItem ecScalar, ecPoint;
            SECItem tmp;
            PRBool withCofactor = PR_FALSE;
            unsigned char *secret;
            unsigned char *keyData = NULL;
            unsigned int secretlen, pubKeyLen;
            CK_ECDH1_DERIVE_PARAMS *mechParams;
            NSSLOWKEYPrivateKey *privKey;
            PLArenaPool *arena = NULL;

            /* Check mechanism parameters */
            mechParams = (CK_ECDH1_DERIVE_PARAMS *)pMechanism->pParameter;
            if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) ||
                ((mechParams->kdf == CKD_NULL) &&
                 ((mechParams->ulSharedDataLen != 0) ||
                  (mechParams->pSharedData != NULL)))) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }

            privKey = sftk_GetPrivKey(sourceKey, CKK_EC, &crv);
            if (privKey == NULL) {
                break;
            }

            /* Now we are working with a non-NULL private key */
            SECITEM_CopyItem(NULL, &ecScalar, &privKey->u.ec.privateValue);

            ecPoint.data = mechParams->pPublicData;
            ecPoint.len = mechParams->ulPublicDataLen;

            pubKeyLen = EC_GetPointSize(&privKey->u.ec.ecParams);

            /* if the len is too large, might be an encoded point */
            if (ecPoint.len > pubKeyLen) {
                SECItem newPoint;

                arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
                if (arena == NULL) {
                    goto ec_loser;
                }

                rv = SEC_QuickDERDecodeItem(arena, &newPoint,
                                            SEC_ASN1_GET(SEC_OctetStringTemplate),
                                            &ecPoint);
                if (rv != SECSuccess) {
                    goto ec_loser;
                }
                ecPoint = newPoint;
            }

            if (mechanism == CKM_ECDH1_COFACTOR_DERIVE) {
                withCofactor = PR_TRUE;
            }

            rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar,
                             withCofactor, &tmp);
            PORT_Free(ecScalar.data);
            ecScalar.data = NULL;
            if (privKey != sourceKey->objectInfo) {
                nsslowkey_DestroyPrivateKey(privKey);
                privKey = NULL;
            }
            if (arena) {
                PORT_FreeArena(arena, PR_FALSE);
                arena = NULL;
            }

            if (rv != SECSuccess) {
                crv = sftk_MapCryptError(PORT_GetError());
                break;
            }

            /*
             * apply the kdf function.
             */
            if (mechParams->kdf == CKD_NULL) {
                /*
             * tmp is the raw data created by ECDH_Derive,
             * secret and secretlen are the values we will
             * eventually pass as our generated key.
             */
                secret = tmp.data;
                secretlen = tmp.len;
            } else {
                secretlen = keySize;
                crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
                                          &tmp, mechParams->pSharedData,
                                          mechParams->ulSharedDataLen, mechParams->kdf);
                PORT_ZFree(tmp.data, tmp.len);
                if (crv != CKR_OK) {
                    break;
                }
                tmp.data = secret;
                tmp.len = secretlen;
            }

            /*
             * if keySize is supplied, then we are generating a key of a specific
             * length. This is done by taking the least significant 'keySize'
             * bytes from the unsigned value calculated by ECDH. Note: this may
             * mean padding temp with extra leading zeros from what ECDH_Derive
             * already returned (which itself may contain leading zeros).
             */
            if (keySize) {
                if (secretlen < keySize) {
                    keyData = PORT_ZAlloc(keySize);
                    if (!keyData) {
                        PORT_ZFree(tmp.data, tmp.len);
                        crv = CKR_HOST_MEMORY;
                        break;
                    }
                    PORT_Memcpy(&keyData[keySize - secretlen], secret, secretlen);
                    secret = keyData;
                } else {
                    secret += (secretlen - keySize);
                }
                secretlen = keySize;
            }

            sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
            PORT_ZFree(tmp.data, tmp.len);
            if (keyData) {
                PORT_ZFree(keyData, keySize);
            }
            break;

        ec_loser:
            crv = CKR_ARGUMENTS_BAD;
            PORT_Free(ecScalar.data);
            if (privKey != sourceKey->objectInfo)
                nsslowkey_DestroyPrivateKey(privKey);
            if (arena) {
                PORT_FreeArena(arena, PR_FALSE);
            }
            break;
        }

        /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */
        case CKM_NSS_HKDF_SHA1:
            hashType = HASH_AlgSHA1;
            goto hkdf;
        case CKM_NSS_HKDF_SHA256:
            hashType = HASH_AlgSHA256;
            goto hkdf;
        case CKM_NSS_HKDF_SHA384:
            hashType = HASH_AlgSHA384;
            goto hkdf;
        case CKM_NSS_HKDF_SHA512:
            hashType = HASH_AlgSHA512;
            goto hkdf;
        hkdf : {
            const CK_NSS_HKDFParams *params =
                (const CK_NSS_HKDFParams *)pMechanism->pParameter;
            const SECHashObject *rawHash;
            unsigned hashLen;
            CK_BYTE hashbuf[HASH_LENGTH_MAX];
            CK_BYTE *prk; /* psuedo-random key */
            CK_ULONG prkLen;
            CK_BYTE *okm; /* output keying material */

            rawHash = HASH_GetRawHashObject(hashType);
            if (rawHash == NULL || rawHash->length > sizeof(hashbuf)) {
                crv = CKR_FUNCTION_FAILED;
                break;
            }
            hashLen = rawHash->length;

            if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams) ||
                !params || (!params->bExpand && !params->bExtract) ||
                (params->bExtract && params->ulSaltLen > 0 && !params->pSalt) ||
                (params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) {
                crv = CKR_MECHANISM_PARAM_INVALID;
                break;
            }
            if (keySize == 0 || keySize > sizeof key_block ||
                (!params->bExpand && keySize > hashLen) ||
                (params->bExpand && keySize > 255 * hashLen)) {
                crv = CKR_TEMPLATE_INCONSISTENT;
                break;
            }
            crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv != CKR_OK)
                break;

            /* HKDF-Extract(salt, base key value) */
            if (params->bExtract) {
                CK_BYTE *salt;
                CK_ULONG saltLen;
                HMACContext *hmac;
                unsigned int bufLen;

                salt = params->pSalt;
                saltLen = params->ulSaltLen;
                if (salt == NULL) {
                    saltLen = hashLen;
                    salt = hashbuf;
                    memset(salt, 0, saltLen);
                }
                hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
                if (!hmac) {
                    crv = CKR_HOST_MEMORY;
                    break;
                }
                HMAC_Begin(hmac);
                HMAC_Update(hmac, (const unsigned char *)att->attrib.pValue,
                            att->attrib.ulValueLen);
                HMAC_Finish(hmac, hashbuf, &bufLen, sizeof(hashbuf));
                HMAC_Destroy(hmac, PR_TRUE);
                PORT_Assert(bufLen == rawHash->length);
                prk = hashbuf;
                prkLen = bufLen;
            } else {
                /* PRK = base key value */
                prk = (CK_BYTE *)att->attrib.pValue;
                prkLen = att->attrib.ulValueLen;
            }

            /* HKDF-Expand */
            if (!params->bExpand) {
                okm = prk;
            } else {
                /* T(1) = HMAC-Hash(prk, "" | info | 0x01)
                 * T(n) = HMAC-Hash(prk, T(n-1) | info | n
                 * key material = T(1) | ... | T(n)
                 */
                HMACContext *hmac;
                CK_BYTE bi;
                unsigned iterations = PR_ROUNDUP(keySize, hashLen) / hashLen;
                hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
                if (hmac == NULL) {
                    crv = CKR_HOST_MEMORY;
                    break;
                }
                for (bi = 1; bi <= iterations; ++bi) {
                    unsigned len;
                    HMAC_Begin(hmac);
                    if (bi > 1) {
                        HMAC_Update(hmac, key_block + ((bi - 2) * hashLen), hashLen);
                    }
                    if (params->ulInfoLen != 0) {
                        HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
                    }
                    HMAC_Update(hmac, &bi, 1);
                    HMAC_Finish(hmac, key_block + ((bi - 1) * hashLen), &len,
                                hashLen);
                    PORT_Assert(len == hashLen);
                }
                HMAC_Destroy(hmac, PR_TRUE);
                okm = key_block;
            }
            /* key material = prk */
            crv = sftk_forceAttribute(key, CKA_VALUE, okm, keySize);
            break;
        } /* end of CKM_NSS_HKDF_* */

        case CKM_NSS_JPAKE_ROUND2_SHA1:
            hashType = HASH_AlgSHA1;
            goto jpake2;
        case CKM_NSS_JPAKE_ROUND2_SHA256:
            hashType = HASH_AlgSHA256;
            goto jpake2;
        case CKM_NSS_JPAKE_ROUND2_SHA384:
            hashType = HASH_AlgSHA384;
            goto jpake2;
        case CKM_NSS_JPAKE_ROUND2_SHA512:
            hashType = HASH_AlgSHA512;
            goto jpake2;
        jpake2:
            if (pMechanism->pParameter == NULL ||
                pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params))
                crv = CKR_MECHANISM_PARAM_INVALID;
            if (crv == CKR_OK && sftk_isTrue(key, CKA_TOKEN))
                crv = CKR_TEMPLATE_INCONSISTENT;
            if (crv == CKR_OK)
                crv = sftk_DeriveSensitiveCheck(sourceKey, key);
            if (crv == CKR_OK)
                crv = jpake_Round2(hashType,
                                   (CK_NSS_JPAKERound2Params *)pMechanism->pParameter,
                                   sourceKey, key);
            break;

        case CKM_NSS_JPAKE_FINAL_SHA1:
            hashType = HASH_AlgSHA1;
            goto jpakeFinal;
        case CKM_NSS_JPAKE_FINAL_SHA256:
            hashType = HASH_AlgSHA256;
            goto jpakeFinal;
        case CKM_NSS_JPAKE_FINAL_SHA384:
            hashType = HASH_AlgSHA384;
            goto jpakeFinal;
        case CKM_NSS_JPAKE_FINAL_SHA512:
            hashType = HASH_AlgSHA512;
            goto jpakeFinal;
        jpakeFinal:
            if (pMechanism->pParameter == NULL ||
                pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams))
                crv = CKR_MECHANISM_PARAM_INVALID;
            /* We purposely do not do the derive sensitivity check; we want to be
               able to derive non-sensitive keys while allowing the ROUND1 and
               ROUND2 keys to be sensitive (which they always are, since they are
               in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE
               in the template in order for the resultant keyblock key to be
               sensitive.
             */
            if (crv == CKR_OK)
                crv = jpake_Final(hashType,
                                  (CK_NSS_JPAKEFinalParams *)pMechanism->pParameter,
                                  sourceKey, key);
            break;

        default:
            crv = CKR_MECHANISM_INVALID;
    }
    if (att) {
        sftk_FreeAttribute(att);
    }
    sftk_FreeObject(sourceKey);
    if (crv != CKR_OK) {
        if (key)
            sftk_FreeObject(key);
        return crv;
    }

    /* link the key object into the list */
    if (key) {
        SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
        PORT_Assert(sessKey);
        /* get the session */
        sessKey->wasDerived = PR_TRUE;
        session = sftk_SessionFromHandle(hSession);
        if (session == NULL) {
            sftk_FreeObject(key);
            return CKR_HOST_MEMORY;
        }

        crv = sftk_handleObject(key, session);
        sftk_FreeSession(session);
        *phKey = key->handle;
        sftk_FreeObject(key);
    }
    return crv;
}

/* NSC_GetFunctionStatus obtains an updated status of a function running
 * in parallel with an application. */
CK_RV
NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
{
    CHECK_FORK();

    return CKR_FUNCTION_NOT_PARALLEL;
}

/* NSC_CancelFunction cancels a function running in parallel */
CK_RV
NSC_CancelFunction(CK_SESSION_HANDLE hSession)
{
    CHECK_FORK();

    return CKR_FUNCTION_NOT_PARALLEL;
}

/* NSC_GetOperationState saves the state of the cryptographic
 * operation in a session.
 * NOTE: This code only works for digest functions for now. eventually need
 * to add full flatten/resurect to our state stuff so that all types of state
 * can be saved */
CK_RV
NSC_GetOperationState(CK_SESSION_HANDLE hSession,
                      CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
{
    SFTKSessionContext *context;
    SFTKSession *session;
    CK_RV crv;
    CK_ULONG pOSLen = *pulOperationStateLen;

    CHECK_FORK();

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
    if (crv != CKR_OK)
        return crv;

    *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE) + sizeof(SFTKContextType);
    if (pOperationState == NULL) {
        sftk_FreeSession(session);
        return CKR_OK;
    } else {
        if (pOSLen < *pulOperationStateLen) {
            return CKR_BUFFER_TOO_SMALL;
        }
    }
    PORT_Memcpy(pOperationState, &context->type, sizeof(SFTKContextType));
    pOperationState += sizeof(SFTKContextType);
    PORT_Memcpy(pOperationState, &context->currentMech,
                sizeof(CK_MECHANISM_TYPE));
    pOperationState += sizeof(CK_MECHANISM_TYPE);
    PORT_Memcpy(pOperationState, context->cipherInfo, context->cipherInfoLen);
    sftk_FreeSession(session);
    return CKR_OK;
}

#define sftk_Decrement(stateSize, len) \
    stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize) - (CK_ULONG)(len)) : 0;

/* NSC_SetOperationState restores the state of the cryptographic
 * operation in a session. This is coded like it can restore lots of
 * states, but it only works for truly flat cipher structures. */
CK_RV
NSC_SetOperationState(CK_SESSION_HANDLE hSession,
                      CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
                      CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
{
    SFTKSessionContext *context;
    SFTKSession *session;
    SFTKContextType type;
    CK_MECHANISM mech;
    CK_RV crv = CKR_OK;

    CHECK_FORK();

    while (ulOperationStateLen != 0) {
        /* get what type of state we're dealing with... */
        PORT_Memcpy(&type, pOperationState, sizeof(SFTKContextType));

        /* fix up session contexts based on type */
        session = sftk_SessionFromHandle(hSession);
        if (session == NULL)
            return CKR_SESSION_HANDLE_INVALID;
        context = sftk_ReturnContextByType(session, type);
        sftk_SetContextByType(session, type, NULL);
        if (context) {
            sftk_FreeContext(context);
        }
        pOperationState += sizeof(SFTKContextType);
        sftk_Decrement(ulOperationStateLen, sizeof(SFTKContextType));

        /* get the mechanism structure */
        PORT_Memcpy(&mech.mechanism, pOperationState, sizeof(CK_MECHANISM_TYPE));
        pOperationState += sizeof(CK_MECHANISM_TYPE);
        sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE));
        /* should be filled in... but not necessary for hash */
        mech.pParameter = NULL;
        mech.ulParameterLen = 0;
        switch (type) {
            case SFTK_HASH:
                crv = NSC_DigestInit(hSession, &mech);
                if (crv != CKR_OK)
                    break;
                crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE,
                                      NULL);
                if (crv != CKR_OK)
                    break;
                PORT_Memcpy(context->cipherInfo, pOperationState,
                            context->cipherInfoLen);
                pOperationState += context->cipherInfoLen;
                sftk_Decrement(ulOperationStateLen, context->cipherInfoLen);
                break;
            default:
                /* do sign/encrypt/decrypt later */
                crv = CKR_SAVED_STATE_INVALID;
        }
        sftk_FreeSession(session);
        if (crv != CKR_OK)
            break;
    }
    return crv;
}

/* Dual-function cryptographic operations */

/* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption
 * operation. */
CK_RV
NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
                        CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
                        CK_ULONG_PTR pulEncryptedPartLen)
{
    CK_RV crv;

    CHECK_FORK();

    crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
                            pulEncryptedPartLen);
    if (crv != CKR_OK)
        return crv;
    crv = NSC_DigestUpdate(hSession, pPart, ulPartLen);

    return crv;
}

/* NSC_DecryptDigestUpdate continues a multiple-part decryption and
 * digesting operation. */
CK_RV
NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
                        CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
                        CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
{
    CK_RV crv;

    CHECK_FORK();

    crv = NSC_DecryptUpdate(hSession, pEncryptedPart, ulEncryptedPartLen,
                            pPart, pulPartLen);
    if (crv != CKR_OK)
        return crv;
    crv = NSC_DigestUpdate(hSession, pPart, *pulPartLen);

    return crv;
}

/* NSC_SignEncryptUpdate continues a multiple-part signing and
 * encryption operation. */
CK_RV
NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
                      CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
                      CK_ULONG_PTR pulEncryptedPartLen)
{
    CK_RV crv;

    CHECK_FORK();

    crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
                            pulEncryptedPartLen);
    if (crv != CKR_OK)
        return crv;
    crv = NSC_SignUpdate(hSession, pPart, ulPartLen);

    return crv;
}

/* NSC_DecryptVerifyUpdate continues a multiple-part decryption
 * and verify operation. */
CK_RV
NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
                        CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
                        CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
{
    CK_RV crv;

    CHECK_FORK();

    crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
                            pData, pulDataLen);
    if (crv != CKR_OK)
        return crv;
    crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);

    return crv;
}

/* NSC_DigestKey continues a multi-part message-digesting operation,
 * by digesting the value of a secret key as part of the data already digested.
 */
CK_RV
NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
{
    SFTKSession *session = NULL;
    SFTKObject *key = NULL;
    SFTKAttribute *att;
    CK_RV crv;

    CHECK_FORK();

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL)
        return CKR_SESSION_HANDLE_INVALID;

    key = sftk_ObjectFromHandle(hKey, session);
    sftk_FreeSession(session);
    if (key == NULL)
        return CKR_KEY_HANDLE_INVALID;

    /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */

    /* make sure it's a valid  key for this operation */
    if (key->objclass != CKO_SECRET_KEY) {
        sftk_FreeObject(key);
        return CKR_KEY_TYPE_INCONSISTENT;
    }
    /* get the key value */
    att = sftk_FindAttribute(key, CKA_VALUE);
    sftk_FreeObject(key);
    if (!att) {
        return CKR_KEY_HANDLE_INVALID;
    }
    crv = NSC_DigestUpdate(hSession, (CK_BYTE_PTR)att->attrib.pValue,
                           att->attrib.ulValueLen);
    sftk_FreeAttribute(att);
    return crv;
}
