/* 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 data structures and functions used by pkcs11.c */ #ifndef _PKCS11I_H_ #define _PKCS11I_H_ 1 #include "nssilock.h" #include "seccomon.h" #include "secoidt.h" #include "lowkeyti.h" #include "pkcs11t.h" #include "sftkdbt.h" #include "chacha20poly1305.h" #include "hasht.h" #include "alghmac.h" #include "cmac.h" /* * Configuration Defines * * The following defines affect the space verse speed trade offs of * the PKCS #11 module. For the most part the current settings are optimized * for web servers, where we want faster speed and lower lock contention at * the expense of space. */ /* * The attribute allocation strategy is static allocation: * Attributes are pre-allocated as part of the session object and used from * the object array. */ #define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in \ * the object (must me the absolute max) */ #define ATTR_SPACE 50 /* Maximum size of attribute data before extra \ * data needs to be allocated. This is set to \ * enough space to hold an SSL MASTER secret */ #define NSC_STRICT PR_FALSE /* forces the code to do strict template \ * matching when doing C_FindObject on token \ * objects. This will slow down search in \ * NSS. */ /* default search block allocations and increments */ #define NSC_CERT_BLOCK_SIZE 50 #define NSC_SEARCH_BLOCK_SIZE 5 #define NSC_SLOT_LIST_BLOCK_SIZE 10 #define NSC_FIPS_MODULE 1 #define NSC_NON_FIPS_MODULE 0 /* these are data base storage hashes, not cryptographic hashes.. The define * the effective size of the various object hash tables */ /* clients care more about memory usage than lookup performance on * cyrptographic objects. Clients also have less objects around to play with * * we eventually should make this configurable at runtime! Especially now that * NSS is a shared library. */ #define SPACE_ATTRIBUTE_HASH_SIZE 32 #define SPACE_SESSION_OBJECT_HASH_SIZE 32 #define SPACE_SESSION_HASH_SIZE 32 #define TIME_ATTRIBUTE_HASH_SIZE 32 #define TIME_SESSION_OBJECT_HASH_SIZE 1024 #define TIME_SESSION_HASH_SIZE 1024 #define MAX_OBJECT_LIST_SIZE 800 /* how many objects to keep on the free list * before we start freeing them */ #define MAX_KEY_LEN 256 /* maximum symmetric key length in bytes */ /* * LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number. * With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0. * With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0. * * HASH_SIZE LOG2_BUCKETS_PER BUCKETS_PER_LOCK NUMBER_OF_BUCKETS * 1024 9 512 2 * 1024 5 32 32 * 1024 1 2 512 * 1024 0 1 1024 * 4096 11 2048 2 * 4096 9 512 8 * 4096 5 32 128 * 4096 1 2 2048 * 4096 0 1 4096 */ #define LOG2_BUCKETS_PER_SESSION_LOCK 1 #define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK)) /* NOSPREAD sessionID to hash table index macro has been slower. */ /* define typedefs, double as forward declarations as well */ typedef struct SFTKAttributeStr SFTKAttribute; typedef struct SFTKObjectListStr SFTKObjectList; typedef struct SFTKObjectFreeListStr SFTKObjectFreeList; typedef struct SFTKObjectListElementStr SFTKObjectListElement; typedef struct SFTKObjectStr SFTKObject; typedef struct SFTKSessionObjectStr SFTKSessionObject; typedef struct SFTKTokenObjectStr SFTKTokenObject; typedef struct SFTKSessionStr SFTKSession; typedef struct SFTKSlotStr SFTKSlot; typedef struct SFTKSessionContextStr SFTKSessionContext; typedef struct SFTKSearchResultsStr SFTKSearchResults; typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo; typedef struct SFTKHashSignInfoStr SFTKHashSignInfo; typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo; typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo; typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo; typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info; typedef struct SFTKChaCha20CtrInfoStr SFTKChaCha20CtrInfo; typedef struct SFTKItemTemplateStr SFTKItemTemplate; /* define function pointer typdefs for pointer tables */ typedef void (*SFTKDestroy)(void *, PRBool); typedef void (*SFTKBegin)(void *); typedef SECStatus (*SFTKCipher)(void *, void *, unsigned int *, unsigned int, void *, unsigned int); typedef SECStatus (*SFTKAEADCipher)(void *, void *, unsigned int *, unsigned int, void *, unsigned int, void *, unsigned int, void *, unsigned int); typedef SECStatus (*SFTKVerify)(void *, void *, unsigned int, void *, unsigned int); typedef void (*SFTKHash)(void *, const void *, unsigned int); typedef void (*SFTKEnd)(void *, void *, unsigned int *, unsigned int); typedef void (*SFTKFree)(void *); /* Value to tell if an attribute is modifiable or not. * NEVER: attribute is only set on creation. * ONCOPY: attribute is set on creation and can only be changed on copy. * SENSITIVE: attribute can only be changed to TRUE. * ALWAYS: attribute can always be changed. */ typedef enum { SFTK_NEVER = 0, SFTK_ONCOPY = 1, SFTK_SENSITIVE = 2, SFTK_ALWAYS = 3 } SFTKModifyType; /* * Free Status Enum... tell us more information when we think we're * deleting an object. */ typedef enum { SFTK_DestroyFailure, SFTK_Destroyed, SFTK_Busy } SFTKFreeStatus; /* * attribute values of an object. */ struct SFTKAttributeStr { SFTKAttribute *next; SFTKAttribute *prev; PRBool freeAttr; PRBool freeData; /*must be called handle to make sftkqueue_find work */ CK_ATTRIBUTE_TYPE handle; CK_ATTRIBUTE attrib; unsigned char space[ATTR_SPACE]; }; /* * doubly link list of objects */ struct SFTKObjectListStr { SFTKObjectList *next; SFTKObjectList *prev; SFTKObject *parent; }; struct SFTKObjectFreeListStr { SFTKObject *head; PZLock *lock; int count; }; /* * PKCS 11 crypto object structure */ struct SFTKObjectStr { SFTKObject *next; SFTKObject *prev; CK_OBJECT_CLASS objclass; CK_OBJECT_HANDLE handle; int refCount; PZLock *refLock; SFTKSlot *slot; void *objectInfo; SFTKFree infoFree; }; struct SFTKTokenObjectStr { SFTKObject obj; SECItem dbKey; }; struct SFTKSessionObjectStr { SFTKObject obj; SFTKObjectList sessionList; PZLock *attributeLock; SFTKSession *session; PRBool wasDerived; int nextAttr; SFTKAttribute attrList[MAX_OBJS_ATTRS]; PRBool optimizeSpace; unsigned int hashSize; SFTKAttribute *head[1]; }; /* * struct to deal with a temparary list of objects */ struct SFTKObjectListElementStr { SFTKObjectListElement *next; SFTKObject *object; }; /* * Area to hold Search results */ struct SFTKSearchResultsStr { CK_OBJECT_HANDLE *handles; int size; int index; int array_size; }; /* * the universal crypto/hash/sign/verify context structure */ typedef enum { SFTK_ENCRYPT, SFTK_DECRYPT, SFTK_HASH, SFTK_SIGN, SFTK_SIGN_RECOVER, SFTK_VERIFY, SFTK_VERIFY_RECOVER, SFTK_MESSAGE_ENCRYPT, SFTK_MESSAGE_DECRYPT, SFTK_MESSAGE_SIGN, SFTK_MESSAGE_VERIFY } SFTKContextType; /** max block size of supported block ciphers */ #define SFTK_MAX_BLOCK_SIZE 16 /** currently SHA512 is the biggest hash length */ #define SFTK_MAX_MAC_LENGTH 64 #define SFTK_INVALID_MAC_SIZE 0xffffffff /** Particular ongoing operation in session (sign/verify/digest/encrypt/...) * * Understanding sign/verify context: * multi=1 hashInfo=0 block (symmetric) cipher MACing * multi=1 hashInfo=X PKC S/V with prior hashing * multi=0 hashInfo=0 PKC S/V one shot (w/o hashing) * multi=0 hashInfo=X *** shouldn't happen *** */ struct SFTKSessionContextStr { SFTKContextType type; PRBool multi; /* is multipart */ PRBool rsa; /* is rsa */ PRBool doPad; /* use PKCS padding for block ciphers */ PRBool isXCBC; /* xcbc, use special handling in final */ unsigned int blockSize; /* blocksize for padding */ unsigned int padDataLength; /* length of the valid data in padbuf */ /** latest incomplete block of data for block cipher */ unsigned char padBuf[SFTK_MAX_BLOCK_SIZE]; /** result of MAC'ing of latest full block of data with block cipher */ unsigned char macBuf[SFTK_MAX_BLOCK_SIZE]; unsigned char k2[SFTK_MAX_BLOCK_SIZE]; unsigned char k3[SFTK_MAX_BLOCK_SIZE]; CK_ULONG macSize; /* size of a general block cipher mac*/ void *cipherInfo; void *hashInfo; unsigned int cipherInfoLen; CK_MECHANISM_TYPE currentMech; SFTKCipher update; SFTKAEADCipher aeadUpdate; SFTKHash hashUpdate; SFTKEnd end; SFTKDestroy destroy; SFTKDestroy hashdestroy; SFTKVerify verify; unsigned int maxLen; SFTKObject *key; }; /* * Sessions (have objects) */ struct SFTKSessionStr { SFTKSession *next; SFTKSession *prev; CK_SESSION_HANDLE handle; PZLock *objectLock; int objectIDCount; CK_SESSION_INFO info; CK_NOTIFY notify; CK_VOID_PTR appData; SFTKSlot *slot; SFTKSearchResults *search; SFTKSessionContext *enc_context; SFTKSessionContext *hash_context; SFTKSessionContext *sign_context; SFTKObjectList *objects[1]; }; /* * slots (have sessions and objects) * * The array of sessionLock's protect the session hash table (head[]) * as well as the reference count of session objects in that bucket * (head[]->refCount), objectLock protects all elements of the slot's * object hash tables (sessObjHashTable[] and tokObjHashTable), and * sessionObjectHandleCount. * slotLock protects the remaining protected elements: * password, isLoggedIn, ssoLoggedIn, and sessionCount, * and pwCheckLock serializes the key database password checks in * NSC_SetPIN and NSC_Login. * * Each of the fields below has the following lifetime as commented * next to the fields: * invariant - This value is set when the slot is first created and * never changed until it is destroyed. * per load - This value is set when the slot is first created, or * when the slot is used to open another directory. Between open and close * this field does not change. * variable - This value changes through the normal process of slot operation. * - reset. The value of this variable is cleared during an open/close * cycles. * - preserved. The value of this variable is preserved over open/close * cycles. */ struct SFTKSlotStr { CK_SLOT_ID slotID; /* invariant */ PZLock *slotLock; /* invariant */ PZLock **sessionLock; /* invariant */ unsigned int numSessionLocks; /* invariant */ unsigned long sessionLockMask; /* invariant */ PZLock *objectLock; /* invariant */ PRLock *pwCheckLock; /* invariant */ PRBool present; /* variable -set */ PRBool hasTokens; /* per load */ PRBool isLoggedIn; /* variable - reset */ PRBool ssoLoggedIn; /* variable - reset */ PRBool needLogin; /* per load */ PRBool DB_loaded; /* per load */ PRBool readOnly; /* per load */ PRBool optimizeSpace; /* invariant */ SFTKDBHandle *certDB; /* per load */ SFTKDBHandle *keyDB; /* per load */ int minimumPinLen; /* per load */ PRInt32 sessionIDCount; /* atomically incremented */ /* (preserved) */ int sessionIDConflict; /* not protected by a lock */ /* (preserved) */ int sessionCount; /* variable - reset */ PRInt32 rwSessionCount; /* set by atomic operations */ /* (reset) */ int sessionObjectHandleCount; /* variable - perserved */ CK_ULONG index; /* invariant */ PLHashTable *tokObjHashTable; /* invariant */ SFTKObject **sessObjHashTable; /* variable - reset */ unsigned int sessObjHashSize; /* invariant */ SFTKSession **head; /* variable -reset */ unsigned int sessHashSize; /* invariant */ char tokDescription[33]; /* per load */ char updateTokDescription[33]; /* per load */ char slotDescription[65]; /* invariant */ }; /* * special joint operations Contexts */ struct SFTKHashVerifyInfoStr { SECOidTag hashOid; void *params; NSSLOWKEYPublicKey *key; }; struct SFTKHashSignInfoStr { SECOidTag hashOid; void *params; NSSLOWKEYPrivateKey *key; }; /** * Contexts for RSA-OAEP */ struct SFTKOAEPEncryptInfoStr { CK_RSA_PKCS_OAEP_PARAMS *params; NSSLOWKEYPublicKey *key; }; struct SFTKOAEPDecryptInfoStr { CK_RSA_PKCS_OAEP_PARAMS *params; NSSLOWKEYPrivateKey *key; }; /* context for the Final SSLMAC message */ struct SFTKSSLMACInfoStr { void *hashContext; SFTKBegin begin; SFTKHash update; SFTKEnd end; CK_ULONG macSize; int padSize; unsigned char key[MAX_KEY_LEN]; unsigned int keySize; }; /* SFTKChaCha20Poly1305Info saves the key, tag length, nonce, * and additional data for a ChaCha20+Poly1305 AEAD operation. */ struct SFTKChaCha20Poly1305InfoStr { ChaCha20Poly1305Context freeblCtx; unsigned char nonce[12]; unsigned char ad[16]; unsigned char *adOverflow; unsigned int adLen; }; /* SFTKChaCha20BlockInfoStr the key, nonce and counter for a * ChaCha20 block operation. */ struct SFTKChaCha20CtrInfoStr { PRUint8 key[32]; PRUint8 nonce[12]; PRUint32 counter; }; /* * Template based on SECItems, suitable for passing as arrays */ struct SFTKItemTemplateStr { CK_ATTRIBUTE_TYPE type; SECItem *item; }; /* macro for setting SFTKTemplates. */ #define SFTK_SET_ITEM_TEMPLATE(templ, count, itemPtr, attr) \ templ[count].type = attr; \ templ[count].item = itemPtr #define SFTK_MAX_ITEM_TEMPLATE 10 /* * session handle modifiers */ #define SFTK_SESSION_SLOT_MASK 0xff000000L /* * object handle modifiers */ #define SFTK_TOKEN_MASK 0x80000000L #define SFTK_TOKEN_MAGIC 0x80000000L #define SFTK_TOKEN_TYPE_MASK 0x70000000L /* keydb (high bit == 0) */ #define SFTK_TOKEN_TYPE_PRIV 0x10000000L #define SFTK_TOKEN_TYPE_PUB 0x20000000L #define SFTK_TOKEN_TYPE_KEY 0x30000000L /* certdb (high bit == 1) */ #define SFTK_TOKEN_TYPE_TRUST 0x40000000L #define SFTK_TOKEN_TYPE_CRL 0x50000000L #define SFTK_TOKEN_TYPE_SMIME 0x60000000L #define SFTK_TOKEN_TYPE_CERT 0x70000000L #define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC | SFTK_TOKEN_TYPE_CRL | 1) /* how big (in bytes) a password/pin we can deal with */ #define SFTK_MAX_PIN 500 /* minimum password/pin length (in Unicode characters) in FIPS mode */ #define FIPS_MIN_PIN 7 /* slot ID's */ #define NETSCAPE_SLOT_ID 1 #define PRIVATE_KEY_SLOT_ID 2 #define FIPS_SLOT_ID 3 /* slot helper macros */ #define sftk_SlotFromSession(sp) ((sp)->slot) #define sftk_isToken(id) (((id)&SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC) /* the session hash multiplier (see bug 201081) */ #define SHMULTIPLIER 1791398085 /* queueing helper macros */ #define sftk_hash(value, size) \ ((PRUint32)((value)*SHMULTIPLIER) & (size - 1)) #define sftkqueue_add(element, id, head, hash_size) \ { \ int tmp = sftk_hash(id, hash_size); \ (element)->next = (head)[tmp]; \ (element)->prev = NULL; \ if ((head)[tmp]) \ (head)[tmp]->prev = (element); \ (head)[tmp] = (element); \ } #define sftkqueue_find(element, id, head, hash_size) \ for ((element) = (head)[sftk_hash(id, hash_size)]; (element) != NULL; \ (element) = (element)->next) { \ if ((element)->handle == (id)) { \ break; \ } \ } #define sftkqueue_is_queued(element, id, head, hash_size) \ (((element)->next) || ((element)->prev) || \ ((head)[sftk_hash(id, hash_size)] == (element))) #define sftkqueue_delete(element, id, head, hash_size) \ if ((element)->next) \ (element)->next->prev = (element)->prev; \ if ((element)->prev) \ (element)->prev->next = (element)->next; \ else \ (head)[sftk_hash(id, hash_size)] = ((element)->next); \ (element)->next = NULL; \ (element)->prev = NULL; #define sftkqueue_init_element(element) \ (element)->prev = NULL; #define sftkqueue_add2(element, id, index, head) \ { \ (element)->next = (head)[index]; \ if ((head)[index]) \ (head)[index]->prev = (element); \ (head)[index] = (element); \ } #define sftkqueue_find2(element, id, index, head) \ for ((element) = (head)[index]; \ (element) != NULL; \ (element) = (element)->next) { \ if ((element)->handle == (id)) { \ break; \ } \ } #define sftkqueue_delete2(element, id, index, head) \ if ((element)->next) \ (element)->next->prev = (element)->prev; \ if ((element)->prev) \ (element)->prev->next = (element)->next; \ else \ (head)[index] = ((element)->next); #define sftkqueue_clear_deleted_element(element) \ (element)->next = NULL; \ (element)->prev = NULL; /* sessionID (handle) is used to determine session lock bucket */ #ifdef NOSPREAD /* NOSPREAD: (ID>>L2LPB) & (perbucket-1) */ #define SFTK_SESSION_LOCK(slot, handle) \ ((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) & (slot)->sessionLockMask]) #else /* SPREAD: ID & (perbucket-1) */ #define SFTK_SESSION_LOCK(slot, handle) \ ((slot)->sessionLock[(handle) & (slot)->sessionLockMask]) #endif /* expand an attribute & secitem structures out */ #define sftk_attr_expand(ap) (ap)->type, (ap)->pValue, (ap)->ulValueLen #define sftk_item_expand(ip) (ip)->data, (ip)->len typedef struct sftk_token_parametersStr { CK_SLOT_ID slotID; char *configdir; char *certPrefix; char *keyPrefix; char *updatedir; char *updCertPrefix; char *updKeyPrefix; char *updateID; char *tokdes; char *slotdes; char *updtokdes; int minPW; PRBool readOnly; PRBool noCertDB; PRBool noKeyDB; PRBool forceOpen; PRBool pwRequired; PRBool optimizeSpace; } sftk_token_parameters; typedef struct sftk_parametersStr { char *configdir; char *updatedir; char *updateID; char *secmodName; char *man; char *libdes; PRBool readOnly; PRBool noModDB; PRBool noCertDB; PRBool forceOpen; PRBool pwRequired; PRBool optimizeSpace; sftk_token_parameters *tokens; int token_count; } sftk_parameters; /* path stuff (was machine dependent) used by dbinit.c and pk11db.c */ #define CERT_DB_FMT "%scert%s.db" #define KEY_DB_FMT "%skey%s.db" struct sftk_MACConstantTimeCtxStr { const SECHashObject *hash; unsigned char mac[64]; unsigned char secret[64]; unsigned int headerLength; unsigned int secretLength; unsigned int totalLength; unsigned char header[75]; }; typedef struct sftk_MACConstantTimeCtxStr sftk_MACConstantTimeCtx; struct sftk_MACCtxStr { /* This is a common MAC context that supports both HMAC and CMAC * operations. This also presents a unified set of semantics: * * - Everything except Destroy returns a CK_RV, indicating success * or failure. (This handles the difference between HMAC's and CMAC's * interfaces, since the underlying AES _might_ fail with CMAC). * * - The underlying MAC is started on Init(...), so Update(...) can * called right away. (This handles the difference between HMAC and * CMAC in their *_Init(...) functions). * * - Calling semantics: * * - One of sftk_MAC_{Create,Init,InitRaw}(...) to set up the MAC * context, checking the return code. * - sftk_MAC_Update(...) as many times as necessary to process * input data, checking the return code. * - sftk_MAC_Finish(...) to get the output of the MAC; result_len * may be NULL if the caller knows the expected output length, * checking the return code. If result_len is NULL, this will * PR_ASSERT(...) that the actual returned length was equal to * max_result_len. * * Note: unlike HMAC_Finish(...), this allows the caller to specify * a return value less than return length, to align with * CMAC_Finish(...)'s semantics. This will force an additional * stack allocation of size SFTK_MAX_MAC_LENGTH. * - sftk_MAC_Reset(...) if the caller wishes to compute a new MAC * with the same key, checking the return code. * - sftk_MAC_Destroy(...) when the caller frees its associated * memory, passing PR_TRUE if sftk_MAC_Create(...) was called, * and PR_FALSE otherwise. */ CK_MECHANISM_TYPE mech; unsigned int mac_size; union { HMACContext *hmac; CMACContext *cmac; /* Functions to update when adding a new MAC or a new hash: * * - sftk_MAC_Init * - sftk_MAC_Update * - sftk_MAC_Finish * - sftk_MAC_Reset */ void *raw; } mac; void (*destroy_func)(void *ctx, PRBool free_it); }; typedef struct sftk_MACCtxStr sftk_MACCtx; extern CK_NSS_MODULE_FUNCTIONS sftk_module_funcList; SEC_BEGIN_PROTOS /* shared functions between pkcs11.c and fipstokn.c */ extern PRBool nsf_init; extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS); extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS); extern PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV *crv); extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, unsigned int moduleIndex); /* slot initialization, reinit, shutdown and destruction */ extern CK_RV SFTK_SlotInit(char *configdir, char *updatedir, char *updateID, sftk_token_parameters *params, unsigned int moduleIndex); extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir, char *updateID, sftk_token_parameters *params, unsigned int moduleIndex); extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot); extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot); extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout); /* internal utility functions used by pkcs11.c */ extern CK_RV sftk_MapCryptError(int error); extern CK_RV sftk_MapDecryptError(int error); extern CK_RV sftk_MapVerifyError(int error); extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern void sftk_FreeAttribute(SFTKAttribute *attribute); extern CK_RV sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type, const void *valPtr, CK_ULONG length); extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern CK_RV sftk_MultipleAttribute2SecItem(PLArenaPool *arena, SFTKObject *object, SFTKItemTemplate *templ, int count); extern unsigned int sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen); extern CK_RV sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, int minLength, int maxLength, int minMultiple); extern PRBool sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern PRBool sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern void sftk_DeleteAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern CK_RV sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item, SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern SFTKModifyType sftk_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass); extern PRBool sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass); extern char *sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern void sftk_nullAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type); extern CK_RV sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, CK_ULONG *longData); extern CK_RV sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, const void *value, unsigned int len); extern CK_RV sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, const void *value, unsigned int len); extern unsigned int sftk_MapTrust(CK_TRUST trust, PRBool clientAuth); extern SFTKObject *sftk_NewObject(SFTKSlot *slot); extern CK_RV sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject); extern SFTKFreeStatus sftk_FreeObject(SFTKObject *object); extern CK_RV sftk_DeleteObject(SFTKSession *session, SFTKObject *object); extern void sftk_ReferenceObject(SFTKObject *object); extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session); extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object); extern void sftk_AddObject(SFTKSession *session, SFTKObject *object); /* clear out all the existing object ID to database key mappings. * used to reinit a token */ extern CK_RV SFTK_ClearTokenKeyHashTable(SFTKSlot *slot); extern CK_RV sftk_searchObjectList(SFTKSearchResults *search, SFTKObject **head, unsigned int size, PZLock *lock, CK_ATTRIBUTE_PTR inTemplate, int count, PRBool isLoggedIn); extern SFTKObjectListElement *sftk_FreeObjectListElement( SFTKObjectListElement *objectList); extern void sftk_FreeObjectList(SFTKObjectListElement *objectList); extern void sftk_FreeSearch(SFTKSearchResults *search); extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session); extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all); extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle); extern CK_SLOT_ID sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle); extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle); extern void sftk_FreeSession(SFTKSession *session); extern void sftk_DestroySession(SFTKSession *session); extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, CK_FLAGS flags); extern void sftk_update_state(SFTKSlot *slot, SFTKSession *session); extern void sftk_update_all_states(SFTKSlot *slot); extern void sftk_InitFreeLists(void); extern void sftk_CleanupFreeLists(void); /* * Helper functions to handle the session crypto contexts */ extern CK_RV sftk_InitGeneric(SFTKSession *session, SFTKSessionContext **contextPtr, SFTKContextType ctype, SFTKObject **keyPtr, CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr, CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation); void sftk_SetContextByType(SFTKSession *session, SFTKContextType type, SFTKSessionContext *context); extern CK_RV sftk_GetContext(CK_SESSION_HANDLE handle, SFTKSessionContext **contextPtr, SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr); extern void sftk_TerminateOp(SFTKSession *session, SFTKContextType ctype, SFTKSessionContext *context); extern void sftk_FreeContext(SFTKSessionContext *context); extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp); extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp); extern CK_RV sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privKey, CK_KEY_TYPE keyType, NSSLOWKEYPublicKey *pubKey); extern void sftk_FormatDESKey(unsigned char *key, int length); extern PRBool sftk_CheckDESKey(unsigned char *key); extern PRBool sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type); extern void sftk_EncodeInteger(PRUint64 integer, CK_ULONG num_bits, CK_BBOOL littleEndian, CK_BYTE_PTR output, CK_ULONG_PTR output_len); /* ike and xcbc helpers */ extern CK_RV sftk_ike_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, const CK_NSS_IKE_PRF_DERIVE_PARAMS *params, SFTKObject *outKey); extern CK_RV sftk_ike1_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, const CK_NSS_IKE1_PRF_DERIVE_PARAMS *params, SFTKObject *outKey, unsigned int keySize); extern CK_RV sftk_ike1_appendix_b_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, const CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS *params, SFTKObject *outKey, unsigned int keySize); extern CK_RV sftk_ike_prf_plus(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, const CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *params, SFTKObject *outKey, unsigned int keySize); extern CK_RV sftk_aes_xcbc_new_keys(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE_PTR phKey, unsigned char *k2, unsigned char *k3); extern CK_RV sftk_xcbc_mac_pad(unsigned char *padBuf, unsigned int bufLen, unsigned int blockSize, const unsigned char *k2, const unsigned char *k3); extern SECStatus sftk_fips_IKE_PowerUpSelfTests(void); /* mechanism allows this operation */ extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op); /* helper function which calls nsslowkey_FindKeyByPublicKey after safely * acquiring a reference to the keydb from the slot */ NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey); /* * parameter parsing functions */ CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS); void sftk_freeParams(sftk_parameters *params); /* * narrow objects */ SFTKSessionObject *sftk_narrowToSessionObject(SFTKObject *); SFTKTokenObject *sftk_narrowToTokenObject(SFTKObject *); /* * token object utilities */ void sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle); PRBool sftk_poisonHandle(SFTKSlot *slot, SECItem *dbkey, CK_OBJECT_HANDLE handle); SFTKObject *sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle); SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so); /* J-PAKE (jpakesftk.c) */ extern CK_RV jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params *params, SFTKObject *key); extern CK_RV jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params *params, SFTKObject *sourceKey, SFTKObject *key); extern CK_RV jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams *params, SFTKObject *sourceKey, SFTKObject *key); /* Constant time MAC functions (hmacct.c) */ sftk_MACConstantTimeCtx *sftk_HMACConstantTime_New( CK_MECHANISM_PTR mech, SFTKObject *key); sftk_MACConstantTimeCtx *sftk_SSLv3MACConstantTime_New( CK_MECHANISM_PTR mech, SFTKObject *key); void sftk_HMACConstantTime_Update(void *pctx, const void *data, unsigned int len); void sftk_SSLv3MACConstantTime_Update(void *pctx, const void *data, unsigned int len); void sftk_MACConstantTime_EndHash( void *pctx, void *out, unsigned int *outLength, unsigned int maxLength); void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool); /**************************************** * implement TLS Pseudo Random Function (PRF) */ extern CK_RV sftk_TLSPRFInit(SFTKSessionContext *context, SFTKObject *key, CK_KEY_TYPE key_type, HASH_HashType hash_alg, unsigned int out_len); /* PKCS#11 MAC implementation. See sftk_MACCtxStr declaration above for * calling semantics for these functions. */ HASH_HashType sftk_HMACMechanismToHash(CK_MECHANISM_TYPE mech); CK_RV sftk_MAC_Create(CK_MECHANISM_TYPE mech, SFTKObject *key, sftk_MACCtx **ret_ctx); CK_RV sftk_MAC_Init(sftk_MACCtx *ctx, CK_MECHANISM_TYPE mech, SFTKObject *key); CK_RV sftk_MAC_InitRaw(sftk_MACCtx *ctx, CK_MECHANISM_TYPE mech, const unsigned char *key, unsigned int key_len, PRBool isFIPS); CK_RV sftk_MAC_Update(sftk_MACCtx *ctx, const CK_BYTE *data, unsigned int data_len); CK_RV sftk_MAC_Finish(sftk_MACCtx *ctx, CK_BYTE_PTR result, unsigned int *result_len, unsigned int max_result_len); CK_RV sftk_MAC_Reset(sftk_MACCtx *ctx); void sftk_MAC_Destroy(sftk_MACCtx *ctx, PRBool free_it); /* constant time helpers */ unsigned int sftk_CKRVToMask(CK_RV rv); CK_RV sftk_CheckCBCPadding(CK_BYTE_PTR pBuf, unsigned int bufLen, unsigned int blockSize, unsigned int *outPadSize); /* NIST 800-108 (kbkdf.c) implementations */ extern CK_RV kbkdf_Dispatch(CK_MECHANISM_TYPE mech, CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, SFTKObject *base_key, SFTKObject *ret_key, CK_ULONG keySize); extern SECStatus sftk_fips_SP800_108_PowerUpSelfTests(void); /* export the HKDF function for use in PowerupSelfTests */ CK_RV sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_SESSION_HANDLE hSession, SFTKObject *sourceKey, const unsigned char *sourceKeyBytes, int sourceKeyLen, SFTKObject *key, unsigned char *outKeyBytes, int keySize, PRBool canBeData, PRBool isFIPS); char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args); /* dh verify functions */ /* verify that dhPrime matches one of our known primes, and if so return * it's subprime value */ const SECItem *sftk_VerifyDH_Prime(SECItem *dhPrime); /* check if dhSubPrime claims dhPrime is a safe prime. */ SECStatus sftk_IsSafePrime(SECItem *dhPrime, SECItem *dhSubPrime, PRBool *isSafe); SEC_END_PROTOS #endif /* _PKCS11I_H_ */