1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5  * Internal data structures and functions used by pkcs11.c
6  */
7 #ifndef _PKCS11I_H_
8 #define _PKCS11I_H_ 1
9 
10 #include "nssilock.h"
11 #include "seccomon.h"
12 #include "secoidt.h"
13 #include "lowkeyti.h"
14 #include "pkcs11t.h"
15 
16 #include "sftkdbt.h"
17 #include "chacha20poly1305.h"
18 #include "hasht.h"
19 
20 #include "alghmac.h"
21 #include "cmac.h"
22 
23 /*
24  * Configuration Defines
25  *
26  * The following defines affect the space verse speed trade offs of
27  * the PKCS #11 module. For the most part the current settings are optimized
28  * for web servers, where we want faster speed and lower lock contention at
29  * the expense of space.
30  */
31 
32 /*
33  * The attribute allocation strategy is static allocation:
34  *   Attributes are pre-allocated as part of the session object and used from
35  *   the object array.
36  */
37 #define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in \
38                            * the object (must me the absolute max) */
39 #define ATTR_SPACE 50     /* Maximum size of attribute data before extra \
40                            * data needs to be allocated. This is set to  \
41                            * enough space to hold an SSL MASTER secret */
42 
43 #define NSC_STRICT PR_FALSE /* forces the code to do strict template     \
44                              * matching when doing C_FindObject on token \
45                              * objects. This will slow down search in    \
46                              * NSS. */
47 /* default search block allocations and increments */
48 #define NSC_CERT_BLOCK_SIZE 50
49 #define NSC_SEARCH_BLOCK_SIZE 5
50 #define NSC_SLOT_LIST_BLOCK_SIZE 10
51 
52 #define NSC_FIPS_MODULE 1
53 #define NSC_NON_FIPS_MODULE 0
54 
55 /* these are data base storage hashes, not cryptographic hashes.. The define
56  * the effective size of the various object hash tables */
57 /* clients care more about memory usage than lookup performance on
58  * cyrptographic objects. Clients also have less objects around to play with
59  *
60  * we eventually should make this configurable at runtime! Especially now that
61  * NSS is a shared library.
62  */
63 #define SPACE_ATTRIBUTE_HASH_SIZE 32
64 #define SPACE_SESSION_OBJECT_HASH_SIZE 32
65 #define SPACE_SESSION_HASH_SIZE 32
66 #define TIME_ATTRIBUTE_HASH_SIZE 32
67 #define TIME_SESSION_OBJECT_HASH_SIZE 1024
68 #define TIME_SESSION_HASH_SIZE 1024
69 #define MAX_OBJECT_LIST_SIZE 800
70 /* how many objects to keep on the free list
71                    * before we start freeing them */
72 #define MAX_KEY_LEN 256 /* maximum symmetric key length in bytes */
73 
74 /*
75  * LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number.
76  * With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0.
77  * With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0.
78  *
79  * HASH_SIZE   LOG2_BUCKETS_PER   BUCKETS_PER_LOCK  NUMBER_OF_BUCKETS
80  * 1024        9                  512               2
81  * 1024        5                  32                32
82  * 1024        1                  2                 512
83  * 1024        0                  1                 1024
84  * 4096        11                 2048              2
85  * 4096        9                  512               8
86  * 4096        5                  32                128
87  * 4096        1                  2                 2048
88  * 4096        0                  1                 4096
89  */
90 #define LOG2_BUCKETS_PER_SESSION_LOCK 1
91 #define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK))
92 /* NOSPREAD sessionID to hash table index macro has been slower. */
93 
94 /* define typedefs, double as forward declarations as well */
95 typedef struct SFTKAttributeStr SFTKAttribute;
96 typedef struct SFTKObjectListStr SFTKObjectList;
97 typedef struct SFTKObjectFreeListStr SFTKObjectFreeList;
98 typedef struct SFTKObjectListElementStr SFTKObjectListElement;
99 typedef struct SFTKObjectStr SFTKObject;
100 typedef struct SFTKSessionObjectStr SFTKSessionObject;
101 typedef struct SFTKTokenObjectStr SFTKTokenObject;
102 typedef struct SFTKSessionStr SFTKSession;
103 typedef struct SFTKSlotStr SFTKSlot;
104 typedef struct SFTKSessionContextStr SFTKSessionContext;
105 typedef struct SFTKSearchResultsStr SFTKSearchResults;
106 typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo;
107 typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
108 typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
109 typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
110 typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
111 typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
112 typedef struct SFTKChaCha20CtrInfoStr SFTKChaCha20CtrInfo;
113 typedef struct SFTKItemTemplateStr SFTKItemTemplate;
114 
115 /* define function pointer typdefs for pointer tables */
116 typedef void (*SFTKDestroy)(void *, PRBool);
117 typedef void (*SFTKBegin)(void *);
118 typedef SECStatus (*SFTKCipher)(void *, void *, unsigned int *, unsigned int,
119                                 void *, unsigned int);
120 typedef SECStatus (*SFTKAEADCipher)(void *, void *, unsigned int *,
121                                     unsigned int, void *, unsigned int,
122                                     void *, unsigned int, void *, unsigned int);
123 typedef SECStatus (*SFTKVerify)(void *, void *, unsigned int, void *, unsigned int);
124 typedef void (*SFTKHash)(void *, const void *, unsigned int);
125 typedef void (*SFTKEnd)(void *, void *, unsigned int *, unsigned int);
126 typedef void (*SFTKFree)(void *);
127 
128 /* Value to tell if an attribute is modifiable or not.
129  *    NEVER: attribute is only set on creation.
130  *    ONCOPY: attribute is set on creation and can only be changed on copy.
131  *    SENSITIVE: attribute can only be changed to TRUE.
132  *    ALWAYS: attribute can always be changed.
133  */
134 typedef enum {
135     SFTK_NEVER = 0,
136     SFTK_ONCOPY = 1,
137     SFTK_SENSITIVE = 2,
138     SFTK_ALWAYS = 3
139 } SFTKModifyType;
140 
141 /*
142  * Free Status Enum... tell us more information when we think we're
143  * deleting an object.
144  */
145 typedef enum {
146     SFTK_DestroyFailure,
147     SFTK_Destroyed,
148     SFTK_Busy
149 } SFTKFreeStatus;
150 
151 /*
152  * attribute values of an object.
153  */
154 struct SFTKAttributeStr {
155     SFTKAttribute *next;
156     SFTKAttribute *prev;
157     PRBool freeAttr;
158     PRBool freeData;
159     /*must be called handle to make sftkqueue_find work */
160     CK_ATTRIBUTE_TYPE handle;
161     CK_ATTRIBUTE attrib;
162     unsigned char space[ATTR_SPACE];
163 };
164 
165 /*
166  * doubly link list of objects
167  */
168 struct SFTKObjectListStr {
169     SFTKObjectList *next;
170     SFTKObjectList *prev;
171     SFTKObject *parent;
172 };
173 
174 struct SFTKObjectFreeListStr {
175     SFTKObject *head;
176     PZLock *lock;
177     int count;
178 };
179 
180 /*
181  * PKCS 11 crypto object structure
182  */
183 struct SFTKObjectStr {
184     SFTKObject *next;
185     SFTKObject *prev;
186     CK_OBJECT_CLASS objclass;
187     CK_OBJECT_HANDLE handle;
188     int refCount;
189     PZLock *refLock;
190     SFTKSlot *slot;
191     void *objectInfo;
192     SFTKFree infoFree;
193 };
194 
195 struct SFTKTokenObjectStr {
196     SFTKObject obj;
197     SECItem dbKey;
198 };
199 
200 struct SFTKSessionObjectStr {
201     SFTKObject obj;
202     SFTKObjectList sessionList;
203     PZLock *attributeLock;
204     SFTKSession *session;
205     PRBool wasDerived;
206     int nextAttr;
207     SFTKAttribute attrList[MAX_OBJS_ATTRS];
208     PRBool optimizeSpace;
209     unsigned int hashSize;
210     SFTKAttribute *head[1];
211 };
212 
213 /*
214  * struct to deal with a temparary list of objects
215  */
216 struct SFTKObjectListElementStr {
217     SFTKObjectListElement *next;
218     SFTKObject *object;
219 };
220 
221 /*
222  * Area to hold Search results
223  */
224 struct SFTKSearchResultsStr {
225     CK_OBJECT_HANDLE *handles;
226     int size;
227     int index;
228     int array_size;
229 };
230 
231 /*
232  * the universal crypto/hash/sign/verify context structure
233  */
234 typedef enum {
235     SFTK_ENCRYPT,
236     SFTK_DECRYPT,
237     SFTK_HASH,
238     SFTK_SIGN,
239     SFTK_SIGN_RECOVER,
240     SFTK_VERIFY,
241     SFTK_VERIFY_RECOVER,
242     SFTK_MESSAGE_ENCRYPT,
243     SFTK_MESSAGE_DECRYPT,
244     SFTK_MESSAGE_SIGN,
245     SFTK_MESSAGE_VERIFY
246 } SFTKContextType;
247 
248 /** max block size of supported block ciphers */
249 #define SFTK_MAX_BLOCK_SIZE 16
250 /** currently SHA512 is the biggest hash length */
251 #define SFTK_MAX_MAC_LENGTH 64
252 #define SFTK_INVALID_MAC_SIZE 0xffffffff
253 
254 /** Particular ongoing operation in session (sign/verify/digest/encrypt/...)
255  *
256  *  Understanding sign/verify context:
257  *      multi=1 hashInfo=0   block (symmetric) cipher MACing
258  *      multi=1 hashInfo=X   PKC S/V with prior hashing
259  *      multi=0 hashInfo=0   PKC S/V one shot (w/o hashing)
260  *      multi=0 hashInfo=X   *** shouldn't happen ***
261  */
262 struct SFTKSessionContextStr {
263     SFTKContextType type;
264     PRBool multi;               /* is multipart */
265     PRBool rsa;                 /* is rsa */
266     PRBool doPad;               /* use PKCS padding for block ciphers */
267     PRBool isXCBC;              /* xcbc, use special handling in final */
268     unsigned int blockSize;     /* blocksize for padding */
269     unsigned int padDataLength; /* length of the valid data in padbuf */
270     /** latest incomplete block of data for block cipher */
271     unsigned char padBuf[SFTK_MAX_BLOCK_SIZE];
272     /** result of MAC'ing of latest full block of data with block cipher */
273     unsigned char macBuf[SFTK_MAX_BLOCK_SIZE];
274     unsigned char k2[SFTK_MAX_BLOCK_SIZE];
275     unsigned char k3[SFTK_MAX_BLOCK_SIZE];
276     CK_ULONG macSize; /* size of a general block cipher mac*/
277     void *cipherInfo;
278     void *hashInfo;
279     unsigned int cipherInfoLen;
280     CK_MECHANISM_TYPE currentMech;
281     SFTKCipher update;
282     SFTKAEADCipher aeadUpdate;
283     SFTKHash hashUpdate;
284     SFTKEnd end;
285     SFTKDestroy destroy;
286     SFTKDestroy hashdestroy;
287     SFTKVerify verify;
288     unsigned int maxLen;
289     SFTKObject *key;
290 };
291 
292 /*
293  * Sessions (have objects)
294  */
295 struct SFTKSessionStr {
296     SFTKSession *next;
297     SFTKSession *prev;
298     CK_SESSION_HANDLE handle;
299     PZLock *objectLock;
300     int objectIDCount;
301     CK_SESSION_INFO info;
302     CK_NOTIFY notify;
303     CK_VOID_PTR appData;
304     SFTKSlot *slot;
305     SFTKSearchResults *search;
306     SFTKSessionContext *enc_context;
307     SFTKSessionContext *hash_context;
308     SFTKSessionContext *sign_context;
309     SFTKObjectList *objects[1];
310 };
311 
312 /*
313  * slots (have sessions and objects)
314  *
315  * The array of sessionLock's protect the session hash table (head[])
316  * as well as the reference count of session objects in that bucket
317  * (head[]->refCount),  objectLock protects all elements of the slot's
318  * object hash tables (sessObjHashTable[] and tokObjHashTable), and
319  * sessionObjectHandleCount.
320  * slotLock protects the remaining protected elements:
321  * password, isLoggedIn, ssoLoggedIn, and sessionCount,
322  * and pwCheckLock serializes the key database password checks in
323  * NSC_SetPIN and NSC_Login.
324  *
325  * Each of the fields below has the following lifetime as commented
326  * next to the fields:
327  *   invariant  - This value is set when the slot is first created and
328  * never changed until it is destroyed.
329  *   per load   - This value is set when the slot is first created, or
330  * when the slot is used to open another directory. Between open and close
331  * this field does not change.
332  *   variable - This value changes through the normal process of slot operation.
333  *      - reset. The value of this variable is cleared during an open/close
334  *   cycles.
335  *      - preserved. The value of this variable is preserved over open/close
336  *   cycles.
337  */
338 struct SFTKSlotStr {
339     CK_SLOT_ID slotID;             /* invariant */
340     PZLock *slotLock;              /* invariant */
341     PZLock **sessionLock;          /* invariant */
342     unsigned int numSessionLocks;  /* invariant */
343     unsigned long sessionLockMask; /* invariant */
344     PZLock *objectLock;            /* invariant */
345     PRLock *pwCheckLock;           /* invariant */
346     PRBool present;                /* variable -set */
347     PRBool hasTokens;              /* per load */
348     PRBool isLoggedIn;             /* variable - reset */
349     PRBool ssoLoggedIn;            /* variable - reset */
350     PRBool needLogin;              /* per load */
351     PRBool DB_loaded;              /* per load */
352     PRBool readOnly;               /* per load */
353     PRBool optimizeSpace;          /* invariant */
354     SFTKDBHandle *certDB;          /* per load */
355     SFTKDBHandle *keyDB;           /* per load */
356     int minimumPinLen;             /* per load */
357     PRInt32 sessionIDCount;        /* atomically incremented */
358                                    /* (preserved) */
359     int sessionIDConflict;         /* not protected by a lock */
360                                    /* (preserved) */
361     int sessionCount;              /* variable - reset */
362     PRInt32 rwSessionCount;        /* set by atomic operations */
363                                    /* (reset) */
364     int sessionObjectHandleCount;  /* variable - perserved */
365     CK_ULONG index;                /* invariant */
366     PLHashTable *tokObjHashTable;  /* invariant */
367     SFTKObject **sessObjHashTable; /* variable - reset */
368     unsigned int sessObjHashSize;  /* invariant */
369     SFTKSession **head;            /* variable -reset */
370     unsigned int sessHashSize;     /* invariant */
371     char tokDescription[33];       /* per load */
372     char updateTokDescription[33]; /* per load */
373     char slotDescription[65];      /* invariant */
374 };
375 
376 /*
377  * special joint operations Contexts
378  */
379 struct SFTKHashVerifyInfoStr {
380     SECOidTag hashOid;
381     void *params;
382     NSSLOWKEYPublicKey *key;
383 };
384 
385 struct SFTKHashSignInfoStr {
386     SECOidTag hashOid;
387     void *params;
388     NSSLOWKEYPrivateKey *key;
389 };
390 
391 /**
392  * Contexts for RSA-OAEP
393  */
394 struct SFTKOAEPEncryptInfoStr {
395     CK_RSA_PKCS_OAEP_PARAMS *params;
396     NSSLOWKEYPublicKey *key;
397 };
398 
399 struct SFTKOAEPDecryptInfoStr {
400     CK_RSA_PKCS_OAEP_PARAMS *params;
401     NSSLOWKEYPrivateKey *key;
402 };
403 
404 /* context for the Final SSLMAC message */
405 struct SFTKSSLMACInfoStr {
406     void *hashContext;
407     SFTKBegin begin;
408     SFTKHash update;
409     SFTKEnd end;
410     CK_ULONG macSize;
411     int padSize;
412     unsigned char key[MAX_KEY_LEN];
413     unsigned int keySize;
414 };
415 
416 /* SFTKChaCha20Poly1305Info saves the key, tag length, nonce,
417  * and additional data for a ChaCha20+Poly1305 AEAD operation. */
418 struct SFTKChaCha20Poly1305InfoStr {
419     ChaCha20Poly1305Context freeblCtx;
420     unsigned char nonce[12];
421     unsigned char ad[16];
422     unsigned char *adOverflow;
423     unsigned int adLen;
424 };
425 
426 /* SFTKChaCha20BlockInfoStr the key, nonce and counter for a
427  * ChaCha20 block operation. */
428 struct SFTKChaCha20CtrInfoStr {
429     PRUint8 key[32];
430     PRUint8 nonce[12];
431     PRUint32 counter;
432 };
433 
434 /*
435  * Template based on SECItems, suitable for passing as arrays
436  */
437 struct SFTKItemTemplateStr {
438     CK_ATTRIBUTE_TYPE type;
439     SECItem *item;
440 };
441 
442 /* macro for setting SFTKTemplates. */
443 #define SFTK_SET_ITEM_TEMPLATE(templ, count, itemPtr, attr) \
444     templ[count].type = attr;                               \
445     templ[count].item = itemPtr
446 
447 #define SFTK_MAX_ITEM_TEMPLATE 10
448 
449 /*
450  * session handle modifiers
451  */
452 #define SFTK_SESSION_SLOT_MASK 0xff000000L
453 
454 /*
455  * object handle modifiers
456  */
457 #define SFTK_TOKEN_MASK 0x80000000L
458 #define SFTK_TOKEN_MAGIC 0x80000000L
459 #define SFTK_TOKEN_TYPE_MASK 0x70000000L
460 /* keydb (high bit == 0) */
461 #define SFTK_TOKEN_TYPE_PRIV 0x10000000L
462 #define SFTK_TOKEN_TYPE_PUB 0x20000000L
463 #define SFTK_TOKEN_TYPE_KEY 0x30000000L
464 /* certdb (high bit == 1) */
465 #define SFTK_TOKEN_TYPE_TRUST 0x40000000L
466 #define SFTK_TOKEN_TYPE_CRL 0x50000000L
467 #define SFTK_TOKEN_TYPE_SMIME 0x60000000L
468 #define SFTK_TOKEN_TYPE_CERT 0x70000000L
469 
470 #define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC | SFTK_TOKEN_TYPE_CRL | 1)
471 /* how big (in bytes) a password/pin we can deal with */
472 #define SFTK_MAX_PIN 500
473 /* minimum password/pin length (in Unicode characters) in FIPS mode */
474 #define FIPS_MIN_PIN 7
475 
476 /* slot ID's */
477 #define NETSCAPE_SLOT_ID 1
478 #define PRIVATE_KEY_SLOT_ID 2
479 #define FIPS_SLOT_ID 3
480 
481 /* slot helper macros */
482 #define sftk_SlotFromSession(sp) ((sp)->slot)
483 #define sftk_isToken(id) (((id)&SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC)
484 
485 /* the session hash multiplier (see bug 201081) */
486 #define SHMULTIPLIER 1791398085
487 
488 /* queueing helper macros */
489 #define sftk_hash(value, size) \
490     ((PRUint32)((value)*SHMULTIPLIER) & (size - 1))
491 #define sftkqueue_add(element, id, head, hash_size) \
492     {                                               \
493         int tmp = sftk_hash(id, hash_size);         \
494         (element)->next = (head)[tmp];              \
495         (element)->prev = NULL;                     \
496         if ((head)[tmp])                            \
497             (head)[tmp]->prev = (element);          \
498         (head)[tmp] = (element);                    \
499     }
500 #define sftkqueue_find(element, id, head, hash_size)                      \
501     for ((element) = (head)[sftk_hash(id, hash_size)]; (element) != NULL; \
502          (element) = (element)->next) {                                   \
503         if ((element)->handle == (id)) {                                  \
504             break;                                                        \
505         }                                                                 \
506     }
507 #define sftkqueue_is_queued(element, id, head, hash_size) \
508     (((element)->next) || ((element)->prev) ||            \
509      ((head)[sftk_hash(id, hash_size)] == (element)))
510 #define sftkqueue_delete(element, id, head, hash_size)        \
511     if ((element)->next)                                      \
512         (element)->next->prev = (element)->prev;              \
513     if ((element)->prev)                                      \
514         (element)->prev->next = (element)->next;              \
515     else                                                      \
516         (head)[sftk_hash(id, hash_size)] = ((element)->next); \
517     (element)->next = NULL;                                   \
518     (element)->prev = NULL;
519 
520 #define sftkqueue_init_element(element) \
521     (element)->prev = NULL;
522 
523 #define sftkqueue_add2(element, id, index, head) \
524     {                                            \
525         (element)->next = (head)[index];         \
526         if ((head)[index])                       \
527             (head)[index]->prev = (element);     \
528         (head)[index] = (element);               \
529     }
530 
531 #define sftkqueue_find2(element, id, index, head) \
532     for ((element) = (head)[index];               \
533          (element) != NULL;                       \
534          (element) = (element)->next) {           \
535         if ((element)->handle == (id)) {          \
536             break;                                \
537         }                                         \
538     }
539 
540 #define sftkqueue_delete2(element, id, index, head) \
541     if ((element)->next)                            \
542         (element)->next->prev = (element)->prev;    \
543     if ((element)->prev)                            \
544         (element)->prev->next = (element)->next;    \
545     else                                            \
546         (head)[index] = ((element)->next);
547 
548 #define sftkqueue_clear_deleted_element(element) \
549     (element)->next = NULL;                      \
550     (element)->prev = NULL;
551 
552 /* sessionID (handle) is used to determine session lock bucket */
553 #ifdef NOSPREAD
554 /* NOSPREAD:    (ID>>L2LPB) & (perbucket-1) */
555 #define SFTK_SESSION_LOCK(slot, handle) \
556     ((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) & (slot)->sessionLockMask])
557 #else
558 /* SPREAD:  ID & (perbucket-1) */
559 #define SFTK_SESSION_LOCK(slot, handle) \
560     ((slot)->sessionLock[(handle) & (slot)->sessionLockMask])
561 #endif
562 
563 /* expand an attribute & secitem structures out */
564 #define sftk_attr_expand(ap) (ap)->type, (ap)->pValue, (ap)->ulValueLen
565 #define sftk_item_expand(ip) (ip)->data, (ip)->len
566 
567 typedef struct sftk_token_parametersStr {
568     CK_SLOT_ID slotID;
569     char *configdir;
570     char *certPrefix;
571     char *keyPrefix;
572     char *updatedir;
573     char *updCertPrefix;
574     char *updKeyPrefix;
575     char *updateID;
576     char *tokdes;
577     char *slotdes;
578     char *updtokdes;
579     int minPW;
580     PRBool readOnly;
581     PRBool noCertDB;
582     PRBool noKeyDB;
583     PRBool forceOpen;
584     PRBool pwRequired;
585     PRBool optimizeSpace;
586 } sftk_token_parameters;
587 
588 typedef struct sftk_parametersStr {
589     char *configdir;
590     char *updatedir;
591     char *updateID;
592     char *secmodName;
593     char *man;
594     char *libdes;
595     PRBool readOnly;
596     PRBool noModDB;
597     PRBool noCertDB;
598     PRBool forceOpen;
599     PRBool pwRequired;
600     PRBool optimizeSpace;
601     sftk_token_parameters *tokens;
602     int token_count;
603 } sftk_parameters;
604 
605 /* path stuff (was machine dependent) used by dbinit.c and pk11db.c */
606 #define CERT_DB_FMT "%scert%s.db"
607 #define KEY_DB_FMT "%skey%s.db"
608 
609 struct sftk_MACConstantTimeCtxStr {
610     const SECHashObject *hash;
611     unsigned char mac[64];
612     unsigned char secret[64];
613     unsigned int headerLength;
614     unsigned int secretLength;
615     unsigned int totalLength;
616     unsigned char header[75];
617 };
618 typedef struct sftk_MACConstantTimeCtxStr sftk_MACConstantTimeCtx;
619 
620 struct sftk_MACCtxStr {
621     /* This is a common MAC context that supports both HMAC and CMAC
622      * operations. This also presents a unified set of semantics:
623      *
624      *  - Everything except Destroy returns a CK_RV, indicating success
625      *    or failure. (This handles the difference between HMAC's and CMAC's
626      *    interfaces, since the underlying AES _might_ fail with CMAC).
627      *
628      *  - The underlying MAC is started on Init(...), so Update(...) can
629      *    called right away. (This handles the difference between HMAC and
630      *    CMAC in their *_Init(...) functions).
631      *
632      *  - Calling semantics:
633      *
634      *      - One of sftk_MAC_{Create,Init,InitRaw}(...) to set up the MAC
635      *        context, checking the return code.
636      *      - sftk_MAC_Update(...) as many times as necessary to process
637      *        input data, checking the return code.
638      *      - sftk_MAC_Finish(...) to get the output of the MAC; result_len
639      *        may be NULL if the caller knows the expected output length,
640      *        checking the return code. If result_len is NULL, this will
641      *        PR_ASSERT(...) that the actual returned length was equal to
642      *        max_result_len.
643      *
644      *        Note: unlike HMAC_Finish(...), this allows the caller to specify
645      *        a return value less than return length, to align with
646      *        CMAC_Finish(...)'s semantics. This will force an additional
647      *        stack allocation of size SFTK_MAX_MAC_LENGTH.
648      *      - sftk_MAC_Reset(...) if the caller wishes to compute a new MAC
649      *        with the same key, checking the return code.
650      *      - sftk_MAC_Destroy(...) when the caller frees its associated
651      *        memory, passing PR_TRUE if sftk_MAC_Create(...) was called,
652      *        and PR_FALSE otherwise.
653      */
654 
655     CK_MECHANISM_TYPE mech;
656     unsigned int mac_size;
657 
658     union {
659         HMACContext *hmac;
660         CMACContext *cmac;
661 
662         /* Functions to update when adding a new MAC or a new hash:
663          *
664          *  - sftk_MAC_Init
665          *  - sftk_MAC_Update
666          *  - sftk_MAC_Finish
667          *  - sftk_MAC_Reset
668          */
669         void *raw;
670     } mac;
671 
672     void (*destroy_func)(void *ctx, PRBool free_it);
673 };
674 typedef struct sftk_MACCtxStr sftk_MACCtx;
675 
676 extern CK_NSS_MODULE_FUNCTIONS sftk_module_funcList;
677 
678 SEC_BEGIN_PROTOS
679 
680 /* shared functions between pkcs11.c and fipstokn.c */
681 extern PRBool nsf_init;
682 extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
683 extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
684 extern PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV *crv);
685 extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent,
686                                    CK_SLOT_ID_PTR pSlotList,
687                                    CK_ULONG_PTR pulCount,
688                                    unsigned int moduleIndex);
689 
690 /* slot initialization, reinit, shutdown and destruction */
691 extern CK_RV SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
692                            sftk_token_parameters *params,
693                            unsigned int moduleIndex);
694 extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir,
695                              char *updatedir, char *updateID,
696                              sftk_token_parameters *params,
697                              unsigned int moduleIndex);
698 extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot);
699 extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot);
700 extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout);
701 
702 /* internal utility functions used by pkcs11.c */
703 extern CK_RV sftk_MapCryptError(int error);
704 extern CK_RV sftk_MapDecryptError(int error);
705 extern CK_RV sftk_MapVerifyError(int error);
706 extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object,
707                                          CK_ATTRIBUTE_TYPE type);
708 extern void sftk_FreeAttribute(SFTKAttribute *attribute);
709 extern CK_RV sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
710                                    const void *valPtr, CK_ULONG length);
711 extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
712                                     SFTKObject *object, CK_ATTRIBUTE_TYPE type);
713 extern CK_RV sftk_MultipleAttribute2SecItem(PLArenaPool *arena,
714                                             SFTKObject *object,
715                                             SFTKItemTemplate *templ, int count);
716 extern unsigned int sftk_GetLengthInBits(unsigned char *buf,
717                                          unsigned int bufLen);
718 extern CK_RV sftk_ConstrainAttribute(SFTKObject *object,
719                                      CK_ATTRIBUTE_TYPE type, int minLength,
720                                      int maxLength, int minMultiple);
721 extern PRBool sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
722 extern PRBool sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
723 extern void sftk_DeleteAttributeType(SFTKObject *object,
724                                      CK_ATTRIBUTE_TYPE type);
725 extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
726                                     SFTKObject *object, CK_ATTRIBUTE_TYPE type);
727 extern CK_RV sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item,
728                                      SFTKObject *object,
729                                      CK_ATTRIBUTE_TYPE type);
730 extern SFTKModifyType sftk_modifyType(CK_ATTRIBUTE_TYPE type,
731                                       CK_OBJECT_CLASS inClass);
732 extern PRBool sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass);
733 extern char *sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
734 extern void sftk_nullAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
735 extern CK_RV sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
736                                     CK_ULONG *longData);
737 extern CK_RV sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
738                                  const void *value, unsigned int len);
739 extern CK_RV sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
740                                    const void *value, unsigned int len);
741 extern unsigned int sftk_MapTrust(CK_TRUST trust, PRBool clientAuth);
742 
743 extern SFTKObject *sftk_NewObject(SFTKSlot *slot);
744 extern CK_RV sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject);
745 extern SFTKFreeStatus sftk_FreeObject(SFTKObject *object);
746 extern CK_RV sftk_DeleteObject(SFTKSession *session, SFTKObject *object);
747 extern void sftk_ReferenceObject(SFTKObject *object);
748 extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle,
749                                          SFTKSession *session);
750 extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object);
751 extern void sftk_AddObject(SFTKSession *session, SFTKObject *object);
752 /* clear out all the existing object ID to database key mappings.
753  * used to reinit a token */
754 extern CK_RV SFTK_ClearTokenKeyHashTable(SFTKSlot *slot);
755 
756 extern CK_RV sftk_searchObjectList(SFTKSearchResults *search,
757                                    SFTKObject **head, unsigned int size,
758                                    PZLock *lock, CK_ATTRIBUTE_PTR inTemplate,
759                                    int count, PRBool isLoggedIn);
760 extern SFTKObjectListElement *sftk_FreeObjectListElement(
761     SFTKObjectListElement *objectList);
762 extern void sftk_FreeObjectList(SFTKObjectListElement *objectList);
763 extern void sftk_FreeSearch(SFTKSearchResults *search);
764 extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session);
765 
766 extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all);
767 extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle);
768 extern CK_SLOT_ID sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle);
769 extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle);
770 extern void sftk_FreeSession(SFTKSession *session);
771 extern void sftk_DestroySession(SFTKSession *session);
772 extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify,
773                                     CK_VOID_PTR pApplication, CK_FLAGS flags);
774 extern void sftk_update_state(SFTKSlot *slot, SFTKSession *session);
775 extern void sftk_update_all_states(SFTKSlot *slot);
776 extern void sftk_InitFreeLists(void);
777 extern void sftk_CleanupFreeLists(void);
778 
779 /*
780  * Helper functions to handle the session crypto contexts
781  */
782 extern CK_RV sftk_InitGeneric(SFTKSession *session,
783                               SFTKSessionContext **contextPtr,
784                               SFTKContextType ctype, SFTKObject **keyPtr,
785                               CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr,
786                               CK_OBJECT_CLASS pubKeyType,
787                               CK_ATTRIBUTE_TYPE operation);
788 void sftk_SetContextByType(SFTKSession *session, SFTKContextType type,
789                            SFTKSessionContext *context);
790 extern CK_RV sftk_GetContext(CK_SESSION_HANDLE handle,
791                              SFTKSessionContext **contextPtr,
792                              SFTKContextType type, PRBool needMulti,
793                              SFTKSession **sessionPtr);
794 extern void sftk_TerminateOp(SFTKSession *session, SFTKContextType ctype,
795                              SFTKSessionContext *context);
796 extern void sftk_FreeContext(SFTKSessionContext *context);
797 
798 extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,
799                                           CK_KEY_TYPE key_type, CK_RV *crvp);
800 extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object,
801                                             CK_KEY_TYPE key_type, CK_RV *crvp);
802 extern CK_RV sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privKey, CK_KEY_TYPE keyType,
803                             NSSLOWKEYPublicKey *pubKey);
804 extern void sftk_FormatDESKey(unsigned char *key, int length);
805 extern PRBool sftk_CheckDESKey(unsigned char *key);
806 extern PRBool sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type);
807 extern void sftk_EncodeInteger(PRUint64 integer, CK_ULONG num_bits, CK_BBOOL littleEndian,
808                                CK_BYTE_PTR output, CK_ULONG_PTR output_len);
809 
810 /* ike and xcbc helpers */
811 extern CK_RV sftk_ike_prf(CK_SESSION_HANDLE hSession,
812                           const SFTKAttribute *inKey,
813                           const CK_NSS_IKE_PRF_DERIVE_PARAMS *params, SFTKObject *outKey);
814 extern CK_RV sftk_ike1_prf(CK_SESSION_HANDLE hSession,
815                            const SFTKAttribute *inKey,
816                            const CK_NSS_IKE1_PRF_DERIVE_PARAMS *params, SFTKObject *outKey,
817                            unsigned int keySize);
818 extern CK_RV sftk_ike1_appendix_b_prf(CK_SESSION_HANDLE hSession,
819                                       const SFTKAttribute *inKey,
820                                       const CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS *params,
821                                       SFTKObject *outKey,
822                                       unsigned int keySize);
823 extern CK_RV sftk_ike_prf_plus(CK_SESSION_HANDLE hSession,
824                                const SFTKAttribute *inKey,
825                                const CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *params, SFTKObject *outKey,
826                                unsigned int keySize);
827 extern CK_RV sftk_aes_xcbc_new_keys(CK_SESSION_HANDLE hSession,
828                                     CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE_PTR phKey,
829                                     unsigned char *k2, unsigned char *k3);
830 extern CK_RV sftk_xcbc_mac_pad(unsigned char *padBuf, unsigned int bufLen,
831                                unsigned int blockSize, const unsigned char *k2,
832                                const unsigned char *k3);
833 extern SECStatus sftk_fips_IKE_PowerUpSelfTests(void);
834 
835 /* mechanism allows this operation */
836 extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op);
837 
838 /* helper function which calls nsslowkey_FindKeyByPublicKey after safely
839  * acquiring a reference to the keydb from the slot */
840 NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey);
841 
842 /*
843  * parameter parsing functions
844  */
845 CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS);
846 void sftk_freeParams(sftk_parameters *params);
847 
848 /*
849  * narrow objects
850  */
851 SFTKSessionObject *sftk_narrowToSessionObject(SFTKObject *);
852 SFTKTokenObject *sftk_narrowToTokenObject(SFTKObject *);
853 
854 /*
855  * token object utilities
856  */
857 void sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle);
858 PRBool sftk_poisonHandle(SFTKSlot *slot, SECItem *dbkey,
859                          CK_OBJECT_HANDLE handle);
860 SFTKObject *sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey,
861                                 CK_OBJECT_HANDLE handle);
862 SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so);
863 
864 /* J-PAKE (jpakesftk.c) */
865 extern CK_RV jpake_Round1(HASH_HashType hashType,
866                           CK_NSS_JPAKERound1Params *params,
867                           SFTKObject *key);
868 extern CK_RV jpake_Round2(HASH_HashType hashType,
869                           CK_NSS_JPAKERound2Params *params,
870                           SFTKObject *sourceKey, SFTKObject *key);
871 extern CK_RV jpake_Final(HASH_HashType hashType,
872                          const CK_NSS_JPAKEFinalParams *params,
873                          SFTKObject *sourceKey, SFTKObject *key);
874 
875 /* Constant time MAC functions (hmacct.c) */
876 sftk_MACConstantTimeCtx *sftk_HMACConstantTime_New(
877     CK_MECHANISM_PTR mech, SFTKObject *key);
878 sftk_MACConstantTimeCtx *sftk_SSLv3MACConstantTime_New(
879     CK_MECHANISM_PTR mech, SFTKObject *key);
880 void sftk_HMACConstantTime_Update(void *pctx, const void *data, unsigned int len);
881 void sftk_SSLv3MACConstantTime_Update(void *pctx, const void *data, unsigned int len);
882 void sftk_MACConstantTime_EndHash(
883     void *pctx, void *out, unsigned int *outLength, unsigned int maxLength);
884 void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool);
885 
886 /****************************************
887  * implement TLS Pseudo Random Function (PRF)
888  */
889 
890 extern CK_RV
891 sftk_TLSPRFInit(SFTKSessionContext *context,
892                 SFTKObject *key,
893                 CK_KEY_TYPE key_type,
894                 HASH_HashType hash_alg,
895                 unsigned int out_len);
896 
897 /* PKCS#11 MAC implementation. See sftk_MACCtxStr declaration above for
898  * calling semantics for these functions. */
899 HASH_HashType sftk_HMACMechanismToHash(CK_MECHANISM_TYPE mech);
900 CK_RV sftk_MAC_Create(CK_MECHANISM_TYPE mech, SFTKObject *key, sftk_MACCtx **ret_ctx);
901 CK_RV sftk_MAC_Init(sftk_MACCtx *ctx, CK_MECHANISM_TYPE mech, SFTKObject *key);
902 CK_RV sftk_MAC_InitRaw(sftk_MACCtx *ctx, CK_MECHANISM_TYPE mech, const unsigned char *key, unsigned int key_len, PRBool isFIPS);
903 CK_RV sftk_MAC_Update(sftk_MACCtx *ctx, CK_BYTE_PTR data, unsigned int data_len);
904 CK_RV sftk_MAC_Finish(sftk_MACCtx *ctx, CK_BYTE_PTR result, unsigned int *result_len, unsigned int max_result_len);
905 CK_RV sftk_MAC_Reset(sftk_MACCtx *ctx);
906 void sftk_MAC_Destroy(sftk_MACCtx *ctx, PRBool free_it);
907 
908 /* constant time helpers */
909 unsigned int sftk_CKRVToMask(CK_RV rv);
910 CK_RV sftk_CheckCBCPadding(CK_BYTE_PTR pBuf, unsigned int bufLen,
911                            unsigned int blockSize, unsigned int *outPadSize);
912 
913 /* NIST 800-108 (kbkdf.c) implementations */
914 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);
915 char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
916 
917 SEC_END_PROTOS
918 
919 #endif /* _PKCS11I_H_ */
920