/* 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 the Symkey wrapper and the PKCS context
 * Interfaces.
 */

#include "seccomon.h"
#include "secmod.h"
#include "nssilock.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "secitem.h"
#include "secoid.h"
#include "secerr.h"
#include "hasht.h"

static ECPointEncoding pk11_ECGetPubkeyEncoding(const SECKEYPublicKey *pubKey);

static void
pk11_EnterKeyMonitor(PK11SymKey *symKey)
{
    if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))
        PK11_EnterSlotMonitor(symKey->slot);
}

static void
pk11_ExitKeyMonitor(PK11SymKey *symKey)
{
    if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))
        PK11_ExitSlotMonitor(symKey->slot);
}

/*
 * pk11_getKeyFromList returns a symKey that has a session (if needSession
 * was specified), or explicitly does not have a session (if needSession
 * was not specified).
 */
static PK11SymKey *
pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession)
{
    PK11SymKey *symKey = NULL;

    PZ_Lock(slot->freeListLock);
    /* own session list are symkeys with sessions that the symkey owns.
     * 'most' symkeys will own their own session. */
    if (needSession) {
        if (slot->freeSymKeysWithSessionHead) {
            symKey = slot->freeSymKeysWithSessionHead;
            slot->freeSymKeysWithSessionHead = symKey->next;
            slot->keyCount--;
        }
    }
    /* if we don't need a symkey with its own session, or we couldn't find
     * one on the owner list, get one from the non-owner free list. */
    if (!symKey) {
        if (slot->freeSymKeysHead) {
            symKey = slot->freeSymKeysHead;
            slot->freeSymKeysHead = symKey->next;
            slot->keyCount--;
        }
    }
    PZ_Unlock(slot->freeListLock);
    if (symKey) {
        symKey->next = NULL;
        if (!needSession) {
            return symKey;
        }
        /* if we are getting an owner key, make sure we have a valid session.
         * session could be invalid if the token has been removed or because
         * we got it from the non-owner free list */
        if ((symKey->series != slot->series) ||
            (symKey->session == CK_INVALID_SESSION)) {
            symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
        }
        PORT_Assert(symKey->session != CK_INVALID_SESSION);
        if (symKey->session != CK_INVALID_SESSION)
            return symKey;
        PK11_FreeSymKey(symKey);
        /* if we are here, we need a session, but couldn't get one, it's
         * unlikely we pk11_GetNewSession will succeed if we call it a second
         * time. */
        return NULL;
    }

    symKey = PORT_New(PK11SymKey);
    if (symKey == NULL) {
        return NULL;
    }

    symKey->next = NULL;
    if (needSession) {
        symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
        PORT_Assert(symKey->session != CK_INVALID_SESSION);
        if (symKey->session == CK_INVALID_SESSION) {
            PK11_FreeSymKey(symKey);
            symKey = NULL;
        }
    } else {
        symKey->session = CK_INVALID_SESSION;
    }
    return symKey;
}

/* Caller MUST hold slot->freeListLock (or ref count == 0?) !! */
void
PK11_CleanKeyList(PK11SlotInfo *slot)
{
    PK11SymKey *symKey = NULL;

    while (slot->freeSymKeysWithSessionHead) {
        symKey = slot->freeSymKeysWithSessionHead;
        slot->freeSymKeysWithSessionHead = symKey->next;
        pk11_CloseSession(slot, symKey->session, symKey->sessionOwner);
        PORT_Free(symKey);
    }
    while (slot->freeSymKeysHead) {
        symKey = slot->freeSymKeysHead;
        slot->freeSymKeysHead = symKey->next;
        pk11_CloseSession(slot, symKey->session, symKey->sessionOwner);
        PORT_Free(symKey);
    }
    return;
}

/*
 * create a symetric key:
 *      Slot is the slot to create the key in.
 *      type is the mechanism type
 *      owner is does this symKey structure own it's object handle (rare
 *        that this is false).
 *      needSession means the returned symKey will return with a valid session
 *        allocated already.
 */
static PK11SymKey *
pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                  PRBool owner, PRBool needSession, void *wincx)
{

    PK11SymKey *symKey = pk11_getKeyFromList(slot, needSession);

    if (symKey == NULL) {
        return NULL;
    }
    /* if needSession was specified, make sure we have a valid session.
     * callers which specify needSession as false should do their own
     * check of the session before returning the symKey */
    if (needSession && symKey->session == CK_INVALID_SESSION) {
        PK11_FreeSymKey(symKey);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return NULL;
    }

    symKey->type = type;
    symKey->data.type = siBuffer;
    symKey->data.data = NULL;
    symKey->data.len = 0;
    symKey->owner = owner;
    symKey->objectID = CK_INVALID_HANDLE;
    symKey->slot = slot;
    symKey->series = slot->series;
    symKey->cx = wincx;
    symKey->size = 0;
    symKey->refCount = 1;
    symKey->origin = PK11_OriginNULL;
    symKey->parent = NULL;
    symKey->freeFunc = NULL;
    symKey->userData = NULL;
    PK11_ReferenceSlot(slot);
    return symKey;
}

/*
 * destroy a symetric key
 */
void
PK11_FreeSymKey(PK11SymKey *symKey)
{
    PK11SlotInfo *slot;
    PRBool freeit = PR_TRUE;

    if (!symKey) {
        return;
    }

    if (PR_ATOMIC_DECREMENT(&symKey->refCount) == 0) {
        PK11SymKey *parent = symKey->parent;

        symKey->parent = NULL;
        if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) {
            pk11_EnterKeyMonitor(symKey);
            (void)PK11_GETTAB(symKey->slot)->C_DestroyObject(symKey->session, symKey->objectID);
            pk11_ExitKeyMonitor(symKey);
        }
        if (symKey->data.data) {
            PORT_Memset(symKey->data.data, 0, symKey->data.len);
            PORT_Free(symKey->data.data);
        }
        /* free any existing data */
        if (symKey->userData && symKey->freeFunc) {
            (*symKey->freeFunc)(symKey->userData);
        }
        slot = symKey->slot;
        PZ_Lock(slot->freeListLock);
        if (slot->keyCount < slot->maxKeyCount) {
            /*
             * freeSymkeysWithSessionHead contain a list of reusable
             *  SymKey structures with valid sessions.
             *    sessionOwner must be true.
             *    session must be valid.
             * freeSymKeysHead contain a list of SymKey structures without
             *  valid session.
             *    session must be CK_INVALID_SESSION.
             *    though sessionOwner is false, callers should not depend on
             *    this fact.
             */
            if (symKey->sessionOwner) {
                PORT_Assert(symKey->session != CK_INVALID_SESSION);
                symKey->next = slot->freeSymKeysWithSessionHead;
                slot->freeSymKeysWithSessionHead = symKey;
            } else {
                symKey->session = CK_INVALID_SESSION;
                symKey->next = slot->freeSymKeysHead;
                slot->freeSymKeysHead = symKey;
            }
            slot->keyCount++;
            symKey->slot = NULL;
            freeit = PR_FALSE;
        }
        PZ_Unlock(slot->freeListLock);
        if (freeit) {
            pk11_CloseSession(symKey->slot, symKey->session,
                              symKey->sessionOwner);
            PORT_Free(symKey);
        }
        PK11_FreeSlot(slot);

        if (parent) {
            PK11_FreeSymKey(parent);
        }
    }
}

PK11SymKey *
PK11_ReferenceSymKey(PK11SymKey *symKey)
{
    PR_ATOMIC_INCREMENT(&symKey->refCount);
    return symKey;
}

/*
 * Accessors
 */
CK_MECHANISM_TYPE
PK11_GetMechanism(PK11SymKey *symKey)
{
    return symKey->type;
}

/*
 * return the slot associated with a symetric key
 */
PK11SlotInfo *
PK11_GetSlotFromKey(PK11SymKey *symKey)
{
    return PK11_ReferenceSlot(symKey->slot);
}

CK_KEY_TYPE
PK11_GetSymKeyType(PK11SymKey *symKey)
{
    return PK11_GetKeyType(symKey->type, symKey->size);
}

PK11SymKey *
PK11_GetNextSymKey(PK11SymKey *symKey)
{
    return symKey ? symKey->next : NULL;
}

char *
PK11_GetSymKeyNickname(PK11SymKey *symKey)
{
    return PK11_GetObjectNickname(symKey->slot, symKey->objectID);
}

SECStatus
PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname)
{
    return PK11_SetObjectNickname(symKey->slot, symKey->objectID, nickname);
}

void *
PK11_GetSymKeyUserData(PK11SymKey *symKey)
{
    return symKey->userData;
}

void
PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData,
                       PK11FreeDataFunc freeFunc)
{
    /* free any existing data */
    if (symKey->userData && symKey->freeFunc) {
        (*symKey->freeFunc)(symKey->userData);
    }
    symKey->userData = userData;
    symKey->freeFunc = freeFunc;
    return;
}

/*
 * turn key handle into an appropriate key object
 */
PK11SymKey *
PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
                      CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, PRBool owner, void *wincx)
{
    PK11SymKey *symKey;
    PRBool needSession = !(owner && parent);

    if (keyID == CK_INVALID_HANDLE) {
        return NULL;
    }

    symKey = pk11_CreateSymKey(slot, type, owner, needSession, wincx);
    if (symKey == NULL) {
        return NULL;
    }

    symKey->objectID = keyID;
    symKey->origin = origin;

    /* adopt the parent's session */
    /* This is only used by SSL. What we really want here is a session
     * structure with a ref count so  the session goes away only after all the
     * keys do. */
    if (!needSession) {
        symKey->sessionOwner = PR_FALSE;
        symKey->session = parent->session;
        symKey->parent = PK11_ReferenceSymKey(parent);
        /* This is the only case where pk11_CreateSymKey does not explicitly
         * check symKey->session. We need to assert here to make sure.
         * the session isn't invalid. */
        PORT_Assert(parent->session != CK_INVALID_SESSION);
        if (parent->session == CK_INVALID_SESSION) {
            PK11_FreeSymKey(symKey);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return NULL;
        }
    }

    return symKey;
}

