summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/softoken/pkcs11i.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--security/nss/lib/softoken/pkcs11i.h977
1 files changed, 977 insertions, 0 deletions
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
new file mode 100644
index 0000000000..b0408dc430
--- /dev/null
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -0,0 +1,977 @@
+/* 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_MIN_SESSION_OBJECT_HANDLE 1U
+
+#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 SFTKOAEPInfoStr SFTKOAEPInfo;
+typedef struct SFTKPSSSignInfoStr SFTKPSSSignInfo;
+typedef struct SFTKPSSVerifyInfoStr SFTKPSSVerifyInfo;
+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;
+ PRBool isFIPS;
+};
+
+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 */
+ PRBool isFIPS; /* current operation is in FIPS mode */
+ 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;
+ PRBool lastOpWasFIPS;
+ 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, needLogin, 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 */
+ SFTKSession moduleObjects; /* global session to hang module specific
+ * objects like profile objects or
+ * validation objects */
+};
+
+/*
+ * special joint operations Contexts
+ */
+struct SFTKHashVerifyInfoStr {
+ SECOidTag hashOid;
+ void *params;
+ NSSLOWKEYPublicKey *key;
+};
+
+struct SFTKHashSignInfoStr {
+ SECOidTag hashOid;
+ void *params;
+ NSSLOWKEYPrivateKey *key;
+};
+
+struct SFTKPSSVerifyInfoStr {
+ size_t size; /* must be first */
+ CK_RSA_PKCS_PSS_PARAMS params;
+ NSSLOWKEYPublicKey *key;
+};
+
+struct SFTKPSSSignInfoStr {
+ size_t size; /* must be first */
+ CK_RSA_PKCS_PSS_PARAMS params;
+ NSSLOWKEYPrivateKey *key;
+};
+
+/**
+ * Contexts for RSA-OAEP
+ */
+struct SFTKOAEPInfoStr {
+ CK_RSA_PKCS_OAEP_PARAMS params;
+ PRBool isEncrypt;
+ union {
+ NSSLOWKEYPublicKey *pub;
+ NSSLOWKEYPrivateKey *priv;
+ } key;
+};
+
+/* context for the Final SSLMAC message */
+struct SFTKSSLMACInfoStr {
+ size_t size; /* must be first */
+ 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)
+#define sftk_isFIPS(id) \
+ (((id) == FIPS_SLOT_ID) || ((id) >= SFTK_MIN_FIPS_USER_SLOT_ID))
+
+/* 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;
+extern CK_NSS_FIPS_FUNCTIONS sftk_fips_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 CK_OBJECT_HANDLE sftk_getNextHandle(SFTKSlot *slot);
+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_ClearSession(SFTKSession *session);
+extern void sftk_DestroySession(SFTKSession *session);
+extern CK_RV sftk_InitSession(SFTKSession *session, SFTKSlot *slot,
+ CK_SLOT_ID slotID, CK_NOTIFY notify,
+ CK_VOID_PTR pApplication, CK_FLAGS flags);
+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,
+ CK_MECHANISM *pMechanism,
+ 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);
+PRBool sftk_RawArgHasFlag(const char *entry, const char *flag, const void *pReserved);
+
+/*
+ * 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);
+
+/* Crypto Utilities */
+HASH_HashType sftk_GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech);
+
+/****************************************
+ * 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, PRBool isFIPS);
+/* check if dhSubPrime claims dhPrime is a safe prime. */
+SECStatus sftk_IsSafePrime(SECItem *dhPrime, SECItem *dhSubPrime, PRBool *isSafe);
+/* map an operation Attribute to a Mechanism flag */
+CK_FLAGS sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE op);
+/* check the FIPS table to determine if this current operation is allowed by
+ * FIPS security policy */
+PRBool sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech,
+ CK_ATTRIBUTE_TYPE op, SFTKObject *source);
+/* add validation objects to the slot */
+CK_RV sftk_CreateValidationObjects(SFTKSlot *slot);
+
+SEC_END_PROTOS
+
+#endif /* _PKCS11I_H_ */