/* 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/. */
/*
 * Internal PKCS #11 functions. Should only be called by pkcs11.c
 */
#include "pkcs11.h"
#include "pkcs11i.h"
#include "lowkeyi.h"
#include "secasn1.h"
#include "blapi.h"
#include "secerr.h"
#include "prnetdb.h" /* for PR_ntohl */
#include "sftkdb.h"
#include "softoken.h"
#include "secoid.h"
#include "softkver.h"

#if !defined(NSS_FIPS_DISABLED) && defined(NSS_ENABLE_FIPS_INDICATORS)
/* this file should be supplied by the vendor and include all the
 * algorithms which have Algorithm certs and have been reviewed by
 * the lab. A blank file is included for the base so that FIPS mode
 * will still be compiled and run, but FIPS indicators will always
 * return PR_FALSE
 */
#include "fips_algorithms.h"
#define NSS_HAS_FIPS_INDICATORS 1
#endif

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

/*
 * functions which adjust the mapping based on different contexts
 * (Decrypt or Verify).
 */

/* used by Decrypt and UnwrapKey (indirectly) and Decrypt message */
CK_RV
sftk_MapDecryptError(int error)
{
    switch (error) {
        /* usually a padding error, or aead tag mismatch */
        case SEC_ERROR_BAD_DATA:
            return CKR_ENCRYPTED_DATA_INVALID;
        default:
            return sftk_MapCryptError(error);
    }
}

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

/*
 * ******************** Attribute Utilities *******************************
 */

/*
 * create a new attribute with type, value, and length. Space is allocated
 * to hold value.
 */
static SFTKAttribute *
sftk_NewAttribute(SFTKObject *object,
                  CK_ATTRIBUTE_TYPE type, const void *value, CK_ULONG len)
{
    SFTKAttribute *attribute;

    SFTKSessionObject *so = sftk_narrowToSessionObject(object);
    int index;

    if (so == NULL) {
        /* allocate new attribute in a buffer */
        PORT_Assert(0);
        return NULL;
    }
    /*
     * We attempt to keep down contention on Malloc and Arena locks by
     * limiting the number of these calls on high traversed paths. This
     * is done for attributes by 'allocating' them from a pool already
     * allocated by the parent object.
     */
    PZ_Lock(so->attributeLock);
    index = so->nextAttr++;
    PZ_Unlock(so->attributeLock);
    PORT_Assert(index < MAX_OBJS_ATTRS);
    if (index >= MAX_OBJS_ATTRS)
        return NULL;

    attribute = &so->attrList[index];
    attribute->attrib.type = type;
    attribute->freeAttr = PR_FALSE;
    attribute->freeData = PR_FALSE;
    if (value) {
        if (len <= ATTR_SPACE) {
            attribute->attrib.pValue = attribute->space;
        } else {
            attribute->attrib.pValue = PORT_Alloc(len);
            attribute->freeData = PR_TRUE;
        }
        if (attribute->attrib.pValue == NULL) {
            return NULL;
        }
        PORT_Memcpy(attribute->attrib.pValue, value, len);
        attribute->attrib.ulValueLen = len;
    } else {
        attribute->attrib.pValue = NULL;
        attribute->attrib.ulValueLen = 0;
    }
    attribute->attrib.type = type;
    attribute->handle = type;
    attribute->next = attribute->prev = NULL;
    return attribute;
}

/*
 * Free up all the memory associated with an attribute. Reference count
 * must be zero to call this.
 */
static void
sftk_DestroyAttribute(SFTKAttribute *attribute)
{
    if (attribute->attrib.pValue) {
        /* clear out the data in the attribute value... it may have been
         * sensitive data */
        PORT_Memset(attribute->attrib.pValue, 0, attribute->attrib.ulValueLen);
        if (attribute->freeData) {
            PORT_Free(attribute->attrib.pValue);
            attribute->attrib.pValue = NULL;
            attribute->freeData = PR_FALSE;
        }
    }
    if (attribute->freeAttr) {
        PORT_Free(attribute);
    }
}

/*
 * release a reference to an attribute structure
 */
void
sftk_FreeAttribute(SFTKAttribute *attribute)
{
    if (attribute && attribute->freeAttr) {
        sftk_DestroyAttribute(attribute);
        return;
    }
}

static SFTKAttribute *
sftk_FindTokenAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *myattribute = NULL;
    SFTKDBHandle *dbHandle = NULL;
    CK_RV crv = CKR_HOST_MEMORY;

    myattribute = (SFTKAttribute *)PORT_Alloc(sizeof(SFTKAttribute));
    if (myattribute == NULL) {
        goto loser;
    }

    dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);

    myattribute->handle = type;
    myattribute->attrib.type = type;
    myattribute->attrib.pValue = myattribute->space;
    myattribute->attrib.ulValueLen = ATTR_SPACE;
    myattribute->next = myattribute->prev = NULL;
    myattribute->freeAttr = PR_TRUE;
    myattribute->freeData = PR_FALSE;

    crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
                                   &myattribute->attrib, 1);

    /* attribute is bigger than our attribute space buffer, malloc it */
    if (crv == CKR_BUFFER_TOO_SMALL) {
        myattribute->attrib.pValue = NULL;
        crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
                                       &myattribute->attrib, 1);
        if (crv != CKR_OK) {
            goto loser;
        }
        myattribute->attrib.pValue = PORT_Alloc(myattribute->attrib.ulValueLen);
        if (myattribute->attrib.pValue == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        myattribute->freeData = PR_TRUE;
        crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
                                       &myattribute->attrib, 1);
    }
loser:
    if (dbHandle) {
        sftk_freeDB(dbHandle);
    }
    if (crv != CKR_OK) {
        if (myattribute) {
            myattribute->attrib.ulValueLen = 0;
            sftk_FreeAttribute(myattribute);
            myattribute = NULL;
        }
    }
    return myattribute;
}

/*
 * look up and attribute structure from a type and Object structure.
 * The returned attribute is referenced and needs to be freed when
 * it is no longer needed.
 */
SFTKAttribute *
sftk_FindAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL) {
        return sftk_FindTokenAttribute(sftk_narrowToTokenObject(object), type);
    }

    PZ_Lock(sessObject->attributeLock);
    sftkqueue_find(attribute, type, sessObject->head, sessObject->hashSize);
    PZ_Unlock(sessObject->attributeLock);

    return (attribute);
}

/*
 * Take a buffer and it's length and return it's true size in bits;
 */
unsigned int
sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
{
    unsigned int size = bufLen * 8;
    unsigned int i;

    /* Get the real length in bytes */
    for (i = 0; i < bufLen; i++) {
        unsigned char c = *buf++;
        if (c != 0) {
            unsigned char m;
            for (m = 0x80; m > 0; m = m >> 1) {
                if ((c & m) != 0) {
                    break;
                }
                size--;
            }
            break;
        }
        size -= 8;
    }
    return size;
}

/*
 * Constrain a big num attribute. to size and padding
 * minLength means length of the object must be greater than equal to minLength
 * maxLength means length of the object must be less than equal to maxLength
 * minMultiple means that object length mod minMultiple must equal 0.
 * all input sizes are in bits.
 * if any constraint is '0' that constraint is not checked.
 */
CK_RV
sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                        int minLength, int maxLength, int minMultiple)
{
    SFTKAttribute *attribute;
    int size;
    unsigned char *ptr;

    attribute = sftk_FindAttribute(object, type);
    if (!attribute) {
        return CKR_TEMPLATE_INCOMPLETE;
    }
    ptr = (unsigned char *)attribute->attrib.pValue;
    if (ptr == NULL) {
        sftk_FreeAttribute(attribute);
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    size = sftk_GetLengthInBits(ptr, attribute->attrib.ulValueLen);
    sftk_FreeAttribute(attribute);

    if ((minLength != 0) && (size < minLength)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    if ((maxLength != 0) && (size > maxLength)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    if ((minMultiple != 0) && ((size % minMultiple) != 0)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    return CKR_OK;
}

PRBool
sftk_hasAttributeToken(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
    CK_ATTRIBUTE template;
    CK_RV crv;
    SFTKDBHandle *dbHandle;

    dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);
    template.type = type;
    template.pValue = NULL;
    template.ulValueLen = 0;

    crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, &template, 1);
    sftk_freeDB(dbHandle);

    /* attribute is bigger than our attribute space buffer, malloc it */
    return (crv == CKR_OK) ? PR_TRUE : PR_FALSE;
}

/*
 * return true if object has attribute
 */
PRBool
sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL) {
        return sftk_hasAttributeToken(sftk_narrowToTokenObject(object), type);
    }

    PZ_Lock(sessObject->attributeLock);
    sftkqueue_find(attribute, type, sessObject->head, sessObject->hashSize);
    PZ_Unlock(sessObject->attributeLock);

    return (PRBool)(attribute != NULL);
}

/*
 * add an attribute to an object
 */