/*
 * turn key handle into an appropriate key object
 */
PK11SymKey *
PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
                int series, void *wincx)
{
    PK11SymKey *symKey = NULL;

    if (slot->series != series)
        return NULL;
    if (slot->refKeys[wrap] == CK_INVALID_HANDLE)
        return NULL;
    if (type == CKM_INVALID_MECHANISM)
        type = slot->wrapMechanism;

    symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
                                   slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx);
    return symKey;
}

/*
 * This function is not thread-safe because it sets wrapKey->sessionOwner
 * without using a lock or atomic routine.  It can only be called when
 * only one thread has a reference to wrapKey.
 */
void
PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey)
{
    /* save the handle and mechanism for the wrapping key */
    /* mark the key and session as not owned by us to they don't get freed
     * when the key goes way... that lets us reuse the key later */
    slot->refKeys[wrap] = wrapKey->objectID;
    wrapKey->owner = PR_FALSE;
    wrapKey->sessionOwner = PR_FALSE;
    slot->wrapMechanism = wrapKey->type;
}

/*
 * figure out if a key is still valid or if it is stale.
 */
PRBool
PK11_VerifyKeyOK(PK11SymKey *key)
{
    if (!PK11_IsPresent(key->slot)) {
        return PR_FALSE;
    }
    return (PRBool)(key->series == key->slot->series);
}

static PK11SymKey *
pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                           PK11Origin origin, PRBool isToken, CK_ATTRIBUTE *keyTemplate,
                           unsigned int templateCount, SECItem *key, void *wincx)
{
    PK11SymKey *symKey;
    SECStatus rv;

    symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
    if (symKey == NULL) {
        return NULL;
    }

    symKey->size = key->len;

    PK11_SETATTRS(&keyTemplate[templateCount], CKA_VALUE, key->data, key->len);
    templateCount++;

    if (SECITEM_CopyItem(NULL, &symKey->data, key) != SECSuccess) {
        PK11_FreeSymKey(symKey);
        return NULL;
    }

    symKey->origin = origin;

    /* import the keys */
    rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate,
                              templateCount, isToken, &symKey->objectID);
    if (rv != SECSuccess) {
        PK11_FreeSymKey(symKey);
        return NULL;
    }

    return symKey;
}

/*
 * turn key bits into an appropriate key object
 */
PK11SymKey *
PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                  PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx)
{
    PK11SymKey *symKey;
    unsigned int templateCount = 0;
    CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_BBOOL cktrue = CK_TRUE; /* sigh */
    CK_ATTRIBUTE keyTemplate[5];
    CK_ATTRIBUTE *attrs = keyTemplate;

    PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
    attrs++;
    PK11_SETATTRS(attrs, operation, &cktrue, 1);
    attrs++;
    templateCount = attrs - keyTemplate;
    PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));

    keyType = PK11_GetKeyType(type, key->len);
    symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, PR_FALSE,
                                        keyTemplate, templateCount, key, wincx);
    return symKey;
}

/*
 * turn key bits into an appropriate key object
 */
PK11SymKey *
PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                           PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,
                           CK_FLAGS flags, PRBool isPerm, void *wincx)
{
    PK11SymKey *symKey;
    unsigned int templateCount = 0;
    CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_BBOOL cktrue = CK_TRUE; /* sigh */
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
    CK_ATTRIBUTE *attrs = keyTemplate;

    PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
    attrs++;
    if (isPerm) {
        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue));
        attrs++;
        /* sigh some tokens think CKA_PRIVATE = false is a reasonable
         * default for secret keys */
        PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue));
        attrs++;
    }
    attrs += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
    if ((operation != CKA_FLAGS_ONLY) &&
        !pk11_FindAttrInTemplate(keyTemplate, attrs - keyTemplate, operation)) {
        PK11_SETATTRS(attrs, operation, &cktrue, sizeof(cktrue));
        attrs++;
    }
    templateCount = attrs - keyTemplate;
    PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));

    keyType = PK11_GetKeyType(type, key->len);
    symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm,
                                        keyTemplate, templateCount, key, wincx);
    if (symKey && isPerm) {
        symKey->owner = PR_FALSE;
    }
    return symKey;
}

PK11SymKey *
PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
                  void *wincx)
{
    CK_ATTRIBUTE findTemp[4];
    CK_ATTRIBUTE *attrs;
    CK_BBOOL ckTrue = CK_TRUE;
    CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
    int tsize = 0;
    CK_OBJECT_HANDLE key_id;

    attrs = findTemp;
    PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue));
    attrs++;
    if (keyID) {
        PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len);
        attrs++;
    }
    tsize = attrs - findTemp;
    PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));

    key_id = pk11_FindObjectByTemplate(slot, findTemp, tsize);
    if (key_id == CK_INVALID_HANDLE) {
        return NULL;
    }
    return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id,
                                 PR_FALSE, wincx);
}

PK11SymKey *
PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
{
    CK_ATTRIBUTE findTemp[4];
    CK_ATTRIBUTE *attrs;
    CK_BBOOL ckTrue = CK_TRUE;
    CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
    int tsize = 0;
    int objCount = 0;
    CK_OBJECT_HANDLE *key_ids;
    PK11SymKey *nextKey = NULL;
    PK11SymKey *topKey = NULL;
    int i, len;

    attrs = findTemp;
    PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue));
    attrs++;
    if (nickname) {
        len = PORT_Strlen(nickname);
        PK11_SETATTRS(attrs, CKA_LABEL, nickname, len);
        attrs++;
    }
    tsize = attrs - findTemp;
    PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));

    key_ids = pk11_FindObjectsByTemplate(slot, findTemp, tsize, &objCount);
    if (key_ids == NULL) {
        return NULL;
    }

    for (i = 0; i < objCount; i++) {
        SECItem typeData;
        CK_KEY_TYPE type = CKK_GENERIC_SECRET;
        SECStatus rv = PK11_ReadAttribute(slot, key_ids[i],
                                          CKA_KEY_TYPE, NULL, &typeData);
        if (rv == SECSuccess) {
            if (typeData.len == sizeof(CK_KEY_TYPE)) {
                type = *(CK_KEY_TYPE *)typeData.data;
            }
            PORT_Free(typeData.data);
        }
        nextKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
                                        PK11_GetKeyMechanism(type), key_ids[i], PR_FALSE, wincx);
        if (nextKey) {
            nextKey->next = topKey;
            topKey = nextKey;
        }
    }
    PORT_Free(key_ids);
    return topKey;
}

void *
PK11_GetWindow(PK11SymKey *key)
{
    return key->cx;
}

/*
 * extract a symetric key value. NOTE: if the key is sensitive, we will
 * not be able to do this operation. This function is used to move
 * keys from one token to another */
SECStatus
PK11_ExtractKeyValue(PK11SymKey *symKey)
{
    SECStatus rv;

    if (symKey->data.data != NULL) {
        if (symKey->size == 0) {
            symKey->size = symKey->data.len;
        }
        return SECSuccess;
    }

    if (symKey->slot == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    rv = PK11_ReadAttribute(symKey->slot, symKey->objectID, CKA_VALUE, NULL,
                            &symKey->data);
    if (rv == SECSuccess) {
        symKey->size = symKey->data.len;
    }
    return rv;
}

SECStatus
PK11_DeleteTokenSymKey(PK11SymKey *symKey)
{
    if (!PK11_IsPermObject(symKey->slot, symKey->objectID)) {
        return SECFailure;
    }
    PK11_DestroyTokenObject(symKey->slot, symKey->objectID);
    symKey->objectID = CK_INVALID_HANDLE;
    return SECSuccess;
}

SECItem *
PK11_GetKeyData(PK11SymKey *symKey)
{
    return &symKey->data;
}

/* This symbol is exported for backward compatibility. */
SECItem *
__PK11_GetKeyData(PK11SymKey *symKey)
{
    return PK11_GetKeyData(symKey);
}

/*
 * PKCS #11 key Types with predefined length
 */
unsigned int
pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType)
{
    int length = 0;
    switch (keyType) {
        case CKK_DES:
            length = 8;
            break;
        case CKK_DES2:
            length = 16;
            break;
        case CKK_DES3:
            length = 24;
            break;
        case CKK_SKIPJACK:
            length = 10;
            break;
        case CKK_BATON:
            length = 20;
            break;
        case CKK_JUNIPER:
            length = 20;
            break;
        default:
            break;
    }
    return length;
}

/* return the keylength if possible.  '0' if not */
unsigned int
PK11_GetKeyLength(PK11SymKey *key)
{
    CK_KEY_TYPE keyType;

    if (key->size != 0)
        return key->size;

    /* First try to figure out the key length from its type */
    keyType = PK11_ReadULongAttribute(key->slot, key->objectID, CKA_KEY_TYPE);
    key->size = pk11_GetPredefinedKeyLength(keyType);
    if ((keyType == CKK_GENERIC_SECRET) &&
        (key->type == CKM_SSL3_PRE_MASTER_KEY_GEN)) {
        key->size = 48;
    }

    if (key->size != 0)
        return key->size;

    if (key->data.data == NULL) {
        PK11_ExtractKeyValue(key);
    }
    /* key is probably secret. Look up its length */
    /*  this is new PKCS #11 version 2.0 functionality. */
    if (key->size == 0) {
        CK_ULONG keyLength;

        keyLength = PK11_ReadULongAttribute(key->slot, key->objectID, CKA_VALUE_LEN);
        if (keyLength != CK_UNAVAILABLE_INFORMATION) {
            key->size = (unsigned int)keyLength;
        }
    }

    return key->size;
}

/* return the strength of a key. This is different from length in that
 * 1) it returns the size in bits, and 2) it returns only the secret portions
 * of the key minus any checksums or parity.
 */
unsigned int
PK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid)
{
    int size = 0;
    CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; /* RC2 only */
    SECItem *param = NULL;                               /* RC2 only */
    CK_RC2_CBC_PARAMS *rc2_params = NULL;                /* RC2 ONLY */
    unsigned int effectiveBits = 0;                      /* RC2 ONLY */

    switch (PK11_GetKeyType(key->type, 0)) {
        case CKK_CDMF:
            return 40;
        case CKK_DES:
            return 56;
        case CKK_DES3:
        case CKK_DES2:
            size = PK11_GetKeyLength(key);
            if (size == 16) {
                /* double des */
                return 112; /* 16*7 */
            }
            return 168;
        /*
         * RC2 has is different than other ciphers in that it allows the user
         * to deprecating keysize while still requiring all the bits for the
         * original key. The info
         * on what the effective key strength is in the parameter for the key.
         * In S/MIME this parameter is stored in the DER encoded algid. In Our
         * other uses of RC2, effectiveBits == keyBits, so this code functions
         * correctly without an algid.
         */
        case CKK_RC2:
            /* if no algid was provided, fall through to default */
            if (!algid) {
                break;
            }
            /* verify that the algid is for RC2 */
            mechanism = PK11_AlgtagToMechanism(SECOID_GetAlgorithmTag(algid));
            if ((mechanism != CKM_RC2_CBC) && (mechanism != CKM_RC2_ECB)) {
                break;
            }

            /* now get effective bits from the algorithm ID. */
            param = PK11_ParamFromAlgid(algid);
            /* if we couldn't get memory just use key length */
            if (param == NULL) {
                break;
            }

            rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
            /* paranoia... shouldn't happen */
            PORT_Assert(param->data != NULL);
            if (param->data == NULL) {
                SECITEM_FreeItem(param, PR_TRUE);
                break;
            }
            effectiveBits = (unsigned int)rc2_params->ulEffectiveBits;
            SECITEM_FreeItem(param, PR_TRUE);
            param = NULL;
            rc2_params = NULL; /* paranoia */

            /* we have effective bits, is and allocated memory is free, now
             * we need to return the smaller of effective bits and keysize */
            size = PK11_GetKeyLength(key);
            if ((unsigned int)size * 8 > effectiveBits) {
                return effectiveBits;
            }

            return size * 8; /* the actual key is smaller, the strength can't be
                              * greater than the actual key size */

        default:
            break;
    }
    return PK11_GetKeyLength(key) * 8;
}

/*
 * The next three utilities are to deal with the fact that a given operation
 * may be a multi-slot affair. This creates a new key object that is copied
 * into the new slot.
 */
PK11SymKey *
pk11_CopyToSlotPerm(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                    CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags,
                    PRBool isPerm, PK11SymKey *symKey)
{
    SECStatus rv;
    PK11SymKey *newKey = NULL;

    /* Extract the raw key data if possible */
    if (symKey->data.data == NULL) {
        rv = PK11_ExtractKeyValue(symKey);
        /* KEY is sensitive, we're try key exchanging it. */
        if (rv != SECSuccess) {
            return pk11_KeyExchange(slot, type, operation,
                                    flags, isPerm, symKey);
        }
    }

    newKey = PK11_ImportSymKeyWithFlags(slot, type, symKey->origin,
                                        operation, &symKey->data, flags, isPerm, symKey->cx);
    if (newKey == NULL) {
        newKey = pk11_KeyExchange(slot, type, operation, flags, isPerm, symKey);
    }
    return newKey;
}

PK11SymKey *
pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey)
{
    return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey);
}

/*
 * Make sure the slot we are in is the correct slot for the operation
 * by verifying that it supports all of the specified mechanism types.
 */
PK11SymKey *
pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type,
                       int mechCount, CK_ATTRIBUTE_TYPE operation)
{
    PK11SlotInfo *slot = symKey->slot;
    PK11SymKey *newKey = NULL;
    PRBool needToCopy = PR_FALSE;
    int i;

    if (slot == NULL) {
        needToCopy = PR_TRUE;
    } else {
        i = 0;
        while ((i < mechCount) && (needToCopy == PR_FALSE)) {
            if (!PK11_DoesMechanism(slot, type[i])) {
                needToCopy = PR_TRUE;
            }
            i++;
        }
    }

    if (needToCopy == PR_TRUE) {
        slot = PK11_GetBestSlotMultiple(type, mechCount, symKey->cx);
        if (slot == NULL) {
            PORT_SetError(SEC_ERROR_NO_MODULE);
            return NULL;
        }
        newKey = pk11_CopyToSlot(slot, type[0], operation, symKey);
        PK11_FreeSlot(slot);
    }
    return newKey;
}

/*
 * Make sure the slot we are in is the correct slot for the operation
 */
PK11SymKey *
pk11_ForceSlot(PK11SymKey *symKey, CK_MECHANISM_TYPE type,
               CK_ATTRIBUTE_TYPE operation)
{
    return pk11_ForceSlotMultiple(symKey, &type, 1, operation);
}

PK11SymKey *
PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
                CK_FLAGS flags, PRBool perm, PK11SymKey *symKey)
{
    if (symKey->slot == slot) {
        if (perm) {
            return PK11_ConvertSessionSymKeyToTokenSymKey(symKey, symKey->cx);
        } else {
            return PK11_ReferenceSymKey(symKey);
        }
    }

    return pk11_CopyToSlotPerm(slot, symKey->type,
                               operation, flags, perm, symKey);
}

/*
 * Use the token to generate a key.
 *
 * keySize must be 'zero' for fixed key length algorithms. A nonzero
 *  keySize causes the CKA_VALUE_LEN attribute to be added to the template
 *  for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN
 *  attribute for keys with fixed length. The exception is DES2. If you
 *  select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN
 *  parameter and use the key size to determine which underlying DES keygen
 *  function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN).
 *
 * keyType must be -1 for most algorithms. Some PBE algorthims cannot
 *  determine the correct key type from the mechanism or the parameters,
 *  so key type must be specified. Other PKCS #11 mechanisms may do so in
 *  the future. Currently there is no need to export this publically.
 *  Keep it private until there is a need in case we need to expand the
 *  keygen parameters again...
 *
 * CK_FLAGS flags: key operation flags
 * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags
 */
PK11SymKey *
pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                                    SECItem *param, CK_KEY_TYPE keyType, int keySize, SECItem *keyid,
                                    CK_FLAGS opFlags, PK11AttrFlags attrFlags, void *wincx)
{
    PK11SymKey *symKey;
    CK_ATTRIBUTE genTemplate[MAX_TEMPL_ATTRS];
    CK_ATTRIBUTE *attrs = genTemplate;
    int count = sizeof(genTemplate) / sizeof(genTemplate[0]);
    CK_MECHANISM_TYPE keyGenType;
    CK_BBOOL cktrue = CK_TRUE;
    CK_BBOOL ckfalse = CK_FALSE;
    CK_ULONG ck_key_size; /* only used for variable-length keys */

    if (pk11_BadAttrFlags(attrFlags)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    if ((keySize != 0) && (type != CKM_DES3_CBC) &&
        (type != CKM_DES3_CBC_PAD) && (type != CKM_DES3_ECB)) {
        ck_key_size = keySize; /* Convert to PK11 type */

        PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_key_size));
        attrs++;
    }

    if (keyType != -1) {
        PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE));
        attrs++;
    }

    /* Include key id value if provided */
    if (keyid) {
        PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len);
        attrs++;
    }

    attrs += pk11_AttrFlagsToAttributes(attrFlags, attrs, &cktrue, &ckfalse);
    attrs += pk11_OpFlagsToAttributes(opFlags, attrs, &cktrue);

    count = attrs - genTemplate;
    PR_ASSERT(count <= sizeof(genTemplate) / sizeof(CK_ATTRIBUTE));

    keyGenType = PK11_GetKeyGenWithSize(type, keySize);
    if (keyGenType == CKM_FAKE_RANDOM) {
        PORT_SetError(SEC_ERROR_NO_MODULE);
        return NULL;
    }
    symKey = PK11_KeyGenWithTemplate(slot, type, keyGenType,
                                     param, genTemplate, count, wincx);
    if (symKey != NULL) {
        symKey->size = keySize;
    }
    return symKey;
}

/*
 * Use the token to generate a key.  - Public
 *
 * keySize must be 'zero' for fixed key length algorithms. A nonzero
 *  keySize causes the CKA_VALUE_LEN attribute to be added to the template
 *  for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN
 *  attribute for keys with fixed length. The exception is DES2. If you
 *  select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN
 *  parameter and use the key size to determine which underlying DES keygen
 *  function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN).
 *
 * CK_FLAGS flags: key operation flags
 * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags
 */
PK11SymKey *
PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                          SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags,
                          PK11AttrFlags attrFlags, void *wincx)
{
    return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param, -1, keySize,
                                               keyid, opFlags, attrFlags, wincx);
}

/*
 * Use the token to generate a key. keySize must be 'zero' for fixed key
 * length algorithms. A nonzero keySize causes the CKA_VALUE_LEN attribute
 * to be added to the template for the key. PKCS #11 modules fail if you
 * specify the CKA_VALUE_LEN attribute for keys with fixed length.
 * NOTE: this means to generate a DES2 key from this interface you must
 * specify CKM_DES2_KEY_GEN as the mechanism directly; specifying
 * CKM_DES3_CBC as the mechanism and 16 as keySize currently doesn't work.
 */
PK11SymKey *
PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
                 int keySize, SECItem *keyid, PRBool isToken, void *wincx)
{
    PK11SymKey *symKey;
    PRBool weird = PR_FALSE; /* hack for fortezza */
    CK_FLAGS opFlags = CKF_SIGN;
    PK11AttrFlags attrFlags = 0;

    if ((keySize == -1) && (type == CKM_SKIPJACK_CBC64)) {
        weird = PR_TRUE;
        keySize = 0;
    }

    opFlags |= weird ? CKF_DECRYPT : CKF_ENCRYPT;

    if (isToken) {
        attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
    }

    symKey = pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param,
                                                 -1, keySize, keyid, opFlags, attrFlags, wincx);
    if (symKey && weird) {
        PK11_SetFortezzaHack(symKey);
    }

    return symKey;
}

PK11SymKey *
PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
            int keySize, void *wincx)
{
    return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx);
}

PK11SymKey *
PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                        CK_MECHANISM_TYPE keyGenType,
                        SECItem *param, CK_ATTRIBUTE *attrs,
                        unsigned int attrsCount, void *wincx)
{
    PK11SymKey *symKey;
    CK_SESSION_HANDLE session;
    CK_MECHANISM mechanism;
    CK_RV crv;
    PRBool isToken = CK_FALSE;
    CK_ULONG keySize = 0;
    unsigned i;

    /* Extract the template's CKA_VALUE_LEN into keySize and CKA_TOKEN into
       isToken. */
    for (i = 0; i < attrsCount; ++i) {
        switch (attrs[i].type) {
            case CKA_VALUE_LEN:
                if (attrs[i].pValue == NULL ||
                    attrs[i].ulValueLen != sizeof(CK_ULONG)) {
                    PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT));
                    return NULL;
                }
                keySize = *(CK_ULONG *)attrs[i].pValue;
                break;
            case CKA_TOKEN:
                if (attrs[i].pValue == NULL ||
                    attrs[i].ulValueLen != sizeof(CK_BBOOL)) {
                    PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT));
                    return NULL;
                }
                isToken = (*(CK_BBOOL *)attrs[i].pValue) ? PR_TRUE : PR_FALSE;
                break;
        }
    }

    /* find a slot to generate the key into */
    /* Only do slot management if this is not a token key */
    if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot, type))) {
        PK11SlotInfo *bestSlot = PK11_GetBestSlot(type, wincx);
        if (bestSlot == NULL) {
            PORT_SetError(SEC_ERROR_NO_MODULE);
            return NULL;
        }
        symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx);
        PK11_FreeSlot(bestSlot);
    } else {
        symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
    }
    if (symKey == NULL)
        return NULL;

    symKey->size = keySize;
    symKey->origin = PK11_OriginGenerated;

    /* Set the parameters for the key gen if provided */
    mechanism.mechanism = keyGenType;
    mechanism.pParameter = NULL;
    mechanism.ulParameterLen = 0;
    if (param) {
        mechanism.pParameter = param->data;
        mechanism.ulParameterLen = param->len;
    }

    /* Get session and perform locking */
    if (isToken) {
        PK11_Authenticate(symKey->slot, PR_TRUE, wincx);
        /* Should always be original slot */
        session = PK11_GetRWSession(symKey->slot);
        symKey->owner = PR_FALSE;
    } else {
        session = symKey->session;
        if (session != CK_INVALID_SESSION)
            pk11_EnterKeyMonitor(symKey);
    }
    if (session == CK_INVALID_SESSION) {
        PK11_FreeSymKey(symKey);
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return NULL;
    }

    crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session, &mechanism, attrs, attrsCount, &symKey->objectID);

    /* Release lock and session */
    if (isToken) {
        PK11_RestoreROSession(symKey->slot, session);
    } else {
        pk11_ExitKeyMonitor(symKey);
    }

    if (crv != CKR_OK) {
        PK11_FreeSymKey(symKey);
        PORT_SetError(PK11_MapError(crv));
        return NULL;
    }

    return symKey;
}

/* --- */
PK11SymKey *
PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx)
{
    return PK11_TokenKeyGen(slot, CKM_DES3_CBC, 0, 0, keyid, PR_TRUE, cx);
}

PK11SymKey *
PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
{
    PK11SlotInfo *slot = symk->slot;
    CK_ATTRIBUTE template[1];
    CK_ATTRIBUTE *attrs = template;
    CK_BBOOL cktrue = CK_TRUE;
    CK_RV crv;
    CK_OBJECT_HANDLE newKeyID;
    CK_SESSION_HANDLE rwsession;

    PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue));
    attrs++;

    PK11_Authenticate(slot, PR_TRUE, wincx);
    rwsession = PK11_GetRWSession(slot);
    if (rwsession == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return NULL;
    }
    crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, symk->objectID,
                                          template, 1, &newKeyID);
    PK11_RestoreROSession(slot, rwsession);

    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return NULL;
    }

    return PK11_SymKeyFromHandle(slot, NULL /*parent*/, symk->origin,
                                 symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/);
}

/*
 * This function does a straight public key wrap (which only RSA can do).
 * Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and
 * Diffie-Hellman Ciphers. */
SECStatus
PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
                   PK11SymKey *symKey, SECItem *wrappedKey)
{
    PK11SlotInfo *slot;
    CK_ULONG len = wrappedKey->len;
    PK11SymKey *newKey = NULL;
    CK_OBJECT_HANDLE id;
    CK_MECHANISM mechanism;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    CK_RV crv;

    if (symKey == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* if this slot doesn't support the mechanism, go to a slot that does */
    newKey = pk11_ForceSlot(symKey, type, CKA_ENCRYPT);
    if (newKey != NULL) {
        symKey = newKey;
    }

    if (symKey->slot == NULL) {
        PORT_SetError(SEC_ERROR_NO_MODULE);
        return SECFailure;
    }

    slot = symKey->slot;
    mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType);
    mechanism.pParameter = NULL;
    mechanism.ulParameterLen = 0;

    id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);
    if (id == CK_INVALID_HANDLE) {
        if (newKey) {
            PK11_FreeSymKey(newKey);
        }
        return SECFailure; /* Error code has been set. */
    }

    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_WrapKey(session, &mechanism,
                                       id, symKey->objectID, wrappedKey->data, &len);
    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    if (newKey) {
        PK11_FreeSymKey(newKey);
    }

    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    wrappedKey->len = len;
    return SECSuccess;
}

/*
 * this little function uses the Encrypt function to wrap a key, just in
 * case we have problems with the wrap implementation for a token.
 */
static SECStatus
pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type,
              SECItem *inKey, SECItem *outKey)
{
    PK11SlotInfo *slot;
    CK_ULONG len;
    SECItem *data;
    CK_MECHANISM mech;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    CK_RV crv;

    slot = wrappingKey->slot;
    /* use NULL IV's for wrapping */
    mech.mechanism = type;
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    } else {
        mech.pParameter = NULL;
        mech.ulParameterLen = 0;
    }
    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_EncryptInit(session, &mech,
                                           wrappingKey->objectID);
    if (crv != CKR_OK) {
        if (!owner || !(slot->isThreadSafe))
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }

    /* keys are almost always aligned, but if we get this far,
     * we've gone above and beyond anyway... */
    data = PK11_BlockData(inKey, PK11_GetBlockSize(type, param));
    if (data == NULL) {
        if (!owner || !(slot->isThreadSafe))
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    len = outKey->len;
    crv = PK11_GETTAB(slot)->C_Encrypt(session, data->data, data->len,
                                       outKey->data, &len);
    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    SECITEM_FreeItem(data, PR_TRUE);
    outKey->len = len;
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

/*
 * This function does a symetric based wrap.
 */
SECStatus
PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
                PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey)
{
    PK11SlotInfo *slot;
    CK_ULONG len = wrappedKey->len;
    PK11SymKey *newKey = NULL;
    SECItem *param_save = NULL;
    CK_MECHANISM mechanism;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    CK_RV crv;
    SECStatus rv;

    /* if this slot doesn't support the mechanism, go to a slot that does */
    /* Force symKey and wrappingKey into the same slot */
    if ((wrappingKey->slot == NULL) || (symKey->slot != wrappingKey->slot)) {
        /* first try copying the wrapping Key to the symKey slot */
        if (symKey->slot && PK11_DoesMechanism(symKey->slot, type)) {
            newKey = pk11_CopyToSlot(symKey->slot, type, CKA_WRAP, wrappingKey);
        }
        /* Nope, try it the other way */
        if (newKey == NULL) {
            if (wrappingKey->slot) {
                newKey = pk11_CopyToSlot(wrappingKey->slot,
                                         symKey->type, CKA_ENCRYPT, symKey);
            }
            /* just not playing... one last thing, can we get symKey's data?
             * If it's possible, we it should already be in the
             * symKey->data.data pointer because pk11_CopyToSlot would have
             * tried to put it there. */
            if (newKey == NULL) {
                /* Can't get symKey's data: Game Over */
                if (symKey->data.data == NULL) {
                    PORT_SetError(SEC_ERROR_NO_MODULE);
                    return SECFailure;
                }
                if (param == NULL) {
                    param_save = param = PK11_ParamFromIV(type, NULL);
                }
                rv = pk11_HandWrap(wrappingKey, param, type,
                                   &symKey->data, wrappedKey);
                if (param_save)
                    SECITEM_FreeItem(param_save, PR_TRUE);
                return rv;
            }
            /* we successfully moved the sym Key */
            symKey = newKey;
        } else {
            /* we successfully moved the wrapping Key */
            wrappingKey = newKey;
        }
    }

    /* at this point both keys are in the same token */
    slot = wrappingKey->slot;
    mechanism.mechanism = type;
    /* use NULL IV's for wrapping */
    if (param == NULL) {
        param_save = param = PK11_ParamFromIV(type, NULL);
    }
    if (param) {
        mechanism.pParameter = param->data;
        mechanism.ulParameterLen = param->len;
    } else {
        mechanism.pParameter = NULL;
        mechanism.ulParameterLen = 0;
    }

    len = wrappedKey->len;

    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_WrapKey(session, &mechanism,
                                       wrappingKey->objectID, symKey->objectID,
                                       wrappedKey->data, &len);
    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    rv = SECSuccess;
    if (crv != CKR_OK) {
        /* can't wrap it? try hand wrapping it... */
        do {
            if (symKey->data.data == NULL) {
                rv = PK11_ExtractKeyValue(symKey);
                if (rv != SECSuccess)
                    break;
            }
            rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data,
                               wrappedKey);
        } while (PR_FALSE);
    } else {
        wrappedKey->len = len;
    }
    if (newKey)
        PK11_FreeSymKey(newKey);
    if (param_save)
        SECITEM_FreeItem(param_save, PR_TRUE);
    return rv;
}

/*
 * This Generates a new key based on a symetricKey
 */
PK11SymKey *
PK11_Derive(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param,
            CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
            int keySize)
{
    return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
                                   keySize, NULL, 0, PR_FALSE);
}