static void
sftk_AddAttribute(SFTKObject *object, SFTKAttribute *attribute)
{
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL)
        return;
    PZ_Lock(sessObject->attributeLock);
    sftkqueue_add(attribute, attribute->handle,
                  sessObject->head, sessObject->hashSize);
    PZ_Unlock(sessObject->attributeLock);
}

/*
 * copy an unsigned attribute into a SECItem. Secitem is allocated in
 * the specified arena.
 */
CK_RV
sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item, SFTKObject *object,
                        CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;

    item->data = NULL;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return CKR_TEMPLATE_INCOMPLETE;

    (void)SECITEM_AllocItem(arena, item, attribute->attrib.ulValueLen);
    if (item->data == NULL) {
        sftk_FreeAttribute(attribute);
        return CKR_HOST_MEMORY;
    }
    PORT_Memcpy(item->data, attribute->attrib.pValue, item->len);
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

/*
 * fetch multiple attributes into  SECItems. Secitem data is allocated in
 * the specified arena.
 */
CK_RV
sftk_MultipleAttribute2SecItem(PLArenaPool *arena, SFTKObject *object,
                               SFTKItemTemplate *itemTemplate, int itemTemplateCount)
{

    CK_RV crv = CKR_OK;
    CK_ATTRIBUTE templateSpace[SFTK_MAX_ITEM_TEMPLATE];
    CK_ATTRIBUTE *template;
    SFTKTokenObject *tokObject;
    SFTKDBHandle *dbHandle = NULL;
    int i;

    tokObject = sftk_narrowToTokenObject(object);

    /* session objects, just loop through the list */
    if (tokObject == NULL) {
        for (i = 0; i < itemTemplateCount; i++) {
            crv = sftk_Attribute2SecItem(arena, itemTemplate[i].item, object,
                                         itemTemplate[i].type);
            if (crv != CKR_OK) {
                return crv;
            }
        }
        return CKR_OK;
    }

    /* don't do any work if none is required */
    if (itemTemplateCount == 0) {
        return CKR_OK;
    }

    /* don't allocate the template unless we need it */
    if (itemTemplateCount > SFTK_MAX_ITEM_TEMPLATE) {
        template = PORT_NewArray(CK_ATTRIBUTE, itemTemplateCount);
    } else {
        template = templateSpace;
    }

    if (template == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
    if (dbHandle == NULL) {
        crv = CKR_OBJECT_HANDLE_INVALID;
        goto loser;
    }

    /* set up the PKCS #11 template */
    for (i = 0; i < itemTemplateCount; i++) {
        template[i].type = itemTemplate[i].type;
        template[i].pValue = NULL;
        template[i].ulValueLen = 0;
    }

    /* fetch the attribute lengths */
    crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
                                   template, itemTemplateCount);
    if (crv != CKR_OK) {
        goto loser;
    }

    /* allocate space for the attributes */
    for (i = 0; i < itemTemplateCount; i++) {
        template[i].pValue = PORT_ArenaAlloc(arena, template[i].ulValueLen);
        if (template[i].pValue == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
    }

    /* fetch the attributes */
    crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
                                   template, itemTemplateCount);
    if (crv != CKR_OK) {
        goto loser;
    }

    /* Fill in the items */
    for (i = 0; i < itemTemplateCount; i++) {
        itemTemplate[i].item->data = template[i].pValue;
        itemTemplate[i].item->len = template[i].ulValueLen;
    }

loser:
    if (template != templateSpace) {
        PORT_Free(template);
    }
    if (dbHandle) {
        sftk_freeDB(dbHandle);
    }

    return crv;
}

/*
 * delete an attribute from an object
 */
static void
sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute)
{
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL) {
        return;
    }
    PZ_Lock(sessObject->attributeLock);
    if (sftkqueue_is_queued(attribute, attribute->handle,
                            sessObject->head, sessObject->hashSize)) {
        sftkqueue_delete(attribute, attribute->handle,
                         sessObject->head, sessObject->hashSize);
    }
    PZ_Unlock(sessObject->attributeLock);
}

/*
 * this is only valid for CK_BBOOL type attributes. Return the state
 * of that attribute.
 */
PRBool
sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    PRBool tok = PR_FALSE;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL) {
        return PR_FALSE;
    }
    tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
    sftk_FreeAttribute(attribute);

    return tok;
}

/*
 * force an attribute to null.
 * this is for sensitive keys which are stored in the database, we don't
 * want to keep this info around in memory in the clear.
 */
void
sftk_nullAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return;

    if (attribute->attrib.pValue != NULL) {
        PORT_Memset(attribute->attrib.pValue, 0, attribute->attrib.ulValueLen);
        if (attribute->freeData) {
            PORT_Free(attribute->attrib.pValue);
        }
        attribute->freeData = PR_FALSE;
        attribute->attrib.pValue = NULL;
        attribute->attrib.ulValueLen = 0;
    }
    sftk_FreeAttribute(attribute);
}

static CK_RV
sftk_forceTokenAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                         const void *value, unsigned int len)
{
    CK_ATTRIBUTE attribute;
    SFTKDBHandle *dbHandle = NULL;
    SFTKTokenObject *to = sftk_narrowToTokenObject(object);
    CK_RV crv;

    PORT_Assert(to);
    if (to == NULL) {
        return CKR_DEVICE_ERROR;
    }

    dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);

    attribute.type = type;
    attribute.pValue = (void *)value;
    attribute.ulValueLen = len;

    crv = sftkdb_SetAttributeValue(dbHandle, object, &attribute, 1);
    sftk_freeDB(dbHandle);
    return crv;
}

/*
 * force an attribute to a specifc value.
 */
CK_RV
sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                    const void *value, unsigned int len)
{
    SFTKAttribute *attribute;
    void *att_val = NULL;
    PRBool freeData = PR_FALSE;

    PORT_Assert(object);
    PORT_Assert(object->refCount);
    PORT_Assert(object->slot);
    if (!object ||
        !object->refCount ||
        !object->slot) {
        return CKR_DEVICE_ERROR;
    }
    if (sftk_isToken(object->handle)) {
        return sftk_forceTokenAttribute(object, type, value, len);
    }
    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return sftk_AddAttributeType(object, type, value, len);

    if (value) {
        if (len <= ATTR_SPACE) {
            att_val = attribute->space;
        } else {
            att_val = PORT_Alloc(len);
            freeData = PR_TRUE;
        }
        if (att_val == NULL) {
            return CKR_HOST_MEMORY;
        }
        if (attribute->attrib.pValue == att_val) {
            PORT_Memset(attribute->attrib.pValue, 0,
                        attribute->attrib.ulValueLen);
        }
        PORT_Memcpy(att_val, value, len);
    }
    if (attribute->attrib.pValue != NULL) {
        if (attribute->attrib.pValue != att_val) {
            PORT_Memset(attribute->attrib.pValue, 0,
                        attribute->attrib.ulValueLen);
        }
        if (attribute->freeData) {
            PORT_Free(attribute->attrib.pValue);
        }
        attribute->freeData = PR_FALSE;
        attribute->attrib.pValue = NULL;
        attribute->attrib.ulValueLen = 0;
    }
    if (att_val) {
        attribute->attrib.pValue = att_val;
        attribute->attrib.ulValueLen = len;
        attribute->freeData = freeData;
    }
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

/*
 * return a null terminated string from attribute 'type'. This string
 * is allocated and needs to be freed with PORT_Free() When complete.
 */
char *
sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    char *label = NULL;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return NULL;

    if (attribute->attrib.pValue != NULL) {
        label = (char *)PORT_Alloc(attribute->attrib.ulValueLen + 1);
        if (label == NULL) {
            sftk_FreeAttribute(attribute);
            return NULL;
        }

        PORT_Memcpy(label, attribute->attrib.pValue,
                    attribute->attrib.ulValueLen);
        label[attribute->attrib.ulValueLen] = 0;
    }
    sftk_FreeAttribute(attribute);
    return label;
}

/*
 * decode when a particular attribute may be modified
 *  SFTK_NEVER: This attribute must be set at object creation time and
 *  can never be modified.
 *  SFTK_ONCOPY: This attribute may be modified only when you copy the
 *  object.
 *  SFTK_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
 *  CK_FALSE to CK_TRUE.
 *  SFTK_ALWAYS: This attribute can always be modified.
 * Some attributes vary their modification type based on the class of the
 *   object.
 */
SFTKModifyType
sftk_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
{
    /* if we don't know about it, user user defined, always allow modify */
    SFTKModifyType mtype = SFTK_ALWAYS;

    switch (type) {
        /* NEVER */
        case CKA_CLASS:
        case CKA_CERTIFICATE_TYPE:
        case CKA_KEY_TYPE:
        case CKA_MODULUS:
        case CKA_MODULUS_BITS:
        case CKA_PUBLIC_EXPONENT:
        case CKA_PRIVATE_EXPONENT:
        case CKA_PRIME:
        case CKA_BASE:
        case CKA_PRIME_1:
        case CKA_PRIME_2:
        case CKA_EXPONENT_1:
        case CKA_EXPONENT_2:
        case CKA_COEFFICIENT:
        case CKA_VALUE_LEN:
        case CKA_ALWAYS_SENSITIVE:
        case CKA_NEVER_EXTRACTABLE:
        case CKA_NSS_DB:
            mtype = SFTK_NEVER;
            break;

        /* ONCOPY */
        case CKA_TOKEN:
        case CKA_PRIVATE:
        case CKA_MODIFIABLE:
            mtype = SFTK_ONCOPY;
            break;

        /* SENSITIVE */
        case CKA_SENSITIVE:
        case CKA_EXTRACTABLE:
            mtype = SFTK_SENSITIVE;
            break;

        /* ALWAYS */
        case CKA_LABEL:
        case CKA_APPLICATION:
        case CKA_ID:
        case CKA_SERIAL_NUMBER:
        case CKA_START_DATE:
        case CKA_END_DATE:
        case CKA_DERIVE:
        case CKA_ENCRYPT:
        case CKA_DECRYPT:
        case CKA_SIGN:
        case CKA_VERIFY:
        case CKA_SIGN_RECOVER:
        case CKA_VERIFY_RECOVER:
        case CKA_WRAP:
        case CKA_UNWRAP:
            mtype = SFTK_ALWAYS;
            break;

        /* DEPENDS ON CLASS */
        case CKA_VALUE:
            mtype = (inClass == CKO_DATA) ? SFTK_ALWAYS : SFTK_NEVER;
            break;

        case CKA_SUBPRIME:
            /* allow the CKA_SUBPRIME to be added to dh private keys */
            mtype = (inClass == CKO_PRIVATE_KEY) ? SFTK_ALWAYS : SFTK_NEVER;
            break;

        case CKA_SUBJECT:
            mtype = (inClass == CKO_CERTIFICATE) ? SFTK_NEVER : SFTK_ALWAYS;
            break;
        default:
            break;
    }
    return mtype;
}

/* decode if a particular attribute is sensitive (cannot be read
 * back to the user of if the object is set to SENSITIVE) */
PRBool
sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
{
    switch (type) {
        /* ALWAYS */
        case CKA_PRIVATE_EXPONENT:
        case CKA_PRIME_1:
        case CKA_PRIME_2:
        case CKA_EXPONENT_1:
        case CKA_EXPONENT_2:
        case CKA_COEFFICIENT:
            return PR_TRUE;

        /* DEPENDS ON CLASS */
        case CKA_VALUE:
            /* PRIVATE and SECRET KEYS have SENSITIVE values */
            return (PRBool)((inClass == CKO_PRIVATE_KEY) || (inClass == CKO_SECRET_KEY));

        default:
            break;
    }
    return PR_FALSE;
}

/*
 * copy an attribute into a SECItem. Secitem is allocated in the specified
 * arena.
 */
CK_RV
sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, SFTKObject *object,
                       CK_ATTRIBUTE_TYPE type)
{
    int len;
    SFTKAttribute *attribute;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return CKR_TEMPLATE_INCOMPLETE;
    len = attribute->attrib.ulValueLen;

    if (arena) {
        item->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
    } else {
        item->data = (unsigned char *)PORT_Alloc(len);
    }
    if (item->data == NULL) {
        sftk_FreeAttribute(attribute);
        return CKR_HOST_MEMORY;
    }
    item->len = len;
    PORT_Memcpy(item->data, attribute->attrib.pValue, len);
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

CK_RV
sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                       CK_ULONG *longData)
{
    SFTKAttribute *attribute;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return CKR_TEMPLATE_INCOMPLETE;

    if (attribute->attrib.ulValueLen != sizeof(CK_ULONG)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    *longData = *(CK_ULONG *)attribute->attrib.pValue;
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

void
sftk_DeleteAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return;
    sftk_DeleteAttribute(object, attribute);
    sftk_DestroyAttribute(attribute);
}

CK_RV
sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                      const void *valPtr, CK_ULONG length)
{
    SFTKAttribute *attribute;
    attribute = sftk_NewAttribute(object, type, valPtr, length);
    if (attribute == NULL) {
        return CKR_HOST_MEMORY;
    }
    sftk_AddAttribute(object, attribute);
    return CKR_OK;
}

/*
 * ******************** Object Utilities *******************************
 */

/* must be called holding sftk_tokenKeyLock(slot) */
static SECItem *
sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
{
    return (SECItem *)PL_HashTableLookup(slot->tokObjHashTable, (void *)handle);
}

/*
 * use the refLock. This operations should be very rare, so the added
 * contention on the ref lock should be lower than the overhead of adding
 * a new lock. We use separate functions for this just in case I'm wrong.
 */
static void
sftk_tokenKeyLock(SFTKSlot *slot)
{
    SKIP_AFTER_FORK(PZ_Lock(slot->objectLock));
}

static void
sftk_tokenKeyUnlock(SFTKSlot *slot)
{
    SKIP_AFTER_FORK(PZ_Unlock(slot->objectLock));
}

static PRIntn
sftk_freeHashItem(PLHashEntry *entry, PRIntn index, void *arg)
{
    SECItem *item = (SECItem *)entry->value;

    SECITEM_FreeItem(item, PR_TRUE);
    return HT_ENUMERATE_NEXT;
}

CK_RV
SFTK_ClearTokenKeyHashTable(SFTKSlot *slot)
{
    sftk_tokenKeyLock(slot);
    PORT_Assert(!slot->present);
    PL_HashTableEnumerateEntries(slot->tokObjHashTable, sftk_freeHashItem, NULL);
    sftk_tokenKeyUnlock(slot);
    return CKR_OK;
}

/* allocation hooks that allow us to recycle old object structures */
static SFTKObjectFreeList sessionObjectList = { NULL, NULL, 0 };
static SFTKObjectFreeList tokenObjectList = { NULL, NULL, 0 };

SFTKObject *
sftk_GetObjectFromList(PRBool *hasLocks, PRBool optimizeSpace,
                       SFTKObjectFreeList *list, unsigned int hashSize, PRBool isSessionObject)
{
    SFTKObject *object;
    int size = 0;

    if (!optimizeSpace) {
        PZ_Lock(list->lock);
        object = list->head;
        if (object) {
            list->head = object->next;
            list->count--;
        }
        PZ_Unlock(list->lock);
        if (object) {
            object->next = object->prev = NULL;
            *hasLocks = PR_TRUE;
            return object;
        }
    }
    size = isSessionObject ? sizeof(SFTKSessionObject) + hashSize * sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject);

    object = (SFTKObject *)PORT_ZAlloc(size);
    if (isSessionObject && object) {
        ((SFTKSessionObject *)object)->hashSize = hashSize;
    }
    *hasLocks = PR_FALSE;
    return object;
}

static void
sftk_PutObjectToList(SFTKObject *object, SFTKObjectFreeList *list,
                     PRBool isSessionObject)
{

    /* the code below is equivalent to :
     *     optimizeSpace = isSessionObject ? object->optimizeSpace : PR_FALSE;
     * just faster.
     */
    PRBool optimizeSpace = isSessionObject &&
                           ((SFTKSessionObject *)object)->optimizeSpace;
    if (object->refLock && !optimizeSpace && (list->count < MAX_OBJECT_LIST_SIZE)) {
        PZ_Lock(list->lock);
        object->next = list->head;
        list->head = object;
        list->count++;
        PZ_Unlock(list->lock);
        return;
    }
    if (isSessionObject) {
        SFTKSessionObject *so = (SFTKSessionObject *)object;
        PZ_DestroyLock(so->attributeLock);
        so->attributeLock = NULL;
    }
    if (object->refLock) {
        PZ_DestroyLock(object->refLock);
        object->refLock = NULL;
    }
    PORT_Free(object);
}

static SFTKObject *
sftk_freeObjectData(SFTKObject *object)
{
    SFTKObject *next = object->next;

    PORT_Free(object);
    return next;
}

static void
sftk_InitFreeList(SFTKObjectFreeList *list)
{
    if (!list->lock) {
        list->lock = PZ_NewLock(nssILockObject);
    }
}

void
sftk_InitFreeLists(void)
{
    sftk_InitFreeList(&sessionObjectList);
    sftk_InitFreeList(&tokenObjectList);
}

static void
sftk_CleanupFreeList(SFTKObjectFreeList *list, PRBool isSessionList)
{
    SFTKObject *object;

    if (!list->lock) {
        return;
    }
    SKIP_AFTER_FORK(PZ_Lock(list->lock));
    for (object = list->head; object != NULL;
         object = sftk_freeObjectData(object)) {
        PZ_DestroyLock(object->refLock);
        if (isSessionList) {
            PZ_DestroyLock(((SFTKSessionObject *)object)->attributeLock);
        }
    }
    list->count = 0;
    list->head = NULL;
    SKIP_AFTER_FORK(PZ_Unlock(list->lock));
    SKIP_AFTER_FORK(PZ_DestroyLock(list->lock));
    list->lock = NULL;
}

void
sftk_CleanupFreeLists(void)
{
    sftk_CleanupFreeList(&sessionObjectList, PR_TRUE);
    sftk_CleanupFreeList(&tokenObjectList, PR_FALSE);
}

/*
 * Create a new object
 */
SFTKObject *
sftk_NewObject(SFTKSlot *slot)
{
    SFTKObject *object;
    SFTKSessionObject *sessObject;
    PRBool hasLocks = PR_FALSE;
    unsigned int i;
    unsigned int hashSize = 0;

    hashSize = (slot->optimizeSpace) ? SPACE_ATTRIBUTE_HASH_SIZE : TIME_ATTRIBUTE_HASH_SIZE;

    object = sftk_GetObjectFromList(&hasLocks, slot->optimizeSpace,
                                    &sessionObjectList, hashSize, PR_TRUE);
    if (object == NULL) {
        return NULL;
    }
    sessObject = (SFTKSessionObject *)object;
    sessObject->nextAttr = 0;

    for (i = 0; i < MAX_OBJS_ATTRS; i++) {
        sessObject->attrList[i].attrib.pValue = NULL;
        sessObject->attrList[i].freeData = PR_FALSE;
    }
    sessObject->optimizeSpace = slot->optimizeSpace;

    object->handle = 0;
    object->next = object->prev = NULL;
    object->slot = slot;
    object->isFIPS = sftk_isFIPS(slot->slotID);

    object->refCount = 1;
    sessObject->sessionList.next = NULL;
    sessObject->sessionList.prev = NULL;
    sessObject->sessionList.parent = object;
    sessObject->session = NULL;
    sessObject->wasDerived = PR_FALSE;
    if (!hasLocks)
        object->refLock = PZ_NewLock(nssILockRefLock);
    if (object->refLock == NULL) {
        PORT_Free(object);
        return NULL;
    }
    if (!hasLocks)
        sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
    if (sessObject->attributeLock == NULL) {
        PZ_DestroyLock(object->refLock);
        PORT_Free(object);
        return NULL;
    }
    for (i = 0; i < sessObject->hashSize; i++) {
        sessObject->head[i] = NULL;
    }
    object->objectInfo = NULL;
    object->infoFree = NULL;
    return object;
}

static CK_RV
sftk_DestroySessionObjectData(SFTKSessionObject *so)
{
    int i;

    for (i = 0; i < MAX_OBJS_ATTRS; i++) {
        unsigned char *value = so->attrList[i].attrib.pValue;
        if (value) {
            PORT_Memset(value, 0, so->attrList[i].attrib.ulValueLen);
            if (so->attrList[i].freeData) {
                PORT_Free(value);
            }
            so->attrList[i].attrib.pValue = NULL;
            so->attrList[i].freeData = PR_FALSE;
        }
    }
    /*  PZ_DestroyLock(so->attributeLock);*/
    return CKR_OK;
}

/*
 * free all the data associated with an object. Object reference count must
 * be 'zero'.
 */
static CK_RV
sftk_DestroyObject(SFTKObject *object)
{
    CK_RV crv = CKR_OK;
    SFTKSessionObject *so = sftk_narrowToSessionObject(object);
    SFTKTokenObject *to = sftk_narrowToTokenObject(object);

    PORT_Assert(object->refCount == 0);

    /* delete the database value */
    if (to) {
        if (to->dbKey.data) {
            PORT_Free(to->dbKey.data);
            to->dbKey.data = NULL;
        }
    }
    if (so) {
        sftk_DestroySessionObjectData(so);
    }
    if (object->objectInfo) {
        (*object->infoFree)(object->objectInfo);
        object->objectInfo = NULL;
        object->infoFree = NULL;
    }
    if (so) {
        sftk_PutObjectToList(object, &sessionObjectList, PR_TRUE);
    } else {
        sftk_PutObjectToList(object, &tokenObjectList, PR_FALSE);
    }
    return crv;
}

void
sftk_ReferenceObject(SFTKObject *object)
{
    PZ_Lock(object->refLock);
    object->refCount++;
    PZ_Unlock(object->refLock);
}

static SFTKObject *
sftk_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, SFTKSlot *slot)
{
    SFTKObject *object;
    PRUint32 index = sftk_hash(handle, slot->sessObjHashSize);

    if (sftk_isToken(handle)) {
        return sftk_NewTokenObject(slot, NULL, handle);
    }

    PZ_Lock(slot->objectLock);
    sftkqueue_find2(object, handle, index, slot->sessObjHashTable);
    if (object) {
        sftk_ReferenceObject(object);
    }
    PZ_Unlock(slot->objectLock);

    return (object);
}
/*
 * look up and object structure from a handle. OBJECT_Handles only make
 * sense in terms of a given session.  make a reference to that object
 * structure returned.
 */
SFTKObject *
sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session)
{
    SFTKSlot *slot = sftk_SlotFromSession(session);

    return sftk_ObjectFromHandleOnSlot(handle, slot);
}

/*
 * release a reference to an object handle
 */
SFTKFreeStatus
sftk_FreeObject(SFTKObject *object)
{
    PRBool destroy = PR_FALSE;
    CK_RV crv;

    PZ_Lock(object->refLock);
    if (object->refCount == 1)
        destroy = PR_TRUE;
    object->refCount--;
    PZ_Unlock(object->refLock);

    if (destroy) {
        crv = sftk_DestroyObject(object);
        if (crv != CKR_OK) {
            return SFTK_DestroyFailure;
        }
        return SFTK_Destroyed;
    }
    return SFTK_Busy;
}

/* find the next available object handle that isn't currently in use */
/* NOTE: This function could loop forever if we've exhausted all
 * 3^31-1 handles. This is highly unlikely (NSS has been running for
 * decades with this code) uless we start increasing the size of the
 * SFTK_TOKEN_MASK (which is just the high bit currently). */
CK_OBJECT_HANDLE
sftk_getNextHandle(SFTKSlot *slot)
{
    CK_OBJECT_HANDLE handle;
    SFTKObject *duplicateObject = NULL;
    do {
        PRUint32 wrappedAround;

        duplicateObject = NULL;
        PZ_Lock(slot->objectLock);
        wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK;
        handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK;
        if (!handle) /* don't allow zero handle */
            handle = NSC_MIN_SESSION_OBJECT_HANDLE;
        slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround;
        /* Is there already a session object with this handle? */
        if (wrappedAround) {
            sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable,
                           slot->sessObjHashSize);
        }
        PZ_Unlock(slot->objectLock);
    } while (duplicateObject != NULL);
    return handle;
}

/*
 * add an object to a slot and session queue. These two functions
 * adopt the object.
 */
void
sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object)
{
    PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
    sftkqueue_init_element(object);
    PZ_Lock(slot->objectLock);
    sftkqueue_add2(object, object->handle, index, slot->sessObjHashTable);
    PZ_Unlock(slot->objectLock);
}

void
sftk_AddObject(SFTKSession *session, SFTKObject *object)
{
    SFTKSlot *slot = sftk_SlotFromSession(session);
    SFTKSessionObject *so = sftk_narrowToSessionObject(object);

    if (so) {
        PZ_Lock(session->objectLock);
        sftkqueue_add(&so->sessionList, 0, session->objects, 0);
        so->session = session;
        PZ_Unlock(session->objectLock);
    }
    sftk_AddSlotObject(slot, object);
    sftk_ReferenceObject(object);
}

/*
 * delete an object from a slot and session queue
 */
CK_RV
sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
{
    SFTKSlot *slot = sftk_SlotFromSession(session);
    SFTKSessionObject *so = sftk_narrowToSessionObject(object);
    CK_RV crv = CKR_OK;
    PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);

    /* Handle Token case */
    if (so && so->session) {
        session = so->session;
        PZ_Lock(session->objectLock);
        sftkqueue_delete(&so->sessionList, 0, session->objects, 0);
        PZ_Unlock(session->objectLock);
        PZ_Lock(slot->objectLock);
        sftkqueue_delete2(object, object->handle, index, slot->sessObjHashTable);
        PZ_Unlock(slot->objectLock);
        sftkqueue_clear_deleted_element(object);
        sftk_FreeObject(object); /* free the reference owned by the queue */
    } else {
        SFTKDBHandle *handle = sftk_getDBForTokenObject(slot, object->handle);
#ifdef DEBUG
        SFTKTokenObject *to = sftk_narrowToTokenObject(object);
        PORT_Assert(to);
#endif
        crv = sftkdb_DestroyObject(handle, object->handle, object->objclass);
        sftk_freeDB(handle);
    }
    return crv;
}

/*
 * Token objects don't explicitly store their attributes, so we need to know
 * what attributes make up a particular token object before we can copy it.
 * below are the tables by object type.
 */