PK11SymKey *
PK11_DeriveWithFlags(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
                     SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
                     int keySize, CK_FLAGS flags)
{
    CK_BBOOL ckTrue = CK_TRUE;
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
    unsigned int templateCount;

    templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
    return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
                                   keySize, keyTemplate, templateCount, PR_FALSE);
}

PK11SymKey *
PK11_DeriveWithFlagsPerm(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
                         SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
                         int keySize, CK_FLAGS flags, PRBool isPerm)
{
    CK_BBOOL cktrue = CK_TRUE;
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
    CK_ATTRIBUTE *attrs;
    unsigned int templateCount = 0;

    attrs = keyTemplate;
    if (isPerm) {
        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
        attrs++;
    }
    templateCount = attrs - keyTemplate;
    templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
    return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
                                   keySize, keyTemplate, templateCount, isPerm);
}

PK11SymKey *
PK11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
                        SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
                        int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs,
                        PRBool isPerm)
{
    PK11SlotInfo *slot = baseKey->slot;
    PK11SymKey *symKey;
    PK11SymKey *newBaseKey = NULL;
    CK_BBOOL cktrue = CK_TRUE;
    CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_ULONG valueLen = 0;
    CK_MECHANISM mechanism;
    CK_RV crv;
#define MAX_ADD_ATTRS 4
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS];
#undef MAX_ADD_ATTRS
    CK_ATTRIBUTE *attrs = keyTemplate;
    CK_SESSION_HANDLE session;
    unsigned int templateCount;

    if (numAttrs > MAX_TEMPL_ATTRS) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    /* first copy caller attributes in. */
    for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
        *attrs++ = *userAttr++;
    }

    /* We only add the following attributes to the template if the caller
    ** didn't already supply them.
    */
    if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) {
        PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass);
        attrs++;
    }
    if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) {
        keyType = PK11_GetKeyType(target, keySize);
        PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType);
        attrs++;
    }
    if (keySize > 0 &&
        !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) {
        valueLen = (CK_ULONG)keySize;
        PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen);
        attrs++;
    }
    if ((operation != CKA_FLAGS_ONLY) &&
        !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) {
        PK11_SETATTRS(attrs, operation, &cktrue, sizeof cktrue);
        attrs++;
    }

    templateCount = attrs - keyTemplate;
    PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));

    /* move the key to a slot that can do the function */
    if (!PK11_DoesMechanism(slot, derive)) {
        /* get a new base key & slot */
        PK11SlotInfo *newSlot = PK11_GetBestSlot(derive, baseKey->cx);

        if (newSlot == NULL)
            return NULL;

        newBaseKey = pk11_CopyToSlot(newSlot, derive, CKA_DERIVE,
                                     baseKey);
        PK11_FreeSlot(newSlot);
        if (newBaseKey == NULL)
            return NULL;
        baseKey = newBaseKey;
        slot = baseKey->slot;
    }

    /* get our key Structure */
    symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, baseKey->cx);
    if (symKey == NULL) {
        return NULL;
    }

    symKey->size = keySize;

    mechanism.mechanism = derive;
    if (param) {
        mechanism.pParameter = param->data;
        mechanism.ulParameterLen = param->len;
    } else {
        mechanism.pParameter = NULL;
        mechanism.ulParameterLen = 0;
    }
    symKey->origin = PK11_OriginDerive;

    if (isPerm) {
        session = PK11_GetRWSession(slot);
    } else {
        pk11_EnterKeyMonitor(symKey);
        session = symKey->session;
    }
    if (session == CK_INVALID_SESSION) {
        if (!isPerm)
            pk11_ExitKeyMonitor(symKey);
        crv = CKR_SESSION_HANDLE_INVALID;
    } else {
        crv = PK11_GETTAB(slot)->C_DeriveKey(session, &mechanism,
                                             baseKey->objectID, keyTemplate, templateCount, &symKey->objectID);
        if (isPerm) {
            PK11_RestoreROSession(slot, session);
        } else {
            pk11_ExitKeyMonitor(symKey);
        }
    }
    if (newBaseKey)
        PK11_FreeSymKey(newBaseKey);
    if (crv != CKR_OK) {
        PK11_FreeSymKey(symKey);
        return NULL;
    }
    return symKey;
}

/* Create a new key by concatenating base and data
 */
static PK11SymKey *
pk11_ConcatenateBaseAndData(PK11SymKey *base,
                            CK_BYTE *data, CK_ULONG dataLen, CK_MECHANISM_TYPE target,
                            CK_ATTRIBUTE_TYPE operation)
{
    CK_KEY_DERIVATION_STRING_DATA mechParams;
    SECItem param;

    if (base == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    mechParams.pData = data;
    mechParams.ulLen = dataLen;
    param.data = (unsigned char *)&mechParams;
    param.len = sizeof(CK_KEY_DERIVATION_STRING_DATA);

    return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_DATA,
                       &param, target, operation, 0);
}

/* Create a new key by concatenating base and key
 */
static PK11SymKey *
pk11_ConcatenateBaseAndKey(PK11SymKey *base,
                           PK11SymKey *key, CK_MECHANISM_TYPE target,
                           CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize)
{
    SECItem param;

    if ((base == NULL) || (key == NULL)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    param.data = (unsigned char *)&(key->objectID);
    param.len = sizeof(CK_OBJECT_HANDLE);

    return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_KEY,
                       &param, target, operation, keySize);
}

/* Create a new key whose value is the hash of tobehashed.
 * type is the mechanism for the derived key.
 */
static PK11SymKey *
pk11_HashKeyDerivation(PK11SymKey *toBeHashed,
                       CK_MECHANISM_TYPE hashMechanism, CK_MECHANISM_TYPE target,
                       CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize)
{
    return PK11_Derive(toBeHashed, hashMechanism, NULL, target, operation, keySize);
}

/* This function implements the ANSI X9.63 key derivation function
 */
static PK11SymKey *
pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
                    CK_EC_KDF_TYPE kdf, SECItem *sharedData,
                    CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
                    CK_ULONG keySize)
{
    CK_KEY_TYPE keyType;
    CK_MECHANISM_TYPE hashMechanism, mechanismArray[4];
    CK_ULONG derivedKeySize, HashLen, counter, maxCounter, bufferLen;
    CK_ULONG SharedInfoLen;
    CK_BYTE *buffer = NULL;
    PK11SymKey *toBeHashed, *hashOutput;
    PK11SymKey *newSharedSecret = NULL;
    PK11SymKey *oldIntermediateResult, *intermediateResult = NULL;

    if (sharedSecret == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    switch (kdf) {
        case CKD_SHA1_KDF:
            HashLen = SHA1_LENGTH;
            hashMechanism = CKM_SHA1_KEY_DERIVATION;
            break;
        case CKD_SHA224_KDF:
            HashLen = SHA224_LENGTH;
            hashMechanism = CKM_SHA224_KEY_DERIVATION;
            break;
        case CKD_SHA256_KDF:
            HashLen = SHA256_LENGTH;
            hashMechanism = CKM_SHA256_KEY_DERIVATION;
            break;
        case CKD_SHA384_KDF:
            HashLen = SHA384_LENGTH;
            hashMechanism = CKM_SHA384_KEY_DERIVATION;
            break;
        case CKD_SHA512_KDF:
            HashLen = SHA512_LENGTH;
            hashMechanism = CKM_SHA512_KEY_DERIVATION;
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return NULL;
    }

    derivedKeySize = keySize;
    if (derivedKeySize == 0) {
        keyType = PK11_GetKeyType(target, keySize);
        derivedKeySize = pk11_GetPredefinedKeyLength(keyType);
        if (derivedKeySize == 0) {
            derivedKeySize = HashLen;
        }
    }

    /* 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 (derivedKeySize > 254 * HashLen) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    maxCounter = derivedKeySize / HashLen;
    if (derivedKeySize > maxCounter * HashLen)
        maxCounter++;

    if ((sharedData == NULL) || (sharedData->data == NULL))
        SharedInfoLen = 0;
    else
        SharedInfoLen = sharedData->len;

    bufferLen = SharedInfoLen + 4;

    /* Populate buffer with Counter || sharedData
     * where Counter is 0x00000001. */
    buffer = (unsigned char *)PORT_Alloc(bufferLen);
    if (buffer == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    buffer[0] = 0;
    buffer[1] = 0;
    buffer[2] = 0;
    buffer[3] = 1;
    if (SharedInfoLen > 0) {
        PORT_Memcpy(&buffer[4], sharedData->data, SharedInfoLen);
    }

    /* Look for a slot that supports the mechanisms needed
     * to implement the ANSI X9.63 KDF as well as the
     * target mechanism.
     */
    mechanismArray[0] = CKM_CONCATENATE_BASE_AND_DATA;
    mechanismArray[1] = hashMechanism;
    mechanismArray[2] = CKM_CONCATENATE_BASE_AND_KEY;
    mechanismArray[3] = target;

    newSharedSecret = pk11_ForceSlotMultiple(sharedSecret,
                                             mechanismArray, 4, operation);
    if (newSharedSecret != NULL) {
        sharedSecret = newSharedSecret;
    }

    for (counter = 1; counter <= maxCounter; counter++) {
        /* Concatenate shared_secret and buffer */
        toBeHashed = pk11_ConcatenateBaseAndData(sharedSecret, buffer,
                                                 bufferLen, hashMechanism, operation);
        if (toBeHashed == NULL) {
            goto loser;
        }

        /* Hash value */
        if (maxCounter == 1) {
            /* In this case the length of the key to be derived is
             * less than or equal to the length of the hash output.
             * So, the output of the hash operation will be the
             * dervied key. */
            hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism,
                                                target, operation, keySize);
        } else {
            /* In this case, the output of the hash operation will be
             * concatenated with other data to create the derived key. */
            hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism,
                                                CKM_CONCATENATE_BASE_AND_KEY, operation, 0);
        }
        PK11_FreeSymKey(toBeHashed);
        if (hashOutput == NULL) {
            goto loser;
        }

        /* Append result to intermediate result, if necessary */
        oldIntermediateResult = intermediateResult;

        if (oldIntermediateResult == NULL) {
            intermediateResult = hashOutput;
        } else {
            if (counter == maxCounter) {
                /* This is the final concatenation, and so the output
                 * will be the derived key. */
                intermediateResult =
                    pk11_ConcatenateBaseAndKey(oldIntermediateResult,
                                               hashOutput, target, operation, keySize);
            } else {
                /* The output of this concatenation will be concatenated
                 * with other data to create the derived key. */
                intermediateResult =
                    pk11_ConcatenateBaseAndKey(oldIntermediateResult,
                                               hashOutput, CKM_CONCATENATE_BASE_AND_KEY,
                                               operation, 0);
            }

            PK11_FreeSymKey(hashOutput);
            PK11_FreeSymKey(oldIntermediateResult);
            if (intermediateResult == NULL) {
                goto loser;
            }
        }

        /* Increment counter (assumes maxCounter < 255) */
        buffer[3]++;
    }

    PORT_ZFree(buffer, bufferLen);
    if (newSharedSecret != NULL)
        PK11_FreeSymKey(newSharedSecret);
    return intermediateResult;

loser:
    PORT_ZFree(buffer, bufferLen);
    if (newSharedSecret != NULL)
        PK11_FreeSymKey(newSharedSecret);
    if (intermediateResult != NULL)
        PK11_FreeSymKey(intermediateResult);
    return NULL;
}