static const CK_ATTRIBUTE_TYPE commonAttrs[] = {
    CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_MODIFIABLE
};
static const CK_ULONG commonAttrsCount =
    sizeof(commonAttrs) / sizeof(commonAttrs[0]);

static const CK_ATTRIBUTE_TYPE commonKeyAttrs[] = {
    CKA_ID, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE, CKA_LOCAL, CKA_KEY_TYPE
};
static const CK_ULONG commonKeyAttrsCount =
    sizeof(commonKeyAttrs) / sizeof(commonKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE secretKeyAttrs[] = {
    CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN,
    CKA_VERIFY, CKA_WRAP, CKA_UNWRAP, CKA_VALUE
};
static const CK_ULONG secretKeyAttrsCount =
    sizeof(secretKeyAttrs) / sizeof(secretKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE commonPubKeyAttrs[] = {
    CKA_ENCRYPT, CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_WRAP, CKA_SUBJECT
};
static const CK_ULONG commonPubKeyAttrsCount =
    sizeof(commonPubKeyAttrs) / sizeof(commonPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE rsaPubKeyAttrs[] = {
    CKA_MODULUS, CKA_PUBLIC_EXPONENT
};
static const CK_ULONG rsaPubKeyAttrsCount =
    sizeof(rsaPubKeyAttrs) / sizeof(rsaPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dsaPubKeyAttrs[] = {
    CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dsaPubKeyAttrsCount =
    sizeof(dsaPubKeyAttrs) / sizeof(dsaPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = {
    CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dhPubKeyAttrsCount =
    sizeof(dhPubKeyAttrs) / sizeof(dhPubKeyAttrs[0]);
static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = {
    CKA_EC_PARAMS, CKA_EC_POINT
};
static const CK_ULONG ecPubKeyAttrsCount =
    sizeof(ecPubKeyAttrs) / sizeof(ecPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = {
    CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT,
    CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NSS_DB, CKA_PUBLIC_KEY_INFO
};
static const CK_ULONG commonPrivKeyAttrsCount =
    sizeof(commonPrivKeyAttrs) / sizeof(commonPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE rsaPrivKeyAttrs[] = {
    CKA_MODULUS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
    CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT
};
static const CK_ULONG rsaPrivKeyAttrsCount =
    sizeof(rsaPrivKeyAttrs) / sizeof(rsaPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dsaPrivKeyAttrs[] = {
    CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dsaPrivKeyAttrsCount =
    sizeof(dsaPrivKeyAttrs) / sizeof(dsaPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = {
    CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dhPrivKeyAttrsCount =
    sizeof(dhPrivKeyAttrs) / sizeof(dhPrivKeyAttrs[0]);
static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = {
    CKA_EC_PARAMS, CKA_VALUE
};
static const CK_ULONG ecPrivKeyAttrsCount =
    sizeof(ecPrivKeyAttrs) / sizeof(ecPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE certAttrs[] = {
    CKA_CERTIFICATE_TYPE, CKA_VALUE, CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER
};
static const CK_ULONG certAttrsCount =
    sizeof(certAttrs) / sizeof(certAttrs[0]);

static const CK_ATTRIBUTE_TYPE trustAttrs[] = {
    CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
    CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_EMAIL_PROTECTION,
    CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED
};
static const CK_ULONG trustAttrsCount =
    sizeof(trustAttrs) / sizeof(trustAttrs[0]);

static const CK_ATTRIBUTE_TYPE smimeAttrs[] = {
    CKA_SUBJECT, CKA_NSS_EMAIL, CKA_NSS_SMIME_TIMESTAMP, CKA_VALUE
};
static const CK_ULONG smimeAttrsCount =
    sizeof(smimeAttrs) / sizeof(smimeAttrs[0]);

static const CK_ATTRIBUTE_TYPE crlAttrs[] = {
    CKA_SUBJECT, CKA_VALUE, CKA_NSS_URL, CKA_NSS_KRL
};
static const CK_ULONG crlAttrsCount =
    sizeof(crlAttrs) / sizeof(crlAttrs[0]);

/* copy an object based on it's table */
CK_RV
stfk_CopyTokenAttributes(SFTKObject *destObject, SFTKTokenObject *src_to,
                         const CK_ATTRIBUTE_TYPE *attrArray, CK_ULONG attrCount)
{
    SFTKAttribute *attribute;
    SFTKAttribute *newAttribute;
    CK_RV crv = CKR_OK;
    unsigned int i;

    for (i = 0; i < attrCount; i++) {
        if (!sftk_hasAttribute(destObject, attrArray[i])) {
            attribute = sftk_FindAttribute(&src_to->obj, attrArray[i]);
            if (!attribute) {
                continue; /* return CKR_ATTRIBUTE_VALUE_INVALID; */
            }
            /* we need to copy the attribute since each attribute
             * only has one set of link list pointers */
            newAttribute = sftk_NewAttribute(destObject,
                                             sftk_attr_expand(&attribute->attrib));
            sftk_FreeAttribute(attribute); /* free the old attribute */
            if (!newAttribute) {
                return CKR_HOST_MEMORY;
            }
            sftk_AddAttribute(destObject, newAttribute);
        }
    }
    return crv;
}

CK_RV
stfk_CopyTokenPrivateKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
    CK_RV crv;
    CK_KEY_TYPE key_type;
    SFTKAttribute *attribute;

    /* copy the common attributes for all keys first */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
                                   commonKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    /* copy the common attributes for all private keys next */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs,
                                   commonPrivKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    attribute = sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
    PORT_Assert(attribute); /* if it wasn't here, ww should have failed
                 * copying the common attributes */
    if (!attribute) {
        /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
         * the fact is, the only reason we couldn't get the attribute would
         * be a memory error or database error (an error in the 'device').
         * if we have a database error code, we could return it here */
        crv = CKR_DEVICE_ERROR;
        goto fail;
    }
    key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
    sftk_FreeAttribute(attribute);

    /* finally copy the attributes for various private key types */
    switch (key_type) {
        case CKK_RSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPrivKeyAttrs,
                                           rsaPrivKeyAttrsCount);
            break;
        case CKK_DSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPrivKeyAttrs,
                                           dsaPrivKeyAttrsCount);
            break;
        case CKK_DH:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs,
                                           dhPrivKeyAttrsCount);
            break;
        case CKK_EC:
            crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs,
                                           ecPrivKeyAttrsCount);
            break;
        default:
            crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
                                     * of token keys into our database. */
    }
fail:
    return crv;
}

CK_RV
stfk_CopyTokenPublicKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
    CK_RV crv;
    CK_KEY_TYPE key_type;
    SFTKAttribute *attribute;

    /* copy the common attributes for all keys first */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
                                   commonKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }

    /* copy the common attributes for all public keys next */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonPubKeyAttrs,
                                   commonPubKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    attribute = sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
    PORT_Assert(attribute); /* if it wasn't here, ww should have failed
                 * copying the common attributes */
    if (!attribute) {
        /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
         * the fact is, the only reason we couldn't get the attribute would
         * be a memory error or database error (an error in the 'device').
         * if we have a database error code, we could return it here */
        crv = CKR_DEVICE_ERROR;
        goto fail;
    }
    key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
    sftk_FreeAttribute(attribute);

    /* finally copy the attributes for various public key types */
    switch (key_type) {
        case CKK_RSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPubKeyAttrs,
                                           rsaPubKeyAttrsCount);
            break;
        case CKK_DSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPubKeyAttrs,
                                           dsaPubKeyAttrsCount);
            break;
        case CKK_DH:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs,
                                           dhPubKeyAttrsCount);
            break;
        case CKK_EC:
            crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs,
                                           ecPubKeyAttrsCount);
            break;
        default:
            crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
                                     * of token keys into our database. */
    }
fail:
    return crv;
}
CK_RV
stfk_CopyTokenSecretKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
    CK_RV crv;
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
                                   commonKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    crv = stfk_CopyTokenAttributes(destObject, src_to, secretKeyAttrs,
                                   secretKeyAttrsCount);
fail:
    return crv;
}

/*
 * Copy a token object. We need to explicitly copy the relevant
 * attributes since token objects don't store those attributes in
 * the token itself.
 */
CK_RV
sftk_CopyTokenObject(SFTKObject *destObject, SFTKObject *srcObject)
{
    SFTKTokenObject *src_to = sftk_narrowToTokenObject(srcObject);
    CK_RV crv;

    PORT_Assert(src_to);
    if (src_to == NULL) {
        return CKR_DEVICE_ERROR; /* internal state inconsistant */
    }

    crv = stfk_CopyTokenAttributes(destObject, src_to, commonAttrs,
                                   commonAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    switch (src_to->obj.objclass) {
        case CKO_CERTIFICATE:
            crv = stfk_CopyTokenAttributes(destObject, src_to, certAttrs,
                                           certAttrsCount);
            break;
        case CKO_NSS_TRUST:
            crv = stfk_CopyTokenAttributes(destObject, src_to, trustAttrs,
                                           trustAttrsCount);
            break;
        case CKO_NSS_SMIME:
            crv = stfk_CopyTokenAttributes(destObject, src_to, smimeAttrs,
                                           smimeAttrsCount);
            break;
        case CKO_NSS_CRL:
            crv = stfk_CopyTokenAttributes(destObject, src_to, crlAttrs,
                                           crlAttrsCount);
            break;
        case CKO_PRIVATE_KEY:
            crv = stfk_CopyTokenPrivateKey(destObject, src_to);
            break;
        case CKO_PUBLIC_KEY:
            crv = stfk_CopyTokenPublicKey(destObject, src_to);
            break;
        case CKO_SECRET_KEY:
            crv = stfk_CopyTokenSecretKey(destObject, src_to);
            break;
        default:
            crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
                                     * of token keys into our database. */
    }
fail:
    return crv;
}

/*
 * copy the attributes from one object to another. Don't overwrite existing
 * attributes. NOTE: This is a pretty expensive operation since it
 * grabs the attribute locks for the src object for a *long* time.
 */
CK_RV
sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject)
{
    SFTKAttribute *attribute;
    SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject);
    unsigned int i;

    destObject->isFIPS = srcObject->isFIPS;
    if (src_so == NULL) {
        return sftk_CopyTokenObject(destObject, srcObject);
    }

    PZ_Lock(src_so->attributeLock);
    for (i = 0; i < src_so->hashSize; i++) {
        attribute = src_so->head[i];
        do {
            if (attribute) {
                if (!sftk_hasAttribute(destObject, attribute->handle)) {
                    /* we need to copy the attribute since each attribute
                     * only has one set of link list pointers */
                    SFTKAttribute *newAttribute = sftk_NewAttribute(
                        destObject, sftk_attr_expand(&attribute->attrib));
                    if (newAttribute == NULL) {
                        PZ_Unlock(src_so->attributeLock);
                        return CKR_HOST_MEMORY;
                    }
                    sftk_AddAttribute(destObject, newAttribute);
                }
                attribute = attribute->next;
            }
        } while (attribute != NULL);
    }
    PZ_Unlock(src_so->attributeLock);

    return CKR_OK;
}

/*
 * ******************** Search Utilities *******************************
 */

/* add an object to a search list */
CK_RV
AddToList(SFTKObjectListElement **list, SFTKObject *object)
{
    SFTKObjectListElement *newElem =
        (SFTKObjectListElement *)PORT_Alloc(sizeof(SFTKObjectListElement));

    if (newElem == NULL)
        return CKR_HOST_MEMORY;

    newElem->next = *list;
    newElem->object = object;
    sftk_ReferenceObject(object);

    *list = newElem;
    return CKR_OK;
}

/* return true if the object matches the template */
PRBool
sftk_objectMatch(SFTKObject *object, CK_ATTRIBUTE_PTR theTemplate, int count)
{
    int i;

    for (i = 0; i < count; i++) {
        SFTKAttribute *attribute = sftk_FindAttribute(object, theTemplate[i].type);
        if (attribute == NULL) {
            return PR_FALSE;
        }
        if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) {
            if (PORT_Memcmp(attribute->attrib.pValue, theTemplate[i].pValue,
                            theTemplate[i].ulValueLen) == 0) {
                sftk_FreeAttribute(attribute);
                continue;
            }
        }
        sftk_FreeAttribute(attribute);
        return PR_FALSE;
    }
    return PR_TRUE;
}

/* search through all the objects in the queue and return the template matches
 * in the object list.
 */
CK_RV
sftk_searchObjectList(SFTKSearchResults *search, SFTKObject **head,
                      unsigned int size, PZLock *lock, CK_ATTRIBUTE_PTR theTemplate,
                      int count, PRBool isLoggedIn)
{
    unsigned int i;
    SFTKObject *object;
    CK_RV crv = CKR_OK;

    PZ_Lock(lock);
    for (i = 0; i < size; i++) {
        for (object = head[i]; object != NULL; object = object->next) {
            if (sftk_objectMatch(object, theTemplate, count)) {
                /* don't return objects that aren't yet visible */
                if ((!isLoggedIn) && sftk_isTrue(object, CKA_PRIVATE))
                    continue;
                sftk_addHandle(search, object->handle);
            }
        }
    }
    PZ_Unlock(lock);
    return crv;
}

/*
 * free a single list element. Return the Next object in the list.
 */
SFTKObjectListElement *
sftk_FreeObjectListElement(SFTKObjectListElement *objectList)
{
    SFTKObjectListElement *ol = objectList->next;

    sftk_FreeObject(objectList->object);
    PORT_Free(objectList);
    return ol;
}

/* free an entire object list */
void
sftk_FreeObjectList(SFTKObjectListElement *objectList)
{
    SFTKObjectListElement *ol;

    for (ol = objectList; ol != NULL; ol = sftk_FreeObjectListElement(ol)) {
    }
}

/*
 * free a search structure
 */
void
sftk_FreeSearch(SFTKSearchResults *search)
{
    if (search->handles) {
        PORT_Free(search->handles);
    }
    PORT_Free(search);
}

/*
 * ******************** Session Utilities *******************************
 */

/* update the sessions state based in it's flags and wether or not it's
 * logged in */
void
sftk_update_state(SFTKSlot *slot, SFTKSession *session)
{
    if (slot->isLoggedIn) {
        if (slot->ssoLoggedIn) {
            session->info.state = CKS_RW_SO_FUNCTIONS;
        } else if (session->info.flags & CKF_RW_SESSION) {
            session->info.state = CKS_RW_USER_FUNCTIONS;
        } else {
            session->info.state = CKS_RO_USER_FUNCTIONS;
        }
    } else {
        if (session->info.flags & CKF_RW_SESSION) {
            session->info.state = CKS_RW_PUBLIC_SESSION;
        } else {
            session->info.state = CKS_RO_PUBLIC_SESSION;
        }
    }
}

/* update the state of all the sessions on a slot */
void
sftk_update_all_states(SFTKSlot *slot)
{
    unsigned int i;
    SFTKSession *session;

    for (i = 0; i < slot->sessHashSize; i++) {
        PZLock *lock = SFTK_SESSION_LOCK(slot, i);
        PZ_Lock(lock);
        for (session = slot->head[i]; session; session = session->next) {
            sftk_update_state(slot, session);
        }
        PZ_Unlock(lock);
    }
}

/*
 * context are cipher and digest contexts that are associated with a session
 */
void
sftk_FreeContext(SFTKSessionContext *context)
{
    if (context->cipherInfo) {
        (*context->destroy)(context->cipherInfo, PR_TRUE);
    }
    if (context->hashInfo) {
        (*context->hashdestroy)(context->hashInfo, PR_TRUE);
    }
    if (context->key) {
        sftk_FreeObject(context->key);
        context->key = NULL;
    }
    PORT_Free(context);
}

/*
 * Init a new session. NOTE: The session handle is not set, and the
 * session is not added to the slot's session queue.
 */
CK_RV
sftk_InitSession(SFTKSession *session, SFTKSlot *slot, CK_SLOT_ID slotID,
                 CK_NOTIFY notify, CK_VOID_PTR pApplication, CK_FLAGS flags)
{
    session->next = session->prev = NULL;
    session->enc_context = NULL;
    session->hash_context = NULL;
    session->sign_context = NULL;
    session->search = NULL;
    session->objectIDCount = 1;
    session->objectLock = PZ_NewLock(nssILockObject);
    if (session->objectLock == NULL) {
        return CKR_HOST_MEMORY;
    }
    session->objects[0] = NULL;

    session->slot = slot;
    session->notify = notify;
    session->appData = pApplication;
    session->info.flags = flags;
    session->info.slotID = slotID;
    session->info.ulDeviceError = 0;
    sftk_update_state(slot, session);
    /* no ops completed yet, so the last one couldn't be a FIPS op */
    session->lastOpWasFIPS = PR_FALSE;
    return CKR_OK;
}

/*
 * Create a new session and init it.
 */
SFTKSession *
sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
                CK_FLAGS flags)
{
    SFTKSession *session;
    SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
    CK_RV crv;

    if (slot == NULL)
        return NULL;

    session = (SFTKSession *)PORT_Alloc(sizeof(SFTKSession));
    if (session == NULL)
        return NULL;

    crv = sftk_InitSession(session, slot, slotID, notify, pApplication, flags);
    if (crv != CKR_OK) {
        PORT_Free(session);
        return NULL;
    }
    return session;
}

/* free all the data associated with a session. */
void
sftk_ClearSession(SFTKSession *session)
{
    SFTKObjectList *op, *next;

    /* clean out the attributes */
    /* since no one is referencing us, it's safe to walk the chain
     * without a lock */
    for (op = session->objects[0]; op != NULL; op = next) {
        next = op->next;
        /* paranoia */
        op->next = op->prev = NULL;
        sftk_DeleteObject(session, op->parent);
    }
    PZ_DestroyLock(session->objectLock);
    if (session->enc_context) {
        sftk_FreeContext(session->enc_context);
    }
    if (session->hash_context) {
        sftk_FreeContext(session->hash_context);
    }
    if (session->sign_context) {
        sftk_FreeContext(session->sign_context);
    }
    if (session->search) {
        sftk_FreeSearch(session->search);
    }
}