/*
 * This Generates a wrapping key based on a privateKey, publicKey, and two
 * random numbers. For Mail usage RandomB should be NULL. In the Sender's
 * case RandomA is generate, outherwize it is passed.
 */
PK11SymKey *
PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
               PRBool isSender, SECItem *randomA, SECItem *randomB,
               CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
               CK_ATTRIBUTE_TYPE operation, int keySize, void *wincx)
{
    PK11SlotInfo *slot = privKey->pkcs11Slot;
    CK_MECHANISM mechanism;
    PK11SymKey *symKey;
    CK_RV crv;

    /* get our key Structure */
    symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx);
    if (symKey == NULL) {
        return NULL;
    }

    symKey->origin = PK11_OriginDerive;

    switch (privKey->keyType) {
        case rsaKey:
        case rsaPssKey:
        case rsaOaepKey:
        case nullKey:
            PORT_SetError(SEC_ERROR_BAD_KEY);
            break;
        case dsaKey:
        case keaKey:
        case fortezzaKey: {
            static unsigned char rb_email[128] = { 0 };
            CK_KEA_DERIVE_PARAMS param;
            param.isSender = (CK_BBOOL)isSender;
            param.ulRandomLen = randomA->len;
            param.pRandomA = randomA->data;
            param.pRandomB = rb_email;
            param.pRandomB[127] = 1;
            if (randomB)
                param.pRandomB = randomB->data;
            if (pubKey->keyType == fortezzaKey) {
                param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len;
                param.pPublicData = pubKey->u.fortezza.KEAKey.data;
            } else {
                /* assert type == keaKey */
                /* XXX change to match key key types */
                param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len;
                param.pPublicData = pubKey->u.fortezza.KEAKey.data;
            }

            mechanism.mechanism = derive;
            mechanism.pParameter = &param;
            mechanism.ulParameterLen = sizeof(param);

            /* get a new symKey structure */
            pk11_EnterKeyMonitor(symKey);
            crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
                                                 privKey->pkcs11ID, NULL, 0,
                                                 &symKey->objectID);
            pk11_ExitKeyMonitor(symKey);
            if (crv == CKR_OK)
                return symKey;
            PORT_SetError(PK11_MapError(crv));
        } break;
        case dhKey: {
            CK_BBOOL cktrue = CK_TRUE;
            CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
            CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
            CK_ULONG key_size = 0;
            CK_ATTRIBUTE keyTemplate[4];
            int templateCount;
            CK_ATTRIBUTE *attrs = keyTemplate;

            if (pubKey->keyType != dhKey) {
                PORT_SetError(SEC_ERROR_BAD_KEY);
                break;
            }

            PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
            attrs++;
            PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
            attrs++;
            PK11_SETATTRS(attrs, operation, &cktrue, 1);
            attrs++;
            PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
            attrs++;
            templateCount = attrs - keyTemplate;
            PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));

            keyType = PK11_GetKeyType(target, keySize);
            key_size = keySize;
            symKey->size = keySize;
            if (key_size == 0)
                templateCount--;

            mechanism.mechanism = derive;

            /* we can undefine these when we define diffie-helman keys */

            mechanism.pParameter = pubKey->u.dh.publicValue.data;
            mechanism.ulParameterLen = pubKey->u.dh.publicValue.len;

            pk11_EnterKeyMonitor(symKey);
            crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
                                                 privKey->pkcs11ID, keyTemplate,
                                                 templateCount, &symKey->objectID);
            pk11_ExitKeyMonitor(symKey);
            if (crv == CKR_OK)
                return symKey;
            PORT_SetError(PK11_MapError(crv));
        } break;
        case ecKey: {
            CK_BBOOL cktrue = CK_TRUE;
            CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
            CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
            CK_ULONG key_size = 0;
            CK_ATTRIBUTE keyTemplate[4];
            int templateCount;
            CK_ATTRIBUTE *attrs = keyTemplate;
            CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;

            if (pubKey->keyType != ecKey) {
                PORT_SetError(SEC_ERROR_BAD_KEY);
                break;
            }

            PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
            attrs++;
            PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
            attrs++;
            PK11_SETATTRS(attrs, operation, &cktrue, 1);
            attrs++;
            PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
            attrs++;
            templateCount = attrs - keyTemplate;
            PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));

            keyType = PK11_GetKeyType(target, keySize);
            key_size = keySize;
            if (key_size == 0) {
                if ((key_size = pk11_GetPredefinedKeyLength(keyType))) {
                    templateCount--;
                } else {
                    /* sigh, some tokens can't figure this out and require
                     * CKA_VALUE_LEN to be set */
                    key_size = SHA1_LENGTH;
                }
            }
            symKey->size = key_size;

            mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS);
            mechParams->kdf = CKD_SHA1_KDF;
            mechParams->ulSharedDataLen = 0;
            mechParams->pSharedData = NULL;
            mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
            mechParams->pPublicData = pubKey->u.ec.publicValue.data;

            mechanism.mechanism = derive;
            mechanism.pParameter = mechParams;
            mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS);

            pk11_EnterKeyMonitor(symKey);
            crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
                                                 &mechanism, privKey->pkcs11ID, keyTemplate,
                                                 templateCount, &symKey->objectID);
            pk11_ExitKeyMonitor(symKey);

            /* old PKCS #11 spec was ambiguous on what needed to be passed,
             * try this again with and encoded public key */
            if (crv != CKR_OK && pk11_ECGetPubkeyEncoding(pubKey) != ECPoint_XOnly) {
                SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
                                                       &pubKey->u.ec.publicValue,
                                                       SEC_ASN1_GET(SEC_OctetStringTemplate));
                if (pubValue == NULL) {
                    PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
                    break;
                }
                mechParams->ulPublicDataLen = pubValue->len;
                mechParams->pPublicData = pubValue->data;

                pk11_EnterKeyMonitor(symKey);
                crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
                                                     &mechanism, privKey->pkcs11ID, keyTemplate,
                                                     templateCount, &symKey->objectID);
                pk11_ExitKeyMonitor(symKey);

                SECITEM_FreeItem(pubValue, PR_TRUE);
            }

            PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));

            if (crv == CKR_OK)
                return symKey;
            PORT_SetError(PK11_MapError(crv));
        }
    }

    PK11_FreeSymKey(symKey);
    return NULL;
}

/* Test for curves that are known to use a special encoding.
 * Extend this function when additional curves are added. */
static ECPointEncoding
pk11_ECGetPubkeyEncoding(const SECKEYPublicKey *pubKey)
{
    SECItem oid;
    SECStatus rv;
    PORTCheapArenaPool tmpArena;
    ECPointEncoding encoding = ECPoint_Undefined;

    PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);

    /* decode the OID tag */
    rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid,
                                SEC_ASN1_GET(SEC_ObjectIDTemplate),
                                &pubKey->u.ec.DEREncodedParams);
    if (rv == SECSuccess) {
        SECOidTag tag = SECOID_FindOIDTag(&oid);
        switch (tag) {
            case SEC_OID_CURVE25519:
                encoding = ECPoint_XOnly;
                break;
            case SEC_OID_SECG_EC_SECP256R1:
            case SEC_OID_SECG_EC_SECP384R1:
            case SEC_OID_SECG_EC_SECP521R1:
            default:
                /* unknown curve, default to uncompressed */
                encoding = ECPoint_Uncompressed;
        }
    }
    PORT_DestroyCheapArena(&tmpArena);
    return encoding;
}

/* Returns the size of the public key, or 0 if there
 * is an error. */
static CK_ULONG
pk11_ECPubKeySize(SECKEYPublicKey *pubKey)
{
    SECItem *publicValue = &pubKey->u.ec.publicValue;

    ECPointEncoding encoding = pk11_ECGetPubkeyEncoding(pubKey);
    if (encoding == ECPoint_XOnly) {
        return publicValue->len;
    }
    if (encoding == ECPoint_Uncompressed) {
        /* key encoded in uncompressed form */
        return ((publicValue->len - 1) / 2);
    }
    /* key encoding not recognized */
    return 0;
}

static PK11SymKey *
pk11_PubDeriveECKeyWithKDF(
    SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
    PRBool isSender, SECItem *randomA, SECItem *randomB,
    CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
    CK_ATTRIBUTE_TYPE operation, int keySize,
    CK_ULONG kdf, SECItem *sharedData, void *wincx)
{
    PK11SlotInfo *slot = privKey->pkcs11Slot;
    PK11SymKey *symKey;
    PK11SymKey *SharedSecret;
    CK_MECHANISM mechanism;
    CK_RV crv;
    CK_BBOOL cktrue = CK_TRUE;
    CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_ULONG key_size = 0;
    CK_ATTRIBUTE keyTemplate[4];
    int templateCount;
    CK_ATTRIBUTE *attrs = keyTemplate;
    CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;

    if (pubKey->keyType != ecKey) {
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return NULL;
    }
    if ((kdf != CKD_NULL) && (kdf != CKD_SHA1_KDF) &&
        (kdf != CKD_SHA224_KDF) && (kdf != CKD_SHA256_KDF) &&
        (kdf != CKD_SHA384_KDF) && (kdf != CKD_SHA512_KDF)) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        return NULL;
    }

    /* get our key Structure */
    symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx);
    if (symKey == NULL) {
        return NULL;
    }

    symKey->origin = PK11_OriginDerive;

    PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
    attrs++;
    PK11_SETATTRS(attrs, operation, &cktrue, 1);
    attrs++;
    PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
    attrs++;
    templateCount = attrs - keyTemplate;
    PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));

    keyType = PK11_GetKeyType(target, keySize);
    key_size = keySize;
    if (key_size == 0) {
        if ((key_size = pk11_GetPredefinedKeyLength(keyType))) {
            templateCount--;
        } else {
            /* sigh, some tokens can't figure this out and require
             * CKA_VALUE_LEN to be set */
            switch (kdf) {
                case CKD_NULL:
                    key_size = pk11_ECPubKeySize(pubKey);
                    if (key_size == 0) {
                        PK11_FreeSymKey(symKey);
                        return NULL;
                    }
                    break;
                case CKD_SHA1_KDF:
                    key_size = SHA1_LENGTH;
                    break;
                case CKD_SHA224_KDF:
                    key_size = SHA224_LENGTH;
                    break;
                case CKD_SHA256_KDF:
                    key_size = SHA256_LENGTH;
                    break;
                case CKD_SHA384_KDF:
                    key_size = SHA384_LENGTH;
                    break;
                case CKD_SHA512_KDF:
                    key_size = SHA512_LENGTH;
                    break;
                default:
                    PORT_Assert(!"Invalid CKD");
                    PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
                    return NULL;
            }
        }
    }
    symKey->size = key_size;

    mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS);
    if (!mechParams) {
        PK11_FreeSymKey(symKey);
        return NULL;
    }
    mechParams->kdf = kdf;
    if (sharedData == NULL) {
        mechParams->ulSharedDataLen = 0;
        mechParams->pSharedData = NULL;
    } else {
        mechParams->ulSharedDataLen = sharedData->len;
        mechParams->pSharedData = sharedData->data;
    }
    mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
    mechParams->pPublicData = pubKey->u.ec.publicValue.data;

    mechanism.mechanism = derive;
    mechanism.pParameter = mechParams;
    mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS);

    pk11_EnterKeyMonitor(symKey);
    crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
                                         privKey->pkcs11ID, keyTemplate,
                                         templateCount, &symKey->objectID);
    pk11_ExitKeyMonitor(symKey);

    /* old PKCS #11 spec was ambiguous on what needed to be passed,
     * try this again with an encoded public key */
    if (crv != CKR_OK) {
        /* For curves that only use X as public value and no encoding we don't
         * have to try again. (Currently only Curve25519) */
        if (pk11_ECGetPubkeyEncoding(pubKey) == ECPoint_XOnly) {
            goto loser;
        }
        SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
                                               &pubKey->u.ec.publicValue,
                                               SEC_ASN1_GET(SEC_OctetStringTemplate));
        if (pubValue == NULL) {
            goto loser;
        }
        mechParams->ulPublicDataLen = pubValue->len;
        mechParams->pPublicData = pubValue->data;

        pk11_EnterKeyMonitor(symKey);
        crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
                                             &mechanism, privKey->pkcs11ID, keyTemplate,
                                             templateCount, &symKey->objectID);
        pk11_ExitKeyMonitor(symKey);

        if ((crv != CKR_OK) && (kdf != CKD_NULL)) {
            /* Some PKCS #11 libraries cannot perform the key derivation
             * function. So, try calling C_DeriveKey with CKD_NULL and then
             * performing the KDF separately.
             */
            CK_ULONG derivedKeySize = key_size;

            keyType = CKK_GENERIC_SECRET;
            key_size = pk11_ECPubKeySize(pubKey);
            if (key_size == 0) {
                SECITEM_FreeItem(pubValue, PR_TRUE);
                goto loser;
            }
            SharedSecret = symKey;
            SharedSecret->size = key_size;

            mechParams->kdf = CKD_NULL;
            mechParams->ulSharedDataLen = 0;
            mechParams->pSharedData = NULL;
            mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
            mechParams->pPublicData = pubKey->u.ec.publicValue.data;

            pk11_EnterKeyMonitor(SharedSecret);
            crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session,
                                                 &mechanism, privKey->pkcs11ID, keyTemplate,
                                                 templateCount, &SharedSecret->objectID);
            pk11_ExitKeyMonitor(SharedSecret);

            if (crv != CKR_OK) {
                /* old PKCS #11 spec was ambiguous on what needed to be passed,
                 * try this one final time with an encoded public key */
                mechParams->ulPublicDataLen = pubValue->len;
                mechParams->pPublicData = pubValue->data;

                pk11_EnterKeyMonitor(SharedSecret);
                crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session,
                                                     &mechanism, privKey->pkcs11ID, keyTemplate,
                                                     templateCount, &SharedSecret->objectID);
                pk11_ExitKeyMonitor(SharedSecret);
            }

            /* Perform KDF. */
            if (crv == CKR_OK) {
                symKey = pk11_ANSIX963Derive(SharedSecret, kdf,
                                             sharedData, target, operation,
                                             derivedKeySize);
                PK11_FreeSymKey(SharedSecret);
                if (symKey == NULL) {
                    SECITEM_FreeItem(pubValue, PR_TRUE);
                    PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
                    return NULL;
                }
            }
        }
        SECITEM_FreeItem(pubValue, PR_TRUE);
    }

loser:
    PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));

    if (crv != CKR_OK) {
        PK11_FreeSymKey(symKey);
        symKey = NULL;
        PORT_SetError(PK11_MapError(crv));
    }
    return symKey;
}

PK11SymKey *
PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
                      PRBool isSender, SECItem *randomA, SECItem *randomB,
                      CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
                      CK_ATTRIBUTE_TYPE operation, int keySize,
                      CK_ULONG kdf, SECItem *sharedData, void *wincx)
{

    switch (privKey->keyType) {
        case rsaKey:
        case nullKey:
        case dsaKey:
        case keaKey:
        case fortezzaKey:
        case dhKey:
            return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB,
                                  derive, target, operation, keySize, wincx);
        case ecKey:
            return pk11_PubDeriveECKeyWithKDF(privKey, pubKey, isSender,
                                              randomA, randomB, derive, target,
                                              operation, keySize,
                                              kdf, sharedData, wincx);
        default:
            PORT_SetError(SEC_ERROR_BAD_KEY);
            break;
    }

    return NULL;
}

/*
 * this little function uses the Decrypt function to unwrap a key, just in
 * case we are having problem with unwrap. NOTE: The key size may
 * not be preserved properly for some algorithms!
 */
static PK11SymKey *
pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
                CK_MECHANISM *mech, SECItem *inKey, CK_MECHANISM_TYPE target,
                CK_ATTRIBUTE *keyTemplate, unsigned int templateCount,
                int key_size, void *wincx, CK_RV *crvp, PRBool isPerm)
{
    CK_ULONG len;
    SECItem outKey;
    PK11SymKey *symKey;
    CK_RV crv;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;

    /* remove any VALUE_LEN parameters */
    if (keyTemplate[templateCount - 1].type == CKA_VALUE_LEN) {
        templateCount--;
    }

    /* keys are almost always aligned, but if we get this far,
     * we've gone above and beyond anyway... */
    outKey.data = (unsigned char *)PORT_Alloc(inKey->len);
    if (outKey.data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        if (crvp)
            *crvp = CKR_HOST_MEMORY;
        return NULL;
    }
    len = inKey->len;

    /* use NULL IV's for wrapping */
    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, wrappingKey);
    if (crv != CKR_OK) {
        if (!owner || !(slot->isThreadSafe))
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_Free(outKey.data);
        PORT_SetError(PK11_MapError(crv));
        if (crvp)
            *crvp = crv;
        return NULL;
    }
    crv = PK11_GETTAB(slot)->C_Decrypt(session, inKey->data, inKey->len,
                                       outKey.data, &len);
    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    if (crv != CKR_OK) {
        PORT_Free(outKey.data);
        PORT_SetError(PK11_MapError(crv));
        if (crvp)
            *crvp = crv;
        return NULL;
    }

    outKey.len = (key_size == 0) ? len : key_size;
    outKey.type = siBuffer;

    if (PK11_DoesMechanism(slot, target)) {
        symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
                                            isPerm, keyTemplate,
                                            templateCount, &outKey, wincx);
    } else {
        slot = PK11_GetBestSlot(target, wincx);
        if (slot == NULL) {
            PORT_SetError(SEC_ERROR_NO_MODULE);
            PORT_Free(outKey.data);
            if (crvp)
                *crvp = CKR_DEVICE_ERROR;
            return NULL;
        }
        symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
                                            isPerm, keyTemplate,
                                            templateCount, &outKey, wincx);
        PK11_FreeSlot(slot);
    }
    PORT_Free(outKey.data);

    if (crvp)
        *crvp = symKey ? CKR_OK : CKR_DEVICE_ERROR;
    return symKey;
}

/*
 * The wrap/unwrap function is pretty much the same for private and
 * public keys. It's just getting the Object ID and slot right. This is
 * the combined unwrap function.
 */