/* free the data associated with the session, and the session */
void
sftk_DestroySession(SFTKSession *session)
{
    sftk_ClearSession(session);
    PORT_Free(session);
}

/*
 * look up a session structure from a session handle
 * generate a reference to it.
 */
SFTKSession *
sftk_SessionFromHandle(CK_SESSION_HANDLE handle)
{
    SFTKSlot *slot = sftk_SlotFromSessionHandle(handle);
    SFTKSession *session;
    PZLock *lock;

    if (!slot)
        return NULL;
    lock = SFTK_SESSION_LOCK(slot, handle);

    PZ_Lock(lock);
    sftkqueue_find(session, handle, slot->head, slot->sessHashSize);
    PZ_Unlock(lock);

    return (session);
}

/*
 * release a reference to a session handle. This method of using SFTKSessions
 * is deprecated, but the pattern should be retained until a future effort
 * to refactor all SFTKSession users at once is completed.
 */
void
sftk_FreeSession(SFTKSession *session)
{
    return;
}

void
sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle)
{
    if (search->handles == NULL) {
        return;
    }
    if (search->size >= search->array_size) {
        search->array_size += NSC_SEARCH_BLOCK_SIZE;
        search->handles = (CK_OBJECT_HANDLE *)PORT_Realloc(search->handles,
                                                           sizeof(CK_OBJECT_HANDLE) * search->array_size);
        if (search->handles == NULL) {
            return;
        }
    }
    search->handles[search->size] = handle;
    search->size++;
}

static CK_RV
handleToClass(SFTKSlot *slot, CK_OBJECT_HANDLE handle,
              CK_OBJECT_CLASS *objClass)
{
    SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, handle);
    CK_ATTRIBUTE objClassTemplate;
    CK_RV crv;

    *objClass = CKO_DATA;
    objClassTemplate.type = CKA_CLASS;
    objClassTemplate.pValue = objClass;
    objClassTemplate.ulValueLen = sizeof(*objClass);
    crv = sftkdb_GetAttributeValue(dbHandle, handle, &objClassTemplate, 1);
    sftk_freeDB(dbHandle);
    return crv;
}

SFTKObject *
sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
{
    SFTKObject *object = NULL;
    PRBool hasLocks = PR_FALSE;
    CK_RV crv;

    object = sftk_GetObjectFromList(&hasLocks, PR_FALSE, &tokenObjectList, 0,
                                    PR_FALSE);
    if (object == NULL) {
        return NULL;
    }

    object->handle = handle;
    /* every object must have a class, if we can't get it, the object
     * doesn't exist */
    crv = handleToClass(slot, handle, &object->objclass);
    if (crv != CKR_OK) {
        goto loser;
    }
    object->slot = slot;
    object->isFIPS = sftk_isFIPS(slot->slotID);
    object->objectInfo = NULL;
    object->infoFree = NULL;
    if (!hasLocks) {
        object->refLock = PZ_NewLock(nssILockRefLock);
    }
    if (object->refLock == NULL) {
        goto loser;
    }
    object->refCount = 1;

    return object;
loser:
    (void)sftk_DestroyObject(object);
    return NULL;
}

SFTKTokenObject *
sftk_convertSessionToToken(SFTKObject *obj)
{
    SECItem *key;
    SFTKSessionObject *so = (SFTKSessionObject *)obj;
    SFTKTokenObject *to = sftk_narrowToTokenObject(obj);
    SECStatus rv;

    sftk_DestroySessionObjectData(so);
    PZ_DestroyLock(so->attributeLock);
    if (to == NULL) {
        return NULL;
    }
    sftk_tokenKeyLock(so->obj.slot);
    key = sftk_lookupTokenKeyByHandle(so->obj.slot, so->obj.handle);
    if (key == NULL) {
        sftk_tokenKeyUnlock(so->obj.slot);
        return NULL;
    }
    rv = SECITEM_CopyItem(NULL, &to->dbKey, key);
    sftk_tokenKeyUnlock(so->obj.slot);
    if (rv == SECFailure) {
        return NULL;
    }

    return to;
}

SFTKSessionObject *
sftk_narrowToSessionObject(SFTKObject *obj)
{
    return !sftk_isToken(obj->handle) ? (SFTKSessionObject *)obj : NULL;
}

SFTKTokenObject *
sftk_narrowToTokenObject(SFTKObject *obj)
{
    return sftk_isToken(obj->handle) ? (SFTKTokenObject *)obj : NULL;
}

/* Constant time helper functions */

/* sftk_CKRVToMask returns, in constant time, a mask value of
 * all ones if rv == CKR_OK.  Otherwise it returns zero. */
unsigned int
sftk_CKRVToMask(CK_RV rv)
{
    PR_STATIC_ASSERT(CKR_OK == 0);
    return ~PORT_CT_NOT_ZERO(rv);
}

/* sftk_CheckCBCPadding checks, in constant time, the padding validity and
 * accordingly sets the pad length. */
CK_RV
sftk_CheckCBCPadding(CK_BYTE_PTR pBuf, unsigned int bufLen,
                     unsigned int blockSize, unsigned int *outPadSize)
{
    PORT_Assert(outPadSize);

    unsigned int padSize = (unsigned int)pBuf[bufLen - 1];

    /* If padSize <= blockSize, set goodPad to all-1s and all-0s otherwise.*/
    unsigned int goodPad = PORT_CT_DUPLICATE_MSB_TO_ALL(~(blockSize - padSize));
    /* padSize should not be 0 */
    goodPad &= PORT_CT_NOT_ZERO(padSize);

    unsigned int i;
    for (i = 0; i < blockSize; i++) {
        /* If i < padSize, set loopMask to all-1s and all-0s otherwise.*/
        unsigned int loopMask = PORT_CT_DUPLICATE_MSB_TO_ALL(~(padSize - 1 - i));
        /* Get the padding value (should be padSize) from buffer */
        unsigned int padVal = pBuf[bufLen - 1 - i];
        /* Update goodPad only if i < padSize */
        goodPad &= PORT_CT_SEL(loopMask, ~(padVal ^ padSize), goodPad);
    }

    /* If any of the final padding bytes had the wrong value, one or more
     * of the lower eight bits of |goodPad| will be cleared. We AND the
     * bottom 8 bits together and duplicate the result to all the bits. */
    goodPad &= goodPad >> 4;
    goodPad &= goodPad >> 2;
    goodPad &= goodPad >> 1;
    goodPad <<= sizeof(goodPad) * 8 - 1;
    goodPad = PORT_CT_DUPLICATE_MSB_TO_ALL(goodPad);

    /* Set outPadSize to padSize or 0 */
    *outPadSize = PORT_CT_SEL(goodPad, padSize, 0);
    /* Return OK if the pad is valid */
    return PORT_CT_SEL(goodPad, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
}

void
sftk_EncodeInteger(PRUint64 integer, CK_ULONG num_bits, CK_BBOOL littleEndian,
                   CK_BYTE_PTR output, CK_ULONG_PTR output_len)
{
    if (output_len) {
        *output_len = (num_bits / 8);
    }

    PR_ASSERT(num_bits > 0 && num_bits <= 64 && (num_bits % 8) == 0);

    if (littleEndian == CK_TRUE) {
        for (size_t offset = 0; offset < num_bits / 8; offset++) {
            output[offset] = (unsigned char)((integer >> (offset * 8)) & 0xFF);
        }
    } else {
        for (size_t offset = 0; offset < num_bits / 8; offset++) {
            PRUint64 shift = num_bits - (offset + 1) * 8;
            output[offset] = (unsigned char)((integer >> shift) & 0xFF);
        }
    }
}

CK_FLAGS
sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE op)
{
    CK_FLAGS flags = 0;

    switch (op) {
        case CKA_ENCRYPT:
            flags = CKF_ENCRYPT;
            break;
        case CKA_DECRYPT:
            flags = CKF_DECRYPT;
            break;
        case CKA_WRAP:
            flags = CKF_WRAP;
            break;
        case CKA_UNWRAP:
            flags = CKF_UNWRAP;
            break;
        case CKA_SIGN:
            flags = CKF_SIGN;
            break;
        case CKA_SIGN_RECOVER:
            flags = CKF_SIGN_RECOVER;
            break;
        case CKA_VERIFY:
            flags = CKF_VERIFY;
            break;
        case CKA_VERIFY_RECOVER:
            flags = CKF_VERIFY_RECOVER;
            break;
        case CKA_DERIVE:
            flags = CKF_DERIVE;
            break;
        /* fake attribute to select digesting */
        case CKA_DIGEST:
            flags = CKF_DIGEST;
            break;
        case CKA_NSS_MESSAGE | CKA_ENCRYPT:
            flags = CKF_MESSAGE_ENCRYPT;
            break;
        case CKA_NSS_MESSAGE | CKA_DECRYPT:
            flags = CKF_MESSAGE_DECRYPT;
            break;
        case CKA_NSS_MESSAGE | CKA_SIGN:
            flags = CKF_MESSAGE_SIGN;
            break;
        case CKA_NSS_MESSAGE | CKA_VERIFY:
            flags = CKF_MESSAGE_VERIFY;
            break;
        default:
            break;
    }
    return flags;
}