static PK11SymKey *
pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
                  CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey,
                  CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize,
                  void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, PRBool isPerm)
{
    PK11SymKey *symKey;
    SECItem *param_free = NULL;
    CK_BBOOL cktrue = CK_TRUE;
    CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_ULONG valueLen = 0;
    CK_MECHANISM mechanism;
    CK_SESSION_HANDLE rwsession;
    CK_RV crv;
    CK_MECHANISM_INFO mechanism_info;
#define MAX_ADD_ATTRS 4
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS];
#undef MAX_ADD_ATTRS
    CK_ATTRIBUTE *attrs = keyTemplate;
    unsigned int templateCount;

    if (numAttrs > MAX_TEMPL_ATTRS) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    /* first copy caller attributes in. */
    for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
        *attrs++ = *userAttr++;
    }

    /* We only add the following attributes to the template if the caller
    ** didn't already supply them.
    */
    if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) {
        PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass);
        attrs++;
    }
    if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) {
        keyType = PK11_GetKeyType(target, keySize);
        PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType);
        attrs++;
    }
    if ((operation != CKA_FLAGS_ONLY) &&
        !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) {
        PK11_SETATTRS(attrs, operation, &cktrue, 1);
        attrs++;
    }

    /*
     * must be last in case we need to use this template to import the key
     */
    if (keySize > 0 &&
        !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) {
        valueLen = (CK_ULONG)keySize;
        PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen);
        attrs++;
    }

    templateCount = attrs - keyTemplate;
    PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));

    /* find out if we can do wrap directly. Because the RSA case if *very*
     * common, cache the results for it. */
    if ((wrapType == CKM_RSA_PKCS) && (slot->hasRSAInfo)) {
        mechanism_info.flags = slot->RSAInfoFlags;
    } else {
        if (!slot->isThreadSafe)
            PK11_EnterSlotMonitor(slot);
        crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, wrapType,
                                                    &mechanism_info);
        if (!slot->isThreadSafe)
            PK11_ExitSlotMonitor(slot);
        if (crv != CKR_OK) {
            mechanism_info.flags = 0;
        }
        if (wrapType == CKM_RSA_PKCS) {
            slot->RSAInfoFlags = mechanism_info.flags;
            slot->hasRSAInfo = PR_TRUE;
        }
    }

    /* initialize the mechanism structure */
    mechanism.mechanism = wrapType;
    /* use NULL IV's for wrapping */
    if (param == NULL)
        param = param_free = PK11_ParamFromIV(wrapType, NULL);
    if (param) {
        mechanism.pParameter = param->data;
        mechanism.ulParameterLen = param->len;
    } else {
        mechanism.pParameter = NULL;
        mechanism.ulParameterLen = 0;
    }

    if ((mechanism_info.flags & CKF_DECRYPT) && !PK11_DoesMechanism(slot, target)) {
        symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey,
                                 target, keyTemplate, templateCount, keySize,
                                 wincx, &crv, isPerm);
        if (symKey) {
            if (param_free)
                SECITEM_FreeItem(param_free, PR_TRUE);
            return symKey;
        }
        /*
         * if the RSA OP simply failed, don't try to unwrap again
         * with this module.
         */
        if (crv == CKR_DEVICE_ERROR) {
            if (param_free)
                SECITEM_FreeItem(param_free, PR_TRUE);
            return NULL;
        }
        /* fall through, maybe they incorrectly set CKF_DECRYPT */
    }

    /* get our key Structure */
    symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, wincx);
    if (symKey == NULL) {
        if (param_free)
            SECITEM_FreeItem(param_free, PR_TRUE);
        return NULL;
    }

    symKey->size = keySize;
    symKey->origin = PK11_OriginUnwrap;

    if (isPerm) {
        rwsession = PK11_GetRWSession(slot);
    } else {
        pk11_EnterKeyMonitor(symKey);
        rwsession = symKey->session;
    }
    PORT_Assert(rwsession != CK_INVALID_SESSION);
    if (rwsession == CK_INVALID_SESSION)
        crv = CKR_SESSION_HANDLE_INVALID;
    else
        crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism, wrappingKey,
                                             wrappedKey->data, wrappedKey->len,
                                             keyTemplate, templateCount,
                                             &symKey->objectID);
    if (isPerm) {
        if (rwsession != CK_INVALID_SESSION)
            PK11_RestoreROSession(slot, rwsession);
    } else {
        pk11_ExitKeyMonitor(symKey);
    }
    if (param_free)
        SECITEM_FreeItem(param_free, PR_TRUE);
    if (crv != CKR_OK) {
        PK11_FreeSymKey(symKey);
        symKey = NULL;
        if (crv != CKR_DEVICE_ERROR) {
            /* try hand Unwrapping */
            symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey,
                                     target, keyTemplate, templateCount,
                                     keySize, wincx, NULL, isPerm);
        }
    }

    return symKey;
}

/* use a symetric key to unwrap another symetric key */
PK11SymKey *
PK11_UnwrapSymKey(PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType,
                  SECItem *param, SECItem *wrappedKey,
                  CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
                  int keySize)
{
    return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
                             wrapType, param, wrappedKey, target, operation, keySize,
                             wrappingKey->cx, NULL, 0, PR_FALSE);
}

/* use a symetric key to unwrap another symetric key */
PK11SymKey *
PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType,
                           SECItem *param, SECItem *wrappedKey,
                           CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
                           int keySize, CK_FLAGS flags)
{
    CK_BBOOL ckTrue = CK_TRUE;
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
    unsigned int templateCount;

    templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
    return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
                             wrapType, param, wrappedKey, target, operation, keySize,
                             wrappingKey->cx, keyTemplate, templateCount, PR_FALSE);
}

PK11SymKey *
PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey,
                               CK_MECHANISM_TYPE wrapType,
                               SECItem *param, SECItem *wrappedKey,
                               CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
                               int keySize, CK_FLAGS flags, PRBool isPerm)
{
    CK_BBOOL cktrue = CK_TRUE;
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
    CK_ATTRIBUTE *attrs;
    unsigned int templateCount;

    attrs = keyTemplate;
    if (isPerm) {
        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
        attrs++;
    }
    templateCount = attrs - keyTemplate;
    templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);

    return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
                             wrapType, param, wrappedKey, target, operation, keySize,
                             wrappingKey->cx, keyTemplate, templateCount, isPerm);
}

/* unwrap a symetric key with a private key. */
PK11SymKey *
PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey,
                     CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize)
{
    CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
    PK11SlotInfo *slot = wrappingKey->pkcs11Slot;

    if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) {
        PK11_HandlePasswordCheck(slot, wrappingKey->wincx);
    }

    return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
                             wrapType, NULL, wrappedKey, target, operation, keySize,
                             wrappingKey->wincx, NULL, 0, PR_FALSE);
}

/* unwrap a symetric key with a private key. */
PK11SymKey *
PK11_PubUnwrapSymKeyWithFlags(SECKEYPrivateKey *wrappingKey,
                              SECItem *wrappedKey, CK_MECHANISM_TYPE target,
                              CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags)
{
    CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
    CK_BBOOL ckTrue = CK_TRUE;
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
    unsigned int templateCount;
    PK11SlotInfo *slot = wrappingKey->pkcs11Slot;

    templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);

    if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) {
        PK11_HandlePasswordCheck(slot, wrappingKey->wincx);
    }

    return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
                             wrapType, NULL, wrappedKey, target, operation, keySize,
                             wrappingKey->wincx, keyTemplate, templateCount, PR_FALSE);
}

PK11SymKey *
PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey,
                                  SECItem *wrappedKey, CK_MECHANISM_TYPE target,
                                  CK_ATTRIBUTE_TYPE operation, int keySize,
                                  CK_FLAGS flags, PRBool isPerm)
{
    CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
    CK_BBOOL cktrue = CK_TRUE;
    CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
    CK_ATTRIBUTE *attrs;
    unsigned int templateCount;
    PK11SlotInfo *slot = wrappingKey->pkcs11Slot;

    attrs = keyTemplate;
    if (isPerm) {
        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
        attrs++;
    }
    templateCount = attrs - keyTemplate;

    templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);

    if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) {
        PK11_HandlePasswordCheck(slot, wrappingKey->wincx);
    }

    return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
                             wrapType, NULL, wrappedKey, target, operation, keySize,
                             wrappingKey->wincx, keyTemplate, templateCount, isPerm);
}

PK11SymKey *
PK11_CopySymKeyForSigning(PK11SymKey *originalKey, CK_MECHANISM_TYPE mech)
{
    CK_RV crv;
    CK_ATTRIBUTE setTemplate;
    CK_BBOOL ckTrue = CK_TRUE;
    PK11SlotInfo *slot = originalKey->slot;

    /* first just try to set this key up for signing */
    PK11_SETATTRS(&setTemplate, CKA_SIGN, &ckTrue, sizeof(ckTrue));
    pk11_EnterKeyMonitor(originalKey);
    crv = PK11_GETTAB(slot)->C_SetAttributeValue(originalKey->session,
                                                 originalKey->objectID, &setTemplate, 1);
    pk11_ExitKeyMonitor(originalKey);
    if (crv == CKR_OK) {
        return PK11_ReferenceSymKey(originalKey);
    }

    /* nope, doesn't like it, use the pk11 copy object command */
    return pk11_CopyToSlot(slot, mech, CKA_SIGN, originalKey);
}

void
PK11_SetFortezzaHack(PK11SymKey *symKey)
{
    symKey->origin = PK11_OriginFortezzaHack;
}

/*
 * This is required to allow FORTEZZA_NULL and FORTEZZA_RC4
 * working. This function simply gets a valid IV for the keys.
 */
SECStatus
PK11_GenerateFortezzaIV(PK11SymKey *symKey, unsigned char *iv, int len)
{
    CK_MECHANISM mech_info;
    CK_ULONG count = 0;
    CK_RV crv;
    SECStatus rv = SECFailure;

    mech_info.mechanism = CKM_SKIPJACK_CBC64;
    mech_info.pParameter = iv;
    mech_info.ulParameterLen = len;

    /* generate the IV for fortezza */
    PK11_EnterSlotMonitor(symKey->slot);
    crv = PK11_GETTAB(symKey->slot)->C_EncryptInit(symKey->slot->session, &mech_info, symKey->objectID);
    if (crv == CKR_OK) {
        PK11_GETTAB(symKey->slot)->C_EncryptFinal(symKey->slot->session, NULL, &count);
        rv = SECSuccess;
    }
    PK11_ExitSlotMonitor(symKey->slot);
    return rv;
}

CK_OBJECT_HANDLE
PK11_GetSymKeyHandle(PK11SymKey *symKey)
{
    return symKey->objectID;
}