#ifdef NSS_HAS_FIPS_INDICATORS
/* sigh, we probably need a version of this in secutil so that both
 * softoken and NSS can use it */
static SECOidTag
sftk_quickGetECCCurveOid(SFTKObject *source)
{
    SFTKAttribute *attribute = sftk_FindAttribute(source, CKA_EC_PARAMS);
    unsigned char *encoded;
    int len;
    SECItem oid;
    SECOidTag tag;

    if (attribute == NULL) {
        return SEC_OID_UNKNOWN;
    }
    encoded = attribute->attrib.pValue;
    len = attribute->attrib.ulValueLen;
    if ((len < 2) || (encoded[0] != SEC_ASN1_OBJECT_ID) ||
        (len != encoded[1] + 2)) {
        sftk_FreeAttribute(attribute);
        return SEC_OID_UNKNOWN;
    }
    oid.data = encoded + 2;
    oid.len = len - 2;
    tag = SECOID_FindOIDTag(&oid);
    sftk_FreeAttribute(attribute);
    return tag;
}

/* This function currently only returns valid lengths for
 * FIPS approved ECC curves. If we want to make this generic
 * in the future, that Curve determination can be done in
 * the sftk_handleSpecial. Since it's currently only used
 * in FIPS indicators, it's currently only compiled with
 * the FIPS indicator code */
static int
sftk_getKeyLength(SFTKObject *source)
{
    CK_KEY_TYPE keyType = CK_INVALID_HANDLE;
    CK_ATTRIBUTE_TYPE keyAttribute;
    CK_ULONG keyLength = 0;
    SFTKAttribute *attribute;
    CK_RV crv;

    /* If we don't have a key, then it doesn't have a length.
     * this may be OK (say we are hashing). The mech info will
     * sort this out because algorithms which expect no keys
     * will accept zero length for the keys */
    if (source == NULL) {
        return 0;
    }

    crv = sftk_GetULongAttribute(source, CKA_KEY_TYPE, &keyType);
    if (crv != CKR_OK) {
        /* sometimes we're passed a data object, in that case the
         * key length is CKA_VALUE, which is the default */
        keyType = CKK_INVALID_KEY_TYPE;
    }
    if (keyType == CKK_EC) {
        SECOidTag curve = sftk_quickGetECCCurveOid(source);
        switch (curve) {
            case SEC_OID_CURVE25519:
                /* change when we start algorithm testing on curve25519 */
                return 0;
            case SEC_OID_SECG_EC_SECP256R1:
                return 256;
            case SEC_OID_SECG_EC_SECP384R1:
                return 384;
            case SEC_OID_SECG_EC_SECP521R1:
                /* this is a lie, but it makes the table easier. We don't
                 * have to have a double entry for every ECC mechanism */
                return 512;
            default:
                break;
        }
        /* other curves aren't NIST approved, returning 0 will cause these
         * curves to fail FIPS length criteria */
        return 0;
    }

    switch (keyType) {
        case CKK_RSA:
            keyAttribute = CKA_MODULUS;
            break;
        case CKK_DSA:
        case CKK_DH:
            keyAttribute = CKA_PRIME;
            break;
        default:
            keyAttribute = CKA_VALUE;
            break;
    }
    attribute = sftk_FindAttribute(source, keyAttribute);
    if (attribute) {
        keyLength = attribute->attrib.ulValueLen * 8;
        sftk_FreeAttribute(attribute);
    }
    return keyLength;
}

/*
 * handle specialized FIPS semantics that are too complicated to
 * handle with just a table. NOTE: this means any additional semantics
 * would have to be coded here before they can be added to the table */
static PRBool
sftk_handleSpecial(SFTKSlot *slot, CK_MECHANISM *mech,
                   SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source)
{
    switch (mechInfo->special) {
        case SFTKFIPSDH: {
            SECItem dhPrime;
            const SECItem *dhSubPrime;
            CK_RV crv = sftk_Attribute2SecItem(NULL, &dhPrime,
                                               source, CKA_PRIME);
            if (crv != CKR_OK) {
                return PR_FALSE;
            }
            dhSubPrime = sftk_VerifyDH_Prime(&dhPrime, PR_TRUE);
            SECITEM_ZfreeItem(&dhPrime, PR_FALSE);
            return (dhSubPrime) ? PR_TRUE : PR_FALSE;
        }
        case SFTKFIPSNone:
            return PR_FALSE;
        case SFTKFIPSECC:
            /* we've already handled the curve selection in the 'getlength'
          * function */
            return PR_TRUE;
        case SFTKFIPSAEAD: {
            if (mech->ulParameterLen == 0) {
                /* AEAD ciphers are only in FIPS mode if we are using the
                 * MESSAGE interface. This takes an empty parameter
                 * in the init function */
                return PR_TRUE;
            }
            return PR_FALSE;
        }
        default:
            break;
    }
    /* if we didn't understand the special processing, mark it non-fips */
    return PR_FALSE;
}
#endif

PRBool
sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, CK_ATTRIBUTE_TYPE op,
                     SFTKObject *source)
{
#ifndef NSS_HAS_FIPS_INDICATORS
    return PR_FALSE;
#else
    int i;
    CK_FLAGS opFlags;
    CK_ULONG keyLength;

    /* handle all the quick stuff first */
    if (!sftk_isFIPS(slot->slotID)) {
        return PR_FALSE;
    }
    if (source && !source->isFIPS) {
        return PR_FALSE;
    }
    if (mech == NULL) {
        return PR_FALSE;
    }

    /* now get the calculated values */
    opFlags = sftk_AttributeToFlags(op);
    if (opFlags == 0) {
        return PR_FALSE;
    }
    keyLength = sftk_getKeyLength(source);

    /* check against our algorithm array */
    for (i = 0; i < SFTK_NUMBER_FIPS_ALGORITHMS; i++) {
        SFTKFIPSAlgorithmList *mechs = &sftk_fips_mechs[i];
        /* if we match the number of records exactly, then we are an
         * approved algorithm in the approved mode with an approved key */
        if (((mech->mechanism == mechs->type) &&
             (opFlags == (mechs->info.flags & opFlags)) &&
             (keyLength <= mechs->info.ulMaxKeySize) &&
             (keyLength >= mechs->info.ulMinKeySize) &&
             ((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) &&
            ((mechs->special == SFTKFIPSNone) ||
             sftk_handleSpecial(slot, mech, mechs, source))) {
            return PR_TRUE;
        }
    }
    return PR_FALSE;
#endif
}

/*
 * create the FIPS Validation objects. If the vendor
 * doesn't supply an NSS_FIPS_MODULE_ID, at compile time,
 * then we assumethis is an unvalidated module.
 */
CK_RV
sftk_CreateValidationObjects(SFTKSlot *slot)
{
    const char *module_id;
    int module_id_len;
    CK_RV crv = CKR_OK;
    /* we currently use vendor specific values until the validation
     * objects are approved for PKCS #11 v3.2. */
    CK_OBJECT_CLASS cko_validation = CKO_NSS_VALIDATION;
    CK_NSS_VALIDATION_TYPE ckv_fips = CKV_NSS_FIPS_140;
    CK_VERSION fips_version = { 3, 0 }; /* FIPS-140-3 */
    CK_ULONG fips_level = 1;            /* or 2 if you validated at level 2 */

#ifndef NSS_FIPS_MODULE_ID
#define NSS_FIPS_MODULE_ID "Generic NSS " SOFTOKEN_VERSION " Unvalidated"
#endif
    module_id = NSS_FIPS_MODULE_ID;
    module_id_len = sizeof(NSS_FIPS_MODULE_ID) - 1;
    SFTKObject *object;

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

    crv = sftk_AddAttributeType(object, CKA_CLASS,
                                &cko_validation, sizeof(cko_validation));
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_TYPE,
                                &ckv_fips, sizeof(ckv_fips));
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_VERSION,
                                &fips_version, sizeof(fips_version));
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_LEVEL,
                                &fips_level, sizeof(fips_level));
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_MODULE_ID,
                                module_id, module_id_len);
    if (crv != CKR_OK) {
        goto loser;
    }

    /* future, fill in validation certificate information from a supplied
     * pointer to a config file */
    object->handle = sftk_getNextHandle(slot);
    object->slot = slot;
    sftk_AddObject(&slot->moduleObjects, object);
loser:
    sftk_FreeObject(object);
    return crv;
}
