1 /*
2  * pk11mode.c - Test FIPS or NONFIPS Modes for the NSS PKCS11 api.
3  *              The goal of this program is to test every function
4  *              entry point of the PKCS11 api at least once.
5  *              To test in FIPS mode: pk11mode
6  *              To test in NONFIPS mode: pk11mode -n
7  *              usage: pk11mode -h
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
12 
13 #include <assert.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <stdarg.h>
18 
19 #if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
20 #include <unistd.h>
21 #include <sys/wait.h>
22 #else
23 #ifndef NO_FORK_CHECK
24 #define NO_FORK_CHECK
25 #endif
26 #endif
27 
28 #ifdef _WIN32
29 #include <windows.h>
30 #define LIB_NAME "softokn3.dll"
31 #endif
32 #include "prlink.h"
33 #include "prprf.h"
34 #include "plgetopt.h"
35 #include "prenv.h"
36 
37 #include "pk11table.h"
38 
39 #define NUM_ELEM(array) (sizeof(array) / sizeof(array[0]))
40 
41 #ifndef NULL_PTR
42 #define NULL_PTR 0
43 #endif
44 
45 /* Returns constant error string for "CRV".
46  * Returns "unknown error" if errNum is unknown.
47  */
48 const char *
PKM_CK_RVtoStr(CK_RV errNum)49 PKM_CK_RVtoStr(CK_RV errNum)
50 {
51     const char *err;
52 
53     err = getName(errNum, ConstResult);
54 
55     if (err)
56         return err;
57 
58     return "unknown error";
59 }
60 
61 #include "pkcs11p.h"
62 
63 typedef struct CK_C_INITIALIZE_ARGS_NSS {
64     CK_CREATEMUTEX CreateMutex;
65     CK_DESTROYMUTEX DestroyMutex;
66     CK_LOCKMUTEX LockMutex;
67     CK_UNLOCKMUTEX UnlockMutex;
68     CK_FLAGS flags;
69     /* The official PKCS #11 spec does not have a 'LibraryParameters' field, but
70      * a reserved field. NSS needs a way to pass instance-specific information
71      * to the library (like where to find its config files, etc). This
72      * information is usually provided by the installer and passed uninterpreted
73      * by NSS to the library, though NSS does know the specifics of the softoken
74      * version of this parameter. Most compliant PKCS#11 modules expect this
75      * parameter to be NULL, and will return CKR_ARGUMENTS_BAD from
76      * C_Initialize if Library parameters is supplied. */
77     CK_CHAR_PTR *LibraryParameters;
78     /* This field is only present if the LibraryParameters is not NULL. It must
79      * be NULL in all cases */
80     CK_VOID_PTR pReserved;
81 } CK_C_INITIALIZE_ARGS_NSS;
82 
83 #include "pkcs11u.h"
84 
85 #define MAX_SIG_SZ 128
86 #define MAX_CIPHER_SZ 128
87 #define MAX_DATA_SZ 64
88 #define MAX_DIGEST_SZ 64
89 #define HMAC_MAX_LENGTH 64
90 #define FIPSMODE 0
91 #define NONFIPSMODE 1
92 #define HYBRIDMODE 2
93 #define NOMODE 3
94 int MODE = FIPSMODE;
95 
96 CK_BBOOL true = CK_TRUE;
97 CK_BBOOL false = CK_FALSE;
98 static const CK_BYTE PLAINTEXT[] = { "Firefox  Rules!" };
99 static const CK_BYTE PLAINTEXT_PAD[] =
100     { "Firefox and thunderbird rule the world!" };
101 CK_ULONG NUMTESTS = 0;
102 
103 static const char *slotFlagName[] = {
104     "CKF_TOKEN_PRESENT",
105     "CKF_REMOVABLE_DEVICE",
106     "CKF_HW_SLOT",
107     "unknown token flag 0x00000008",
108     "unknown token flag 0x00000010",
109     "unknown token flag 0x00000020",
110     "unknown token flag 0x00000040",
111     "unknown token flag 0x00000080",
112     "unknown token flag 0x00000100",
113     "unknown token flag 0x00000200",
114     "unknown token flag 0x00000400",
115     "unknown token flag 0x00000800",
116     "unknown token flag 0x00001000",
117     "unknown token flag 0x00002000",
118     "unknown token flag 0x00004000",
119     "unknown token flag 0x00008000"
120     "unknown token flag 0x00010000",
121     "unknown token flag 0x00020000",
122     "unknown token flag 0x00040000",
123     "unknown token flag 0x00080000",
124     "unknown token flag 0x00100000",
125     "unknown token flag 0x00200000",
126     "unknown token flag 0x00400000",
127     "unknown token flag 0x00800000"
128     "unknown token flag 0x01000000",
129     "unknown token flag 0x02000000",
130     "unknown token flag 0x04000000",
131     "unknown token flag 0x08000000",
132     "unknown token flag 0x10000000",
133     "unknown token flag 0x20000000",
134     "unknown token flag 0x40000000",
135     "unknown token flag 0x80000000"
136 };
137 
138 static const char *tokenFlagName[] = {
139     "CKF_PKM_RNG",
140     "CKF_WRITE_PROTECTED",
141     "CKF_LOGIN_REQUIRED",
142     "CKF_USER_PIN_INITIALIZED",
143     "unknown token flag 0x00000010",
144     "CKF_RESTORE_KEY_NOT_NEEDED",
145     "CKF_CLOCK_ON_TOKEN",
146     "unknown token flag 0x00000080",
147     "CKF_PROTECTED_AUTHENTICATION_PATH",
148     "CKF_DUAL_CRYPTO_OPERATIONS",
149     "CKF_TOKEN_INITIALIZED",
150     "CKF_SECONDARY_AUTHENTICATION",
151     "unknown token flag 0x00001000",
152     "unknown token flag 0x00002000",
153     "unknown token flag 0x00004000",
154     "unknown token flag 0x00008000",
155     "CKF_USER_PIN_COUNT_LOW",
156     "CKF_USER_PIN_FINAL_TRY",
157     "CKF_USER_PIN_LOCKED",
158     "CKF_USER_PIN_TO_BE_CHANGED",
159     "CKF_SO_PIN_COUNT_LOW",
160     "CKF_SO_PIN_FINAL_TRY",
161     "CKF_SO_PIN_LOCKED",
162     "CKF_SO_PIN_TO_BE_CHANGED",
163     "unknown token flag 0x01000000",
164     "unknown token flag 0x02000000",
165     "unknown token flag 0x04000000",
166     "unknown token flag 0x08000000",
167     "unknown token flag 0x10000000",
168     "unknown token flag 0x20000000",
169     "unknown token flag 0x40000000",
170     "unknown token flag 0x80000000"
171 };
172 
173 static const unsigned char TLSClientRandom[] = {
174     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176     0x0d, 0x90, 0xbb, 0x5e, 0xc6, 0xe1, 0x3f, 0x71,
177     0x0a, 0xa2, 0x70, 0x5a, 0x4f, 0xbc, 0x3f, 0x0d
178 };
179 static const unsigned char TLSServerRandom[] = {
180     0x00, 0x00, 0x1d, 0x4a, 0x7a, 0x0a, 0xa5, 0x01,
181     0x8e, 0x79, 0x72, 0xde, 0x9e, 0x2f, 0x8a, 0x0d,
182     0xed, 0xb2, 0x5d, 0xf1, 0x14, 0xc2, 0xc6, 0x66,
183     0x95, 0x86, 0xb0, 0x0d, 0x87, 0x2a, 0x2a, 0xc9
184 };
185 
186 typedef enum {
187     CORRECT,
188     BOGUS_CLIENT_RANDOM,
189     BOGUS_CLIENT_RANDOM_LEN,
190     BOGUS_SERVER_RANDOM,
191     BOGUS_SERVER_RANDOM_LEN
192 } enum_random_t;
193 
194 void
dumpToHash64(const unsigned char * buf,unsigned int bufLen)195 dumpToHash64(const unsigned char *buf, unsigned int bufLen)
196 {
197     unsigned int i;
198     for (i = 0; i < bufLen; i += 8) {
199         if (i % 32 == 0)
200             printf("\n");
201         printf(" 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,",
202                buf[i], buf[i + 1], buf[i + 2], buf[i + 3],
203                buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
204     }
205     printf("\n");
206 }
207 
208 #ifdef _WIN32
209 HMODULE hModule;
210 #else
211 PRLibrary *lib;
212 #endif
213 
214 /*
215 * All api that belongs to pk11mode.c layer start with the prefix PKM_
216 */
217 void PKM_LogIt(const char *fmt, ...);
218 void PKM_Error(const char *fmt, ...);
219 CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
220                             CK_ULONG slotID);
221 CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID);
222 CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
223                       CK_SLOT_ID *pSlotList, CK_ULONG slotID,
224                       CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
225 CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
226                     CK_SLOT_ID *pSlotList, CK_ULONG slotID);
227 CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
228               CK_ULONG slotID);
229 CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,
230                        CK_SLOT_ID *pSlotList, CK_ULONG slotID,
231                        CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
232 CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
233                     CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
234 CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
235                     CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
236 CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
237                      CK_C_INITIALIZE_ARGS_NSS *initArgs);
238 CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,
239                          CK_SLOT_ID *pSlotList, CK_ULONG slotID,
240                          CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
241 CK_RV PKM_MultiObjectManagement(CK_FUNCTION_LIST_PTR pFunctionList,
242                                 CK_SLOT_ID *pSlotList, CK_ULONG slotID,
243                                 CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
244 CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,
245                            CK_SLOT_ID *pSlotList, CK_ULONG slotID,
246                            CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
247 CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
248                           CK_SLOT_ID *pSlotList, CK_ULONG slotID,
249                           CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
250 CK_RV PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,
251                          CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj,
252                          CK_ATTRIBUTE_PTR expected_attrs,
253                          CK_ULONG expected_attrs_count);
254 CK_RV PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList,
255                     CK_SESSION_HANDLE hSession, CK_MECHANISM_TYPE mechType,
256                     CK_FLAGS flags, CK_BBOOL check_sizes,
257                     CK_ULONG minkeysize, CK_ULONG maxkeysize);
258 CK_RV PKM_TLSKeyAndMacDerive(CK_FUNCTION_LIST_PTR pFunctionList,
259                              CK_SLOT_ID *pSlotList, CK_ULONG slotID,
260                              CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
261                              CK_MECHANISM_TYPE mechType, enum_random_t rnd);
262 CK_RV PKM_TLSMasterKeyDerive(CK_FUNCTION_LIST_PTR pFunctionList,
263                              CK_SLOT_ID *pSlotList, CK_ULONG slotID,
264                              CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
265                              CK_MECHANISM_TYPE mechType,
266                              enum_random_t rnd);
267 CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
268                    CK_SLOT_ID *pSlotList, CK_ULONG slotID,
269                    CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
270 CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,
271                        CK_SESSION_HANDLE hRwSession,
272                        CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey,
273                        CK_MECHANISM *sigMech, CK_OBJECT_HANDLE secretKey,
274                        CK_MECHANISM *cryptMech,
275                        const CK_BYTE *pData, CK_ULONG pDataLen);
276 CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,
277                          CK_SESSION_HANDLE hSession,
278                          CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech,
279                          CK_OBJECT_HANDLE hSecKeyDigest,
280                          CK_MECHANISM *digestMech,
281                          const CK_BYTE *pData, CK_ULONG pDataLen);
282 CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList,
283                      CK_SESSION_HANDLE hRwSession,
284                      CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
285                      CK_MECHANISM *signMech, const CK_BYTE *pData,
286                      CK_ULONG dataLen);
287 CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList,
288                       CK_SESSION_HANDLE hSession,
289                       CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech,
290                       const CK_BYTE *pData, CK_ULONG dataLen);
291 CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
292                CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech,
293                const CK_BYTE *pData, CK_ULONG pDataLen);
294 CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList,
295                  CK_SESSION_HANDLE hRwSession,
296                  CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey,
297                  const CK_BYTE *pData, CK_ULONG pDataLen);
298 CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,
299                      CK_SESSION_HANDLE hSession,
300                      CK_OBJECT_HANDLE hPublicKey,
301                      CK_OBJECT_HANDLE hPrivateKey,
302                      CK_MECHANISM *wrapMechanism,
303                      CK_OBJECT_HANDLE hSecretKey,
304                      CK_ATTRIBUTE *sKeyTemplate,
305                      CK_ULONG skeyTempSize);
306 CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
307                            CK_SESSION_HANDLE hSession,
308                            CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
309                            CK_MECHANISM *signMech, const CK_BYTE *pData,
310                            CK_ULONG pDataLen);
311 CK_RV PKM_ForkCheck(int expected, CK_FUNCTION_LIST_PTR fList,
312                     PRBool forkAssert, CK_C_INITIALIZE_ARGS_NSS *initArgs);
313 
314 void PKM_Help();
315 void PKM_CheckPath(char *string);
316 char *PKM_FilePasswd(char *pwFile);
317 static PRBool verbose = PR_FALSE;
318 
319 int
main(int argc,char ** argv)320 main(int argc, char **argv)
321 {
322     CK_C_GetFunctionList pC_GetFunctionList;
323     CK_FUNCTION_LIST_PTR pFunctionList;
324     CK_RV crv = CKR_OK;
325     CK_C_INITIALIZE_ARGS_NSS initArgs;
326     CK_SLOT_ID *pSlotList = NULL;
327     CK_TOKEN_INFO tokenInfo;
328     CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */
329 
330     CK_UTF8CHAR *pwd = NULL;
331     CK_ULONG pwdLen = 0;
332     char *moduleSpec = NULL;
333     char *configDir = NULL;
334     char *dbPrefix = NULL;
335     char *disableUnload = NULL;
336     PRBool doForkTests = PR_TRUE;
337 
338     PLOptStatus os;
339     PLOptState *opt = PL_CreateOptState(argc, argv, "nvhf:Fd:p:");
340     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
341         if (PL_OPT_BAD == os)
342             continue;
343         switch (opt->option) {
344             case 'F': /* disable fork tests */
345                 doForkTests = PR_FALSE;
346                 break;
347             case 'n': /* non fips mode */
348                 MODE = NONFIPSMODE;
349                 slotID = 1;
350                 break;
351             case 'f': /* password file */
352                 pwd = (CK_UTF8CHAR *)PKM_FilePasswd((char *)opt->value);
353                 if (!pwd)
354                     PKM_Help();
355                 break;
356             case 'd': /* opt_CertDir */
357                 if (!opt->value)
358                     PKM_Help();
359                 configDir = strdup(opt->value);
360                 PKM_CheckPath(configDir);
361                 break;
362             case 'p': /* opt_DBPrefix */
363                 if (!opt->value)
364                     PKM_Help();
365                 dbPrefix = strdup(opt->value);
366                 break;
367             case 'v':
368                 verbose = PR_TRUE;
369                 break;
370             case 'h': /* help message */
371             default:
372                 PKM_Help();
373                 break;
374         }
375     }
376     PL_DestroyOptState(opt);
377 
378     if (!pwd) {
379         pwd = (CK_UTF8CHAR *)strdup("1Mozilla");
380     }
381     pwdLen = strlen((const char *)pwd);
382     if (!configDir) {
383         configDir = strdup(".");
384     }
385     if (!dbPrefix) {
386         dbPrefix = strdup("");
387     }
388 
389     if (doForkTests) {
390         /* first, try to fork without softoken loaded to make sure
391          * everything is OK */
392         crv = PKM_ForkCheck(123, NULL, PR_FALSE, NULL);
393         if (crv != CKR_OK)
394             goto cleanup;
395     }
396 
397 #ifdef _WIN32
398     hModule = LoadLibrary(LIB_NAME);
399     if (hModule == NULL) {
400         PKM_Error("cannot load %s\n", LIB_NAME);
401         goto cleanup;
402     }
403     if (MODE == FIPSMODE) {
404         /* FIPS mode == FC_GetFunctionList */
405         pC_GetFunctionList = (CK_C_GetFunctionList)
406             GetProcAddress(hModule, "FC_GetFunctionList");
407     } else {
408         /* NON FIPS mode  == C_GetFunctionList */
409         pC_GetFunctionList = (CK_C_GetFunctionList)
410             GetProcAddress(hModule, "C_GetFunctionList");
411     }
412     if (pC_GetFunctionList == NULL) {
413         PKM_Error("cannot load %s\n", LIB_NAME);
414         goto cleanup;
415     }
416 #else
417     {
418         char *libname = NULL;
419         /* Get the platform-dependent library name of the NSS cryptographic module */
420         libname = PR_GetLibraryName(NULL, "softokn3");
421         assert(libname != NULL);
422         lib = PR_LoadLibrary(libname);
423         assert(lib != NULL);
424         PR_FreeLibraryName(libname);
425     }
426     if (MODE == FIPSMODE) {
427         pC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
428                                                                          "FC_GetFunctionList");
429         assert(pC_GetFunctionList != NULL);
430         slotID = 0;
431     } else {
432         pC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
433                                                                          "C_GetFunctionList");
434         assert(pC_GetFunctionList != NULL);
435         slotID = 1;
436     }
437 #endif
438 
439     if (MODE == FIPSMODE) {
440         printf("Loaded FC_GetFunctionList for FIPS MODE; slotID %d \n",
441                (int)slotID);
442     } else {
443         printf("loaded C_GetFunctionList for NON FIPS MODE; slotID %d \n",
444                (int)slotID);
445     }
446 
447     crv = (*pC_GetFunctionList)(&pFunctionList);
448     assert(crv == CKR_OK);
449 
450     if (doForkTests) {
451         /* now, try to fork with softoken loaded, but not initialized */
452         crv = PKM_ForkCheck(CKR_CRYPTOKI_NOT_INITIALIZED, pFunctionList,
453                             PR_TRUE, NULL);
454         if (crv != CKR_OK)
455             goto cleanup;
456     }
457 
458     initArgs.CreateMutex = NULL;
459     initArgs.DestroyMutex = NULL;
460     initArgs.LockMutex = NULL;
461     initArgs.UnlockMutex = NULL;
462     initArgs.flags = CKF_OS_LOCKING_OK;
463     moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' "
464                              "keyPrefix='%s' secmod='secmod.db' flags= ",
465                              configDir, dbPrefix, dbPrefix);
466     initArgs.LibraryParameters = (CK_CHAR_PTR *)moduleSpec;
467     initArgs.pReserved = NULL;
468 
469     /*DebugBreak();*/
470     /* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */
471     /* NSS cryptographic module library initialization for the FIPS  */
472     /* Approved mode when FC_Initialize is envoked will perfom       */
473     /* software integrity test, and power-up self-tests before       */
474     /* FC_Initialize returns                                         */
475     crv = pFunctionList->C_Initialize(&initArgs);
476     if (crv == CKR_OK) {
477         PKM_LogIt("C_Initialize succeeded\n");
478     } else {
479         PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv,
480                   PKM_CK_RVtoStr(crv));
481         goto cleanup;
482     }
483 
484     if (doForkTests) {
485         /* Disable core on fork for this test, since we are testing the
486          * pathological case, and if enabled, the child process would dump
487          * core in C_GetTokenInfo .
488          * We can still differentiate the correct from incorrect behavior
489          * by the PKCS#11 return code.
490          */
491         /* try to fork with softoken both loaded and initialized */
492         crv = PKM_ForkCheck(CKR_DEVICE_ERROR, pFunctionList, PR_FALSE, NULL);
493         if (crv != CKR_OK)
494             goto cleanup;
495     }
496 
497     if (doForkTests) {
498         /* In this next test, we fork and try to re-initialize softoken in
499          * the child. This should now work because softoken has the ability
500          * to hard reset.
501          */
502         /* try to fork with softoken both loaded and initialized */
503         crv = PKM_ForkCheck(CKR_OK, pFunctionList, PR_TRUE, &initArgs);
504         if (crv != CKR_OK)
505             goto cleanup;
506     }
507 
508     crv = PKM_ShowInfo(pFunctionList, slotID);
509     if (crv == CKR_OK) {
510         PKM_LogIt("PKM_ShowInfo succeeded\n");
511     } else {
512         PKM_Error("PKM_ShowInfo failed with 0x%08X, %-26s\n", crv,
513                   PKM_CK_RVtoStr(crv));
514         goto cleanup;
515     }
516     pSlotList = PKM_GetSlotList(pFunctionList, slotID);
517     if (pSlotList == NULL) {
518         PKM_Error("PKM_GetSlotList failed with \n");
519         goto cleanup;
520     }
521     crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
522     if (crv == CKR_OK) {
523         PKM_LogIt("C_GetTokenInfo succeeded\n\n");
524     } else {
525         PKM_Error("C_GetTokenInfo failed with 0x%08X, %-26s\n", crv,
526                   PKM_CK_RVtoStr(crv));
527         goto cleanup;
528     }
529 
530     if (!(tokenInfo.flags & CKF_USER_PIN_INITIALIZED)) {
531         PKM_LogIt("Initing PW for DB\n");
532         crv = PKM_InitPWforDB(pFunctionList, pSlotList, slotID,
533                               pwd, pwdLen);
534         if (crv == CKR_OK) {
535             PKM_LogIt("PKM_InitPWforDB succeeded\n\n");
536         } else {
537             PKM_Error("PKM_InitPWforDB failed with 0x%08X, %-26s\n", crv,
538                       PKM_CK_RVtoStr(crv));
539             goto cleanup;
540         }
541     } else {
542         PKM_LogIt("using existing DB\n");
543     }
544 
545     /* general mechanism by token */
546     crv = PKM_Mechanism(pFunctionList, pSlotList, slotID);
547     if (crv == CKR_OK) {
548         PKM_LogIt("PKM_Mechanism succeeded\n\n");
549     } else {
550         PKM_Error("PKM_Mechanism failed with 0x%08X, %-26s\n", crv,
551                   PKM_CK_RVtoStr(crv));
552         goto cleanup;
553     }
554     /* RNG example without Login */
555     crv = PKM_RNG(pFunctionList, pSlotList, slotID);
556     if (crv == CKR_OK) {
557         PKM_LogIt("PKM_RNG succeeded\n\n");
558     } else {
559         PKM_Error("PKM_RNG failed with 0x%08X, %-26s\n", crv,
560                   PKM_CK_RVtoStr(crv));
561         goto cleanup;
562     }
563 
564     crv = PKM_SessionLogin(pFunctionList, pSlotList, slotID,
565                            pwd, pwdLen);
566     if (crv == CKR_OK) {
567         PKM_LogIt("PKM_SessionLogin succeeded\n\n");
568     } else {
569         PKM_Error("PKM_SessionLogin failed with 0x%08X, %-26s\n", crv,
570                   PKM_CK_RVtoStr(crv));
571         goto cleanup;
572     }
573 
574     /*
575      * PKM_KeyTest creates RSA,DSA public keys
576      * and AES, DES3 secret keys.
577      * then does digest, hmac, encrypt/decrypt, signing operations.
578      */
579     crv = PKM_KeyTests(pFunctionList, pSlotList, slotID,
580                        pwd, pwdLen);
581     if (crv == CKR_OK) {
582         PKM_LogIt("PKM_KeyTests succeeded\n\n");
583     } else {
584         PKM_Error("PKM_KeyTest failed with 0x%08X, %-26s\n", crv,
585                   PKM_CK_RVtoStr(crv));
586         goto cleanup;
587     }
588 
589     crv = PKM_SecretKey(pFunctionList, pSlotList, slotID, pwd,
590                         pwdLen);
591     if (crv == CKR_OK) {
592         PKM_LogIt("PKM_SecretKey succeeded\n\n");
593     } else {
594         PKM_Error("PKM_SecretKey failed with 0x%08X, %-26s\n", crv,
595                   PKM_CK_RVtoStr(crv));
596         goto cleanup;
597     }
598 
599     crv = PKM_PublicKey(pFunctionList, pSlotList, slotID,
600                         pwd, pwdLen);
601     if (crv == CKR_OK) {
602         PKM_LogIt("PKM_PublicKey succeeded\n\n");
603     } else {
604         PKM_Error("PKM_PublicKey failed with 0x%08X, %-26s\n", crv,
605                   PKM_CK_RVtoStr(crv));
606         goto cleanup;
607     }
608     crv = PKM_OperationalState(pFunctionList, pSlotList, slotID,
609                                pwd, pwdLen);
610     if (crv == CKR_OK) {
611         PKM_LogIt("PKM_OperationalState succeeded\n\n");
612     } else {
613         PKM_Error("PKM_OperationalState failed with 0x%08X, %-26s\n", crv,
614                   PKM_CK_RVtoStr(crv));
615         goto cleanup;
616     }
617     crv = PKM_MultiObjectManagement(pFunctionList, pSlotList, slotID,
618                                     pwd, pwdLen);
619     if (crv == CKR_OK) {
620         PKM_LogIt("PKM_MultiObjectManagement succeeded\n\n");
621     } else {
622         PKM_Error("PKM_MultiObjectManagement failed with 0x%08X, %-26s\n", crv,
623                   PKM_CK_RVtoStr(crv));
624         goto cleanup;
625     }
626     crv = PKM_LegacyFunctions(pFunctionList, pSlotList, slotID,
627                               pwd, pwdLen);
628     if (crv == CKR_OK) {
629         PKM_LogIt("PKM_LegacyFunctions succeeded\n\n");
630     } else {
631         PKM_Error("PKM_LegacyFunctions failed with 0x%08X, %-26s\n", crv,
632                   PKM_CK_RVtoStr(crv));
633         goto cleanup;
634     }
635     crv = PKM_TLSKeyAndMacDerive(pFunctionList, pSlotList, slotID,
636                                  pwd, pwdLen,
637                                  CKM_TLS_KEY_AND_MAC_DERIVE, CORRECT);
638 
639     if (crv == CKR_OK) {
640         PKM_LogIt("PKM_TLSKeyAndMacDerive succeeded\n\n");
641     } else {
642         PKM_Error("PKM_TLSKeyAndMacDerive failed with 0x%08X, %-26s\n", crv,
643                   PKM_CK_RVtoStr(crv));
644         goto cleanup;
645     }
646     crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
647                                  pwd, pwdLen,
648                                  CKM_TLS_MASTER_KEY_DERIVE,
649                                  CORRECT);
650     if (crv == CKR_OK) {
651         PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
652     } else {
653         PKM_Error("PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv,
654                   PKM_CK_RVtoStr(crv));
655         goto cleanup;
656     }
657     crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
658                                  pwd, pwdLen,
659                                  CKM_TLS_MASTER_KEY_DERIVE_DH,
660                                  CORRECT);
661     if (crv == CKR_OK) {
662         PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
663     } else {
664         PKM_Error("PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv,
665                   PKM_CK_RVtoStr(crv));
666         goto cleanup;
667     }
668     crv = PKM_FindAllObjects(pFunctionList, pSlotList, slotID,
669                              pwd, pwdLen);
670     if (crv == CKR_OK) {
671         PKM_LogIt("PKM_FindAllObjects succeeded\n\n");
672     } else {
673         PKM_Error("PKM_FindAllObjects failed with 0x%08X, %-26s\n", crv,
674                   PKM_CK_RVtoStr(crv));
675         goto cleanup;
676     }
677     crv = pFunctionList->C_Finalize(NULL);
678     if (crv == CKR_OK) {
679         PKM_LogIt("C_Finalize succeeded\n");
680     } else {
681         PKM_Error("C_Finalize failed with 0x%08X, %-26s\n", crv,
682                   PKM_CK_RVtoStr(crv));
683         goto cleanup;
684     }
685 
686     if (doForkTests) {
687         /* try to fork with softoken still loaded, but de-initialized */
688         crv = PKM_ForkCheck(CKR_CRYPTOKI_NOT_INITIALIZED, pFunctionList,
689                             PR_TRUE, NULL);
690         if (crv != CKR_OK)
691             goto cleanup;
692     }
693 
694     free(pSlotList);
695 
696     /* demonstrate how an application can be in Hybrid mode */
697     /* PKM_HybridMode shows how to switch between NONFIPS */
698     /* mode to FIPS mode */
699 
700     PKM_LogIt("Testing Hybrid mode \n");
701     crv = PKM_HybridMode(pwd, pwdLen, &initArgs);
702     if (crv == CKR_OK) {
703         PKM_LogIt("PKM_HybridMode succeeded\n");
704     } else {
705         PKM_Error("PKM_HybridMode failed with 0x%08X, %-26s\n", crv,
706                   PKM_CK_RVtoStr(crv));
707         goto cleanup;
708     }
709 
710     if (doForkTests) {
711         /* testing one more C_Initialize / C_Finalize to exercise getpid()
712          * fork check code */
713         crv = pFunctionList->C_Initialize(&initArgs);
714         if (crv == CKR_OK) {
715             PKM_LogIt("C_Initialize succeeded\n");
716         } else {
717             PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv,
718                       PKM_CK_RVtoStr(crv));
719             goto cleanup;
720         }
721         crv = pFunctionList->C_Finalize(NULL);
722         if (crv == CKR_OK) {
723             PKM_LogIt("C_Finalize succeeded\n");
724         } else {
725             PKM_Error("C_Finalize failed with 0x%08X, %-26s\n", crv,
726                       PKM_CK_RVtoStr(crv));
727             goto cleanup;
728         }
729         /* try to C_Initialize / C_Finalize in child. This should succeed */
730         crv = PKM_ForkCheck(CKR_OK, pFunctionList, PR_TRUE, &initArgs);
731     }
732 
733     PKM_LogIt("unloading NSS PKCS # 11 softoken and exiting\n");
734 
735 cleanup:
736 
737     if (pwd) {
738         free(pwd);
739     }
740     if (configDir) {
741         free(configDir);
742     }
743     if (dbPrefix) {
744         free(dbPrefix);
745     }
746     if (moduleSpec) {
747         PR_smprintf_free(moduleSpec);
748     }
749 
750 #ifdef _WIN32
751     FreeLibrary(hModule);
752 #else
753     disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
754     if (!disableUnload) {
755         PR_UnloadLibrary(lib);
756     }
757 #endif
758     if (CKR_OK == crv && doForkTests && !disableUnload) {
759         /* try to fork with softoken both de-initialized and unloaded */
760         crv = PKM_ForkCheck(123, NULL, PR_TRUE, NULL);
761     }
762 
763     printf("**** Total number of TESTS ran in %s is %d. ****\n",
764            ((MODE == FIPSMODE) ? "FIPS MODE" : "NON FIPS MODE"), (int)NUMTESTS);
765     if (CKR_OK == crv) {
766         printf("**** ALL TESTS PASSED ****\n");
767     }
768 
769     return crv;
770 }
771 
772 /*
773 *  PKM_KeyTests
774 *
775 *
776 */
777 
778 CK_RV
PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)779 PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
780              CK_SLOT_ID *pSlotList, CK_ULONG slotID,
781              CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
782 {
783     CK_SESSION_HANDLE hRwSession;
784 
785     CK_RV crv = CKR_OK;
786 
787     /*** DSA Key ***/
788     CK_MECHANISM dsaParamGenMech;
789     CK_ULONG primeBits = 1024;
790     CK_ATTRIBUTE dsaParamGenTemplate[1];
791     CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE;
792     CK_BYTE DSA_P[128];
793     CK_BYTE DSA_Q[20];
794     CK_BYTE DSA_G[128];
795     CK_MECHANISM dsaKeyPairGenMech;
796     CK_ATTRIBUTE dsaPubKeyTemplate[5];
797     CK_ATTRIBUTE dsaPrivKeyTemplate[5];
798     CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
799     CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
800 
801     /**** RSA Key ***/
802     CK_KEY_TYPE rsatype = CKK_RSA;
803     CK_MECHANISM rsaKeyPairGenMech;
804     CK_BYTE subject[] = { "RSA Private Key" };
805     CK_ULONG modulusBits = 1024;
806     CK_BYTE publicExponent[] = { 0x01, 0x00, 0x01 };
807     CK_BYTE id[] = { "RSA123" };
808     CK_ATTRIBUTE rsaPubKeyTemplate[9];
809     CK_ATTRIBUTE rsaPrivKeyTemplate[11];
810     CK_OBJECT_HANDLE hRSApubKey = CK_INVALID_HANDLE;
811     CK_OBJECT_HANDLE hRSAprivKey = CK_INVALID_HANDLE;
812 
813     /*** AES Key ***/
814     CK_MECHANISM sAESKeyMech = {
815         CKM_AES_KEY_GEN, NULL, 0
816     };
817     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
818     CK_KEY_TYPE keyAESType = CKK_AES;
819     CK_UTF8CHAR AESlabel[] = "An AES secret key object";
820     CK_ULONG AESvalueLen = 32;
821     CK_ATTRIBUTE sAESKeyTemplate[9];
822     CK_OBJECT_HANDLE hAESSecKey;
823 
824     /*** DES3 Key ***/
825     CK_KEY_TYPE keyDES3Type = CKK_DES3;
826     CK_UTF8CHAR DES3label[] = "An Triple DES secret key object";
827     CK_ULONG DES3valueLen = 56;
828     CK_MECHANISM sDES3KeyGenMechanism = {
829         CKM_DES3_KEY_GEN, NULL, 0
830     };
831     CK_ATTRIBUTE sDES3KeyTemplate[9];
832     CK_OBJECT_HANDLE hDES3SecKey;
833 
834     CK_MECHANISM dsaWithSha1Mech = {
835         CKM_DSA_SHA1, NULL, 0
836     };
837 
838     CK_BYTE IV[16];
839     CK_MECHANISM mech_DES3_CBC;
840     CK_MECHANISM mech_DES3_CBC_PAD;
841     CK_MECHANISM mech_AES_CBC_PAD;
842     CK_MECHANISM mech_AES_CBC;
843     struct mech_str {
844         CK_ULONG mechanism;
845         const char *mechanismStr;
846     };
847 
848     typedef struct mech_str mech_str;
849 
850     mech_str digestMechs[] = {
851         { CKM_SHA_1, "CKM_SHA_1 " },
852         { CKM_SHA224, "CKM_SHA224" },
853         { CKM_SHA256, "CKM_SHA256" },
854         { CKM_SHA384, "CKM_SHA384" },
855         { CKM_SHA512, "CKM_SHA512" }
856     };
857     mech_str hmacMechs[] = {
858         { CKM_SHA_1_HMAC, "CKM_SHA_1_HMAC" },
859         { CKM_SHA224_HMAC, "CKM_SHA224_HMAC" },
860         { CKM_SHA256_HMAC, "CKM_SHA256_HMAC" },
861         { CKM_SHA384_HMAC, "CKM_SHA384_HMAC" },
862         { CKM_SHA512_HMAC, "CKM_SHA512_HMAC" }
863     };
864     mech_str sigRSAMechs[] = {
865         { CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS" },
866         { CKM_SHA224_RSA_PKCS, "CKM_SHA224_RSA_PKCS" },
867         { CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS" },
868         { CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS" },
869         { CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS" }
870     };
871 
872     CK_ULONG digestMechsSZ = NUM_ELEM(digestMechs);
873     CK_ULONG sigRSAMechsSZ = NUM_ELEM(sigRSAMechs);
874     CK_ULONG hmacMechsSZ = NUM_ELEM(hmacMechs);
875     CK_MECHANISM mech;
876 
877     unsigned int i;
878 
879     NUMTESTS++; /* increment NUMTESTS */
880 
881     /* DSA key init */
882     dsaParamGenMech.mechanism = CKM_DSA_PARAMETER_GEN;
883     dsaParamGenMech.pParameter = NULL_PTR;
884     dsaParamGenMech.ulParameterLen = 0;
885     dsaParamGenTemplate[0].type = CKA_PRIME_BITS;
886     dsaParamGenTemplate[0].pValue = &primeBits;
887     dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits);
888     dsaPubKeyTemplate[0].type = CKA_PRIME;
889     dsaPubKeyTemplate[0].pValue = DSA_P;
890     dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P);
891     dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
892     dsaPubKeyTemplate[1].pValue = DSA_Q;
893     dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q);
894     dsaPubKeyTemplate[2].type = CKA_BASE;
895     dsaPubKeyTemplate[2].pValue = DSA_G;
896     dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G);
897     dsaPubKeyTemplate[3].type = CKA_TOKEN;
898     dsaPubKeyTemplate[3].pValue = &true;
899     dsaPubKeyTemplate[3].ulValueLen = sizeof(true);
900     dsaPubKeyTemplate[4].type = CKA_VERIFY;
901     dsaPubKeyTemplate[4].pValue = &true;
902     dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
903     dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN;
904     dsaKeyPairGenMech.pParameter = NULL_PTR;
905     dsaKeyPairGenMech.ulParameterLen = 0;
906     dsaPrivKeyTemplate[0].type = CKA_TOKEN;
907     dsaPrivKeyTemplate[0].pValue = &true;
908     dsaPrivKeyTemplate[0].ulValueLen = sizeof(true);
909     dsaPrivKeyTemplate[1].type = CKA_PRIVATE;
910     dsaPrivKeyTemplate[1].pValue = &true;
911     dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
912     dsaPrivKeyTemplate[2].type = CKA_SENSITIVE;
913     dsaPrivKeyTemplate[2].pValue = &true;
914     dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
915     dsaPrivKeyTemplate[3].type = CKA_SIGN,
916     dsaPrivKeyTemplate[3].pValue = &true;
917     dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
918     dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE;
919     dsaPrivKeyTemplate[4].pValue = &true;
920     dsaPrivKeyTemplate[4].ulValueLen = sizeof(true);
921 
922     /* RSA key init */
923     rsaKeyPairGenMech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
924     rsaKeyPairGenMech.pParameter = NULL_PTR;
925     rsaKeyPairGenMech.ulParameterLen = 0;
926 
927     rsaPubKeyTemplate[0].type = CKA_KEY_TYPE;
928     rsaPubKeyTemplate[0].pValue = &rsatype;
929     rsaPubKeyTemplate[0].ulValueLen = sizeof(rsatype);
930     rsaPubKeyTemplate[1].type = CKA_PRIVATE;
931     rsaPubKeyTemplate[1].pValue = &true;
932     rsaPubKeyTemplate[1].ulValueLen = sizeof(true);
933     rsaPubKeyTemplate[2].type = CKA_ENCRYPT;
934     rsaPubKeyTemplate[2].pValue = &true;
935     rsaPubKeyTemplate[2].ulValueLen = sizeof(true);
936     rsaPubKeyTemplate[3].type = CKA_DECRYPT;
937     rsaPubKeyTemplate[3].pValue = &true;
938     rsaPubKeyTemplate[3].ulValueLen = sizeof(true);
939     rsaPubKeyTemplate[4].type = CKA_VERIFY;
940     rsaPubKeyTemplate[4].pValue = &true;
941     rsaPubKeyTemplate[4].ulValueLen = sizeof(true);
942     rsaPubKeyTemplate[5].type = CKA_SIGN;
943     rsaPubKeyTemplate[5].pValue = &true;
944     rsaPubKeyTemplate[5].ulValueLen = sizeof(true);
945     rsaPubKeyTemplate[6].type = CKA_WRAP;
946     rsaPubKeyTemplate[6].pValue = &true;
947     rsaPubKeyTemplate[6].ulValueLen = sizeof(true);
948     rsaPubKeyTemplate[7].type = CKA_MODULUS_BITS;
949     rsaPubKeyTemplate[7].pValue = &modulusBits;
950     rsaPubKeyTemplate[7].ulValueLen = sizeof(modulusBits);
951     rsaPubKeyTemplate[8].type = CKA_PUBLIC_EXPONENT;
952     rsaPubKeyTemplate[8].pValue = publicExponent;
953     rsaPubKeyTemplate[8].ulValueLen = sizeof(publicExponent);
954 
955     rsaPrivKeyTemplate[0].type = CKA_KEY_TYPE;
956     rsaPrivKeyTemplate[0].pValue = &rsatype;
957     rsaPrivKeyTemplate[0].ulValueLen = sizeof(rsatype);
958     rsaPrivKeyTemplate[1].type = CKA_TOKEN;
959     rsaPrivKeyTemplate[1].pValue = &true;
960     rsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
961     rsaPrivKeyTemplate[2].type = CKA_PRIVATE;
962     rsaPrivKeyTemplate[2].pValue = &true;
963     rsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
964     rsaPrivKeyTemplate[3].type = CKA_SUBJECT;
965     rsaPrivKeyTemplate[3].pValue = subject;
966     rsaPrivKeyTemplate[3].ulValueLen = sizeof(subject);
967     rsaPrivKeyTemplate[4].type = CKA_ID;
968     rsaPrivKeyTemplate[4].pValue = id;
969     rsaPrivKeyTemplate[4].ulValueLen = sizeof(id);
970     rsaPrivKeyTemplate[5].type = CKA_SENSITIVE;
971     rsaPrivKeyTemplate[5].pValue = &true;
972     rsaPrivKeyTemplate[5].ulValueLen = sizeof(true);
973     rsaPrivKeyTemplate[6].type = CKA_ENCRYPT;
974     rsaPrivKeyTemplate[6].pValue = &true;
975     rsaPrivKeyTemplate[6].ulValueLen = sizeof(true);
976     rsaPrivKeyTemplate[7].type = CKA_DECRYPT;
977     rsaPrivKeyTemplate[7].pValue = &true;
978     rsaPrivKeyTemplate[7].ulValueLen = sizeof(true);
979     rsaPrivKeyTemplate[8].type = CKA_VERIFY;
980     rsaPrivKeyTemplate[8].pValue = &true;
981     rsaPrivKeyTemplate[8].ulValueLen = sizeof(true);
982     rsaPrivKeyTemplate[9].type = CKA_SIGN;
983     rsaPrivKeyTemplate[9].pValue = &true;
984     rsaPrivKeyTemplate[9].ulValueLen = sizeof(true);
985     rsaPrivKeyTemplate[10].type = CKA_UNWRAP;
986     rsaPrivKeyTemplate[10].pValue = &true;
987     rsaPrivKeyTemplate[10].ulValueLen = sizeof(true);
988 
989     /* AES key template */
990     sAESKeyTemplate[0].type = CKA_CLASS;
991     sAESKeyTemplate[0].pValue = &class;
992     sAESKeyTemplate[0].ulValueLen = sizeof(class);
993     sAESKeyTemplate[1].type = CKA_KEY_TYPE;
994     sAESKeyTemplate[1].pValue = &keyAESType;
995     sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
996     sAESKeyTemplate[2].type = CKA_LABEL;
997     sAESKeyTemplate[2].pValue = AESlabel;
998     sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel) - 1;
999     sAESKeyTemplate[3].type = CKA_ENCRYPT;
1000     sAESKeyTemplate[3].pValue = &true;
1001     sAESKeyTemplate[3].ulValueLen = sizeof(true);
1002     sAESKeyTemplate[4].type = CKA_DECRYPT;
1003     sAESKeyTemplate[4].pValue = &true;
1004     sAESKeyTemplate[4].ulValueLen = sizeof(true);
1005     sAESKeyTemplate[5].type = CKA_SIGN;
1006     sAESKeyTemplate[5].pValue = &true;
1007     sAESKeyTemplate[5].ulValueLen = sizeof(true);
1008     sAESKeyTemplate[6].type = CKA_VERIFY;
1009     sAESKeyTemplate[6].pValue = &true;
1010     sAESKeyTemplate[6].ulValueLen = sizeof(true);
1011     sAESKeyTemplate[7].type = CKA_UNWRAP;
1012     sAESKeyTemplate[7].pValue = &true;
1013     sAESKeyTemplate[7].ulValueLen = sizeof(true);
1014     sAESKeyTemplate[8].type = CKA_VALUE_LEN;
1015     sAESKeyTemplate[8].pValue = &AESvalueLen;
1016     sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
1017 
1018     /* DES3 key template */
1019     sDES3KeyTemplate[0].type = CKA_CLASS;
1020     sDES3KeyTemplate[0].pValue = &class;
1021     sDES3KeyTemplate[0].ulValueLen = sizeof(class);
1022     sDES3KeyTemplate[1].type = CKA_KEY_TYPE;
1023     sDES3KeyTemplate[1].pValue = &keyDES3Type;
1024     sDES3KeyTemplate[1].ulValueLen = sizeof(keyDES3Type);
1025     sDES3KeyTemplate[2].type = CKA_LABEL;
1026     sDES3KeyTemplate[2].pValue = DES3label;
1027     sDES3KeyTemplate[2].ulValueLen = sizeof(DES3label) - 1;
1028     sDES3KeyTemplate[3].type = CKA_ENCRYPT;
1029     sDES3KeyTemplate[3].pValue = &true;
1030     sDES3KeyTemplate[3].ulValueLen = sizeof(true);
1031     sDES3KeyTemplate[4].type = CKA_DECRYPT;
1032     sDES3KeyTemplate[4].pValue = &true;
1033     sDES3KeyTemplate[4].ulValueLen = sizeof(true);
1034     sDES3KeyTemplate[5].type = CKA_UNWRAP;
1035     sDES3KeyTemplate[5].pValue = &true;
1036     sDES3KeyTemplate[5].ulValueLen = sizeof(true);
1037     sDES3KeyTemplate[6].type = CKA_SIGN,
1038     sDES3KeyTemplate[6].pValue = &true;
1039     sDES3KeyTemplate[6].ulValueLen = sizeof(true);
1040     sDES3KeyTemplate[7].type = CKA_VERIFY;
1041     sDES3KeyTemplate[7].pValue = &true;
1042     sDES3KeyTemplate[7].ulValueLen = sizeof(true);
1043     sDES3KeyTemplate[8].type = CKA_VALUE_LEN;
1044     sDES3KeyTemplate[8].pValue = &DES3valueLen;
1045     sDES3KeyTemplate[8].ulValueLen = sizeof(DES3valueLen);
1046 
1047     /* mech init */
1048     memset(IV, 0x01, sizeof(IV));
1049     mech_DES3_CBC.mechanism = CKM_DES3_CBC;
1050     mech_DES3_CBC.pParameter = IV;
1051     mech_DES3_CBC.ulParameterLen = sizeof(IV);
1052     mech_DES3_CBC_PAD.mechanism = CKM_DES3_CBC_PAD;
1053     mech_DES3_CBC_PAD.pParameter = IV;
1054     mech_DES3_CBC_PAD.ulParameterLen = sizeof(IV);
1055     mech_AES_CBC.mechanism = CKM_AES_CBC;
1056     mech_AES_CBC.pParameter = IV;
1057     mech_AES_CBC.ulParameterLen = sizeof(IV);
1058     mech_AES_CBC_PAD.mechanism = CKM_AES_CBC_PAD;
1059     mech_AES_CBC_PAD.pParameter = IV;
1060     mech_AES_CBC_PAD.ulParameterLen = sizeof(IV);
1061 
1062     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
1063                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
1064                                        NULL, NULL, &hRwSession);
1065     if (crv == CKR_OK) {
1066         PKM_LogIt("Opening a read/write session succeeded\n");
1067     } else {
1068         PKM_Error("Opening a read/write session failed "
1069                   "with 0x%08X, %-26s\n",
1070                   crv, PKM_CK_RVtoStr(crv));
1071         return crv;
1072     }
1073 
1074     if (MODE == FIPSMODE) {
1075         crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
1076                                            sAESKeyTemplate,
1077                                            NUM_ELEM(sAESKeyTemplate),
1078                                            &hAESSecKey);
1079         if (crv == CKR_OK) {
1080             PKM_Error("C_GenerateKey succeeded when not logged in.\n");
1081             return CKR_GENERAL_ERROR;
1082         } else {
1083             PKM_LogIt("C_GenerateKey returned as EXPECTED with 0x%08X, %-26s\n"
1084                       "since not logged in\n",
1085                       crv, PKM_CK_RVtoStr(crv));
1086         }
1087         crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
1088                                                rsaPubKeyTemplate,
1089                                                NUM_ELEM(rsaPubKeyTemplate),
1090                                                rsaPrivKeyTemplate,
1091                                                NUM_ELEM(rsaPrivKeyTemplate),
1092                                                &hRSApubKey, &hRSAprivKey);
1093         if (crv == CKR_OK) {
1094             PKM_Error("C_GenerateKeyPair succeeded when not logged in.\n");
1095             return CKR_GENERAL_ERROR;
1096         } else {
1097             PKM_LogIt("C_GenerateKeyPair returned as EXPECTED with 0x%08X, "
1098                       "%-26s\n since not logged in\n",
1099                       crv,
1100                       PKM_CK_RVtoStr(crv));
1101         }
1102     }
1103 
1104     crv = pFunctionList->C_Login(hRwSession, CKU_USER, pwd, pwdLen);
1105     if (crv == CKR_OK) {
1106         PKM_LogIt("C_Login with correct password succeeded\n");
1107     } else {
1108         PKM_Error("C_Login with correct password failed "
1109                   "with 0x%08X, %-26s\n",
1110                   crv, PKM_CK_RVtoStr(crv));
1111         return crv;
1112     }
1113 
1114     PKM_LogIt("Generate an AES key ... \n");
1115     /* generate an AES Secret Key */
1116     crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
1117                                        sAESKeyTemplate,
1118                                        NUM_ELEM(sAESKeyTemplate),
1119                                        &hAESSecKey);
1120     if (crv == CKR_OK) {
1121         PKM_LogIt("C_GenerateKey AES succeeded\n");
1122     } else {
1123         PKM_Error("C_GenerateKey AES failed with 0x%08X, %-26s\n",
1124                   crv, PKM_CK_RVtoStr(crv));
1125         return crv;
1126     }
1127 
1128     PKM_LogIt("Generate an 3DES key ...\n");
1129     /* generate an 3DES Secret Key */
1130     crv = pFunctionList->C_GenerateKey(hRwSession, &sDES3KeyGenMechanism,
1131                                        sDES3KeyTemplate,
1132                                        NUM_ELEM(sDES3KeyTemplate),
1133                                        &hDES3SecKey);
1134     if (crv == CKR_OK) {
1135         PKM_LogIt("C_GenerateKey DES3 succeeded\n");
1136     } else {
1137         PKM_Error("C_GenerateKey failed with 0x%08X, %-26s\n", crv,
1138                   PKM_CK_RVtoStr(crv));
1139         return crv;
1140     }
1141 
1142     PKM_LogIt("Generate DSA PQG domain parameters ... \n");
1143     /* Generate DSA domain parameters PQG */
1144     crv = pFunctionList->C_GenerateKey(hRwSession, &dsaParamGenMech,
1145                                        dsaParamGenTemplate,
1146                                        1,
1147                                        &hDsaParams);
1148     if (crv == CKR_OK) {
1149         PKM_LogIt("DSA domain parameter generation succeeded\n");
1150     } else {
1151         PKM_Error("DSA domain parameter generation failed "
1152                   "with 0x%08X, %-26s\n",
1153                   crv, PKM_CK_RVtoStr(crv));
1154         return crv;
1155     }
1156     crv = pFunctionList->C_GetAttributeValue(hRwSession, hDsaParams,
1157                                              dsaPubKeyTemplate, 3);
1158     if (crv == CKR_OK) {
1159         PKM_LogIt("Getting DSA domain parameters succeeded\n");
1160     } else {
1161         PKM_Error("Getting DSA domain parameters failed "
1162                   "with 0x%08X, %-26s\n",
1163                   crv, PKM_CK_RVtoStr(crv));
1164         return crv;
1165     }
1166     crv = pFunctionList->C_DestroyObject(hRwSession, hDsaParams);
1167     if (crv == CKR_OK) {
1168         PKM_LogIt("Destroying DSA domain parameters succeeded\n");
1169     } else {
1170         PKM_Error("Destroying DSA domain parameters failed "
1171                   "with 0x%08X, %-26s\n",
1172                   crv, PKM_CK_RVtoStr(crv));
1173         return crv;
1174     }
1175 
1176     PKM_LogIt("Generate a DSA key pair ... \n");
1177     /* Generate a persistent DSA key pair */
1178     crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech,
1179                                            dsaPubKeyTemplate,
1180                                            NUM_ELEM(dsaPubKeyTemplate),
1181                                            dsaPrivKeyTemplate,
1182                                            NUM_ELEM(dsaPrivKeyTemplate),
1183                                            &hDSApubKey, &hDSAprivKey);
1184     if (crv == CKR_OK) {
1185         PKM_LogIt("DSA key pair generation succeeded\n");
1186     } else {
1187         PKM_Error("DSA key pair generation failed "
1188                   "with 0x%08X, %-26s\n",
1189                   crv, PKM_CK_RVtoStr(crv));
1190         return crv;
1191     }
1192 
1193     PKM_LogIt("Generate a RSA key pair ... \n");
1194     /*** GEN RSA Key ***/
1195     crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
1196                                            rsaPubKeyTemplate,
1197                                            NUM_ELEM(rsaPubKeyTemplate),
1198                                            rsaPrivKeyTemplate,
1199                                            NUM_ELEM(rsaPrivKeyTemplate),
1200                                            &hRSApubKey, &hRSAprivKey);
1201     if (crv == CKR_OK) {
1202         PKM_LogIt("C_GenerateKeyPair created an RSA key pair. \n");
1203     } else {
1204         PKM_Error("C_GenerateKeyPair failed to create an RSA key pair.\n"
1205                   "with 0x%08X, %-26s\n",
1206                   crv, PKM_CK_RVtoStr(crv));
1207         return crv;
1208     }
1209 
1210     PKM_LogIt("**** Generation of keys completed ***** \n");
1211 
1212     mech.mechanism = CKM_RSA_PKCS;
1213     mech.pParameter = NULL;
1214     mech.ulParameterLen = 0;
1215 
1216     crv = PKM_wrapUnwrap(pFunctionList,
1217                          hRwSession,
1218                          hRSApubKey, hRSAprivKey,
1219                          &mech,
1220                          hAESSecKey,
1221                          sAESKeyTemplate,
1222                          NUM_ELEM(sAESKeyTemplate));
1223 
1224     if (crv == CKR_OK) {
1225         PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap AES key "
1226                   "succeeded\n\n");
1227     } else {
1228         PKM_Error("PKM_wrapUnwrap using RSA keypair to wrap AES key failed "
1229                   "with 0x%08X, %-26s\n",
1230                   crv,
1231                   PKM_CK_RVtoStr(crv));
1232         return crv;
1233     }
1234 
1235     crv = PKM_wrapUnwrap(pFunctionList,
1236                          hRwSession,
1237                          hRSApubKey, hRSAprivKey,
1238                          &mech,
1239                          hDES3SecKey,
1240                          sDES3KeyTemplate,
1241                          NUM_ELEM(sDES3KeyTemplate));
1242 
1243     if (crv == CKR_OK) {
1244         PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
1245                   "succeeded\n\n");
1246     } else {
1247         PKM_Error("PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
1248                   "failed with 0x%08X, %-26s\n",
1249                   crv,
1250                   PKM_CK_RVtoStr(crv));
1251         return crv;
1252     }
1253 
1254     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
1255                           hAESSecKey, &mech_AES_CBC_PAD,
1256                           PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
1257     if (crv == CKR_OK) {
1258         PKM_LogIt("PKM_SecKeyCrypt succeeded \n\n");
1259     } else {
1260         PKM_Error("PKM_SecKeyCrypt failed "
1261                   "with 0x%08X, %-26s\n",
1262                   crv, PKM_CK_RVtoStr(crv));
1263         return crv;
1264     }
1265 
1266     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
1267                           hAESSecKey, &mech_AES_CBC,
1268                           PLAINTEXT, sizeof(PLAINTEXT));
1269     if (crv == CKR_OK) {
1270         PKM_LogIt("PKM_SecKeyCrypt AES succeeded \n\n");
1271     } else {
1272         PKM_Error("PKM_SecKeyCrypt failed "
1273                   "with 0x%08X, %-26s\n",
1274                   crv, PKM_CK_RVtoStr(crv));
1275         return crv;
1276     }
1277 
1278     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
1279                           hDES3SecKey, &mech_DES3_CBC,
1280                           PLAINTEXT, sizeof(PLAINTEXT));
1281     if (crv == CKR_OK) {
1282         PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n");
1283     } else {
1284         PKM_Error("PKM_SecKeyCrypt DES3 failed "
1285                   "with 0x%08X, %-26s\n",
1286                   crv, PKM_CK_RVtoStr(crv));
1287         return crv;
1288     }
1289 
1290     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
1291                           hDES3SecKey, &mech_DES3_CBC_PAD,
1292                           PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
1293     if (crv == CKR_OK) {
1294         PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n\n");
1295     } else {
1296         PKM_Error("PKM_SecKeyCrypt DES3 failed "
1297                   "with 0x%08X, %-26s\n",
1298                   crv, PKM_CK_RVtoStr(crv));
1299         return crv;
1300     }
1301 
1302     mech.mechanism = CKM_RSA_PKCS;
1303     crv = PKM_RecoverFunctions(pFunctionList, hRwSession,
1304                                hRSApubKey, hRSAprivKey,
1305                                &mech,
1306                                PLAINTEXT, sizeof(PLAINTEXT));
1307     if (crv == CKR_OK) {
1308         PKM_LogIt("PKM_RecoverFunctions for CKM_RSA_PKCS succeeded\n\n");
1309     } else {
1310         PKM_Error("PKM_RecoverFunctions failed with 0x%08X, %-26s\n", crv,
1311                   PKM_CK_RVtoStr(crv));
1312         return crv;
1313     }
1314 
1315     mech.pParameter = NULL;
1316     mech.ulParameterLen = 0;
1317 
1318     for (i = 0; i < sigRSAMechsSZ; i++) {
1319 
1320         mech.mechanism = sigRSAMechs[i].mechanism;
1321 
1322         crv = PKM_PubKeySign(pFunctionList, hRwSession,
1323                              hRSApubKey, hRSAprivKey,
1324                              &mech,
1325                              PLAINTEXT, sizeof(PLAINTEXT));
1326         if (crv == CKR_OK) {
1327             PKM_LogIt("PKM_PubKeySign succeeded for %-10s\n\n",
1328                       sigRSAMechs[i].mechanismStr);
1329         } else {
1330             PKM_Error("PKM_PubKeySign failed for %-10s  "
1331                       "with 0x%08X, %-26s\n",
1332                       sigRSAMechs[i].mechanismStr, crv,
1333                       PKM_CK_RVtoStr(crv));
1334             return crv;
1335         }
1336         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1337                                hRSApubKey, hRSAprivKey,
1338                                &mech,
1339                                hAESSecKey, &mech_AES_CBC,
1340                                PLAINTEXT, sizeof(PLAINTEXT));
1341         if (crv == CKR_OK) {
1342             PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
1343                       "for %-10s\n\n",
1344                       sigRSAMechs[i].mechanismStr);
1345         } else {
1346             PKM_Error("PKM_DualFuncSign with AES secret key failed "
1347                       "for %-10s  "
1348                       "with 0x%08X, %-26s\n",
1349                       sigRSAMechs[i].mechanismStr, crv,
1350                       PKM_CK_RVtoStr(crv));
1351             return crv;
1352         }
1353         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1354                                hRSApubKey, hRSAprivKey,
1355                                &mech,
1356                                hDES3SecKey, &mech_DES3_CBC,
1357                                PLAINTEXT, sizeof(PLAINTEXT));
1358         if (crv == CKR_OK) {
1359             PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
1360                       "for %-10s\n\n",
1361                       sigRSAMechs[i].mechanismStr);
1362         } else {
1363             PKM_Error("PKM_DualFuncSign with DES3 secret key failed "
1364                       "for %-10s  "
1365                       "with 0x%08X, %-26s\n",
1366                       sigRSAMechs[i].mechanismStr, crv,
1367                       PKM_CK_RVtoStr(crv));
1368             return crv;
1369         }
1370         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1371                                hRSApubKey, hRSAprivKey,
1372                                &mech,
1373                                hAESSecKey, &mech_AES_CBC_PAD,
1374                                PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
1375         if (crv == CKR_OK) {
1376             PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD "
1377                       "succeeded for %-10s\n\n",
1378                       sigRSAMechs[i].mechanismStr);
1379         } else {
1380             PKM_Error("PKM_DualFuncSign with AES secret key CBC_PAD "
1381                       "failed for %-10s  "
1382                       "with 0x%08X, %-26s\n",
1383                       sigRSAMechs[i].mechanismStr, crv,
1384                       PKM_CK_RVtoStr(crv));
1385             return crv;
1386         }
1387         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1388                                hRSApubKey, hRSAprivKey,
1389                                &mech,
1390                                hDES3SecKey, &mech_DES3_CBC_PAD,
1391                                PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
1392         if (crv == CKR_OK) {
1393             PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD "
1394                       "succeeded for %-10s\n\n",
1395                       sigRSAMechs[i].mechanismStr);
1396         } else {
1397             PKM_Error("PKM_DualFuncSign with DES3 secret key CBC_PAD "
1398                       "failed for %-10s  "
1399                       "with 0x%08X, %-26s\n",
1400                       sigRSAMechs[i].mechanismStr, crv,
1401                       PKM_CK_RVtoStr(crv));
1402             return crv;
1403         }
1404 
1405     } /* end of RSA for loop */
1406 
1407     crv = PKM_PubKeySign(pFunctionList, hRwSession,
1408                          hDSApubKey, hDSAprivKey,
1409                          &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT));
1410     if (crv == CKR_OK) {
1411         PKM_LogIt("PKM_PubKeySign for DSAwithSHA1 succeeded \n\n");
1412     } else {
1413         PKM_Error("PKM_PubKeySign failed "
1414                   "with 0x%08X, %-26s\n",
1415                   crv, PKM_CK_RVtoStr(crv));
1416         return crv;
1417     }
1418     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1419                            hDSApubKey, hDSAprivKey,
1420                            &dsaWithSha1Mech,
1421                            hAESSecKey, &mech_AES_CBC,
1422                            PLAINTEXT, sizeof(PLAINTEXT));
1423     if (crv == CKR_OK) {
1424         PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
1425                   "for DSAWithSHA1\n\n");
1426     } else {
1427         PKM_Error("PKM_DualFuncSign with AES secret key failed "
1428                   "for DSAWithSHA1 with 0x%08X, %-26s\n",
1429                   crv, PKM_CK_RVtoStr(crv));
1430         return crv;
1431     }
1432     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1433                            hDSApubKey, hDSAprivKey,
1434                            &dsaWithSha1Mech,
1435                            hDES3SecKey, &mech_DES3_CBC,
1436                            PLAINTEXT, sizeof(PLAINTEXT));
1437     if (crv == CKR_OK) {
1438         PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
1439                   "for DSAWithSHA1\n\n");
1440     } else {
1441         PKM_Error("PKM_DualFuncSign with DES3 secret key failed "
1442                   "for DSAWithSHA1 with 0x%08X, %-26s\n",
1443                   crv, PKM_CK_RVtoStr(crv));
1444         return crv;
1445     }
1446     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1447                            hDSApubKey, hDSAprivKey,
1448                            &dsaWithSha1Mech,
1449                            hAESSecKey, &mech_AES_CBC_PAD,
1450                            PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
1451     if (crv == CKR_OK) {
1452         PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD succeeded "
1453                   "for DSAWithSHA1\n\n");
1454     } else {
1455         PKM_Error("PKM_DualFuncSign with AES secret key CBC_PAD failed "
1456                   "for DSAWithSHA1 with 0x%08X, %-26s\n",
1457                   crv, PKM_CK_RVtoStr(crv));
1458         return crv;
1459     }
1460     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
1461                            hDSApubKey, hDSAprivKey,
1462                            &dsaWithSha1Mech,
1463                            hDES3SecKey, &mech_DES3_CBC_PAD,
1464                            PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
1465     if (crv == CKR_OK) {
1466         PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD succeeded "
1467                   "for DSAWithSHA1\n\n");
1468     } else {
1469         PKM_Error("PKM_DualFuncSign with DES3 secret key CBC_PAD failed "
1470                   "for DSAWithSHA1 with 0x%08X, %-26s\n",
1471                   crv, PKM_CK_RVtoStr(crv));
1472         return crv;
1473     }
1474 
1475     for (i = 0; i < digestMechsSZ; i++) {
1476         mech.mechanism = digestMechs[i].mechanism;
1477         crv = PKM_Digest(pFunctionList, hRwSession,
1478                          &mech, hAESSecKey,
1479                          PLAINTEXT, sizeof(PLAINTEXT));
1480         if (crv == CKR_OK) {
1481             PKM_LogIt("PKM_Digest with AES secret key succeeded for %-10s\n\n",
1482                       digestMechs[i].mechanismStr);
1483         } else {
1484             PKM_Error("PKM_Digest with AES secret key failed for "
1485                       "%-10s with 0x%08X,  %-26s\n",
1486                       digestMechs[i].mechanismStr, crv,
1487                       PKM_CK_RVtoStr(crv));
1488             return crv;
1489         }
1490         crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
1491                                  hAESSecKey, &mech_AES_CBC,
1492                                  0, &mech,
1493                                  PLAINTEXT, sizeof(PLAINTEXT));
1494         if (crv == CKR_OK) {
1495             PKM_LogIt("PKM_DualFuncDigest with AES secret key succeeded\n\n");
1496         } else {
1497             PKM_Error("PKM_DualFuncDigest with AES secret key "
1498                       "failed with 0x%08X, %-26s\n",
1499                       crv,
1500                       PKM_CK_RVtoStr(crv));
1501         }
1502 
1503         crv = PKM_Digest(pFunctionList, hRwSession,
1504                          &mech, hDES3SecKey,
1505                          PLAINTEXT, sizeof(PLAINTEXT));
1506         if (crv == CKR_OK) {
1507             PKM_LogIt("PKM_Digest with DES3 secret key succeeded for %-10s\n\n",
1508                       digestMechs[i].mechanismStr);
1509         } else {
1510             PKM_Error("PKM_Digest with DES3 secret key failed for "
1511                       "%-10s with 0x%08X,  %-26s\n",
1512                       digestMechs[i].mechanismStr, crv,
1513                       PKM_CK_RVtoStr(crv));
1514             return crv;
1515         }
1516         crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
1517                                  hDES3SecKey, &mech_DES3_CBC,
1518                                  0, &mech,
1519                                  PLAINTEXT, sizeof(PLAINTEXT));
1520         if (crv == CKR_OK) {
1521             PKM_LogIt("PKM_DualFuncDigest DES3 secret key succeeded\n\n");
1522         } else {
1523             PKM_Error("PKM_DualFuncDigest DES3 secret key "
1524                       "failed with 0x%08X, %-26s\n",
1525                       crv,
1526                       PKM_CK_RVtoStr(crv));
1527         }
1528 
1529         crv = PKM_Digest(pFunctionList, hRwSession,
1530                          &mech, 0,
1531                          PLAINTEXT, sizeof(PLAINTEXT));
1532         if (crv == CKR_OK) {
1533             PKM_LogIt("PKM_Digest with no secret key succeeded for %-10s\n\n",
1534                       digestMechs[i].mechanismStr);
1535         } else {
1536             PKM_Error("PKM_Digest with no secret key failed for %-10s  "
1537                       "with 0x%08X, %-26s\n",
1538                       digestMechs[i].mechanismStr, crv,
1539                       PKM_CK_RVtoStr(crv));
1540             return crv;
1541         }
1542     } /* end of digest loop */
1543 
1544     for (i = 0; i < hmacMechsSZ; i++) {
1545         mech.mechanism = hmacMechs[i].mechanism;
1546         crv = PKM_Hmac(pFunctionList, hRwSession,
1547                        hAESSecKey, &mech,
1548                        PLAINTEXT, sizeof(PLAINTEXT));
1549         if (crv == CKR_OK) {
1550             PKM_LogIt("PKM_Hmac with AES secret key succeeded for %-10s\n\n",
1551                       hmacMechs[i].mechanismStr);
1552         } else {
1553             PKM_Error("PKM_Hmac with AES secret key failed for %-10s "
1554                       "with 0x%08X, %-26s\n",
1555                       hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
1556             return crv;
1557         }
1558         if ((MODE == FIPSMODE) && (mech.mechanism == CKM_SHA512_HMAC))
1559             break;
1560         crv = PKM_Hmac(pFunctionList, hRwSession,
1561                        hDES3SecKey, &mech,
1562                        PLAINTEXT, sizeof(PLAINTEXT));
1563         if (crv == CKR_OK) {
1564             PKM_LogIt("PKM_Hmac with DES3 secret key succeeded for %-10s\n\n",
1565                       hmacMechs[i].mechanismStr);
1566         } else {
1567             PKM_Error("PKM_Hmac with DES3 secret key failed for %-10s "
1568                       "with 0x%08X,  %-26s\n",
1569                       hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
1570             return crv;
1571         }
1572 
1573     } /* end of hmac loop */
1574 
1575     crv = pFunctionList->C_Logout(hRwSession);
1576     if (crv == CKR_OK) {
1577         PKM_LogIt("C_Logout succeeded\n");
1578     } else {
1579         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
1580                   PKM_CK_RVtoStr(crv));
1581         return crv;
1582     }
1583 
1584     crv = pFunctionList->C_CloseSession(hRwSession);
1585     if (crv != CKR_OK) {
1586         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
1587                   PKM_CK_RVtoStr(crv));
1588         return crv;
1589     }
1590 
1591     return crv;
1592 }
1593 
1594 void
PKM_LogIt(const char * fmt,...)1595 PKM_LogIt(const char *fmt, ...)
1596 {
1597     va_list args;
1598 
1599     if (verbose) {
1600         va_start(args, fmt);
1601         if (MODE == FIPSMODE) {
1602             printf("FIPS MODE: ");
1603         } else if (MODE == NONFIPSMODE) {
1604             printf("NON FIPS MODE: ");
1605         } else if (MODE == HYBRIDMODE) {
1606             printf("Hybrid MODE: ");
1607         }
1608         vprintf(fmt, args);
1609         va_end(args);
1610     }
1611 }
1612 
1613 void
PKM_Error(const char * fmt,...)1614 PKM_Error(const char *fmt, ...)
1615 {
1616     va_list args;
1617     va_start(args, fmt);
1618 
1619     if (MODE == FIPSMODE) {
1620         fprintf(stderr, "\nFIPS MODE PKM_Error: ");
1621     } else if (MODE == NONFIPSMODE) {
1622         fprintf(stderr, "NON FIPS MODE PKM_Error: ");
1623     } else if (MODE == HYBRIDMODE) {
1624         fprintf(stderr, "Hybrid MODE PKM_Error: ");
1625     } else
1626         fprintf(stderr, "NOMODE PKM_Error: ");
1627     vfprintf(stderr, fmt, args);
1628     va_end(args);
1629 }
1630 CK_SLOT_ID *
PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,CK_ULONG slotID)1631 PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
1632                 CK_ULONG slotID)
1633 {
1634     CK_RV crv = CKR_OK;
1635     CK_SLOT_ID *pSlotList = NULL;
1636     CK_ULONG slotCount;
1637 
1638     NUMTESTS++; /* increment NUMTESTS */
1639 
1640     /* Get slot list */
1641     crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
1642                                        NULL, &slotCount);
1643     if (crv != CKR_OK) {
1644         PKM_Error("C_GetSlotList failed with 0x%08X, %-26s\n", crv,
1645                   PKM_CK_RVtoStr(crv));
1646         return NULL;
1647     }
1648     PKM_LogIt("C_GetSlotList reported there are %lu slots\n", slotCount);
1649     pSlotList = (CK_SLOT_ID *)malloc(slotCount * sizeof(CK_SLOT_ID));
1650     if (!pSlotList) {
1651         PKM_Error("failed to allocate slot list\n");
1652         return NULL;
1653     }
1654     crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
1655                                        pSlotList, &slotCount);
1656     if (crv != CKR_OK) {
1657         PKM_Error("C_GetSlotList failed with 0x%08X, %-26s\n", crv,
1658                   PKM_CK_RVtoStr(crv));
1659         if (pSlotList)
1660             free(pSlotList);
1661         return NULL;
1662     }
1663     return pSlotList;
1664 }
1665 
1666 CK_RV
PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)1667 PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
1668                 CK_SLOT_ID *pSlotList, CK_ULONG slotID,
1669                 CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
1670 {
1671     CK_RV crv = CKR_OK;
1672     CK_SESSION_HANDLE hSession;
1673     static const CK_UTF8CHAR testPin[] = { "0Mozilla" };
1674     static const CK_UTF8CHAR weakPin[] = { "mozilla" };
1675 
1676     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
1677                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
1678                                        NULL, NULL, &hSession);
1679     if (crv != CKR_OK) {
1680         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
1681                   PKM_CK_RVtoStr(crv));
1682         return crv;
1683     }
1684     PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER);
1685 
1686     crv = pFunctionList->C_Login(hSession, CKU_SO, NULL, 0);
1687     if (crv != CKR_OK) {
1688         PKM_Error("C_Login failed with 0x%08X, %-26s\n", crv,
1689                   PKM_CK_RVtoStr(crv));
1690         return crv;
1691     }
1692     if (MODE == FIPSMODE) {
1693         crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *)weakPin,
1694                                        strlen((char *)weakPin));
1695         if (crv == CKR_OK) {
1696             PKM_Error("C_InitPIN with a weak password succeeded\n");
1697             return crv;
1698         } else {
1699             PKM_LogIt("C_InitPIN with a weak password failed with "
1700                       "0x%08X, %-26s\n",
1701                       crv, PKM_CK_RVtoStr(crv));
1702         }
1703     }
1704     crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *)testPin,
1705                                    strlen((char *)testPin));
1706     if (crv == CKR_OK) {
1707         PKM_LogIt("C_InitPIN succeeded\n");
1708     } else {
1709         PKM_Error("C_InitPIN failed with 0x%08X, %-26s\n", crv,
1710                   PKM_CK_RVtoStr(crv));
1711         return crv;
1712     }
1713     crv = pFunctionList->C_Logout(hSession);
1714     if (crv != CKR_OK) {
1715         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
1716                   PKM_CK_RVtoStr(crv));
1717         return crv;
1718     }
1719     crv = pFunctionList->C_CloseSession(hSession);
1720     if (crv != CKR_OK) {
1721         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
1722                   PKM_CK_RVtoStr(crv));
1723         return crv;
1724     }
1725 
1726     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
1727                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
1728                                        NULL, NULL, &hSession);
1729     if (crv != CKR_OK) {
1730         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
1731                   PKM_CK_RVtoStr(crv));
1732         return crv;
1733     }
1734 
1735     PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER);
1736 
1737     crv = pFunctionList->C_Login(hSession, CKU_USER, (CK_UTF8CHAR *)testPin,
1738                                  strlen((const char *)testPin));
1739     if (crv != CKR_OK) {
1740         PKM_Error("C_Login failed with 0x%08X, %-26s\n", crv,
1741                   PKM_CK_RVtoStr(crv));
1742         return crv;
1743     }
1744     if (MODE == FIPSMODE) {
1745         crv = pFunctionList->C_SetPIN(
1746             hSession, (CK_UTF8CHAR *)testPin,
1747             strlen((const char *)testPin),
1748             (CK_UTF8CHAR *)weakPin,
1749             strlen((const char *)weakPin));
1750         if (crv == CKR_OK) {
1751             PKM_Error("C_SetPIN with a weak password succeeded\n");
1752             return crv;
1753         } else {
1754             PKM_LogIt("C_SetPIN with a weak password returned with "
1755                       "0x%08X, %-26s\n",
1756                       crv, PKM_CK_RVtoStr(crv));
1757         }
1758     }
1759     crv = pFunctionList->C_SetPIN(
1760         hSession, (CK_UTF8CHAR *)testPin,
1761         strlen((const char *)testPin),
1762         pwd, pwdLen);
1763     if (crv != CKR_OK) {
1764         PKM_Error("C_CSetPin failed with 0x%08X, %-26s\n", crv,
1765                   PKM_CK_RVtoStr(crv));
1766         return crv;
1767     }
1768     crv = pFunctionList->C_Logout(hSession);
1769     if (crv != CKR_OK) {
1770         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
1771                   PKM_CK_RVtoStr(crv));
1772         return crv;
1773     }
1774     crv = pFunctionList->C_CloseSession(hSession);
1775     if (crv != CKR_OK) {
1776         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
1777                   PKM_CK_RVtoStr(crv));
1778         return crv;
1779     }
1780     return crv;
1781 }
1782 
1783 CK_RV
PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList,CK_ULONG slotID)1784 PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID)
1785 {
1786     CK_RV crv = CKR_OK;
1787     CK_INFO info;
1788     CK_SLOT_ID *pSlotList = NULL;
1789     unsigned i;
1790 
1791     CK_SLOT_INFO slotInfo;
1792     CK_TOKEN_INFO tokenInfo;
1793     CK_FLAGS bitflag;
1794 
1795     NUMTESTS++; /* increment NUMTESTS */
1796 
1797     crv = pFunctionList->C_GetInfo(&info);
1798     if (crv == CKR_OK) {
1799         PKM_LogIt("C_GetInfo succeeded\n");
1800     } else {
1801         PKM_Error("C_GetInfo failed with 0x%08X, %-26s\n", crv,
1802                   PKM_CK_RVtoStr(crv));
1803         return crv;
1804     }
1805     PKM_LogIt("General information about the PKCS #11 library:\n");
1806     PKM_LogIt("    PKCS #11 version: %d.%d\n",
1807               (int)info.cryptokiVersion.major,
1808               (int)info.cryptokiVersion.minor);
1809     PKM_LogIt("    manufacturer ID: %.32s\n", info.manufacturerID);
1810     PKM_LogIt("    flags: 0x%08lX\n", info.flags);
1811     PKM_LogIt("    library description: %.32s\n", info.libraryDescription);
1812     PKM_LogIt("    library version: %d.%d\n",
1813               (int)info.libraryVersion.major, (int)info.libraryVersion.minor);
1814     PKM_LogIt("\n");
1815 
1816     /* Get slot list */
1817     pSlotList = PKM_GetSlotList(pFunctionList, slotID);
1818     if (pSlotList == NULL) {
1819         PKM_Error("PKM_GetSlotList failed with \n");
1820         return crv;
1821     }
1822     crv = pFunctionList->C_GetSlotInfo(pSlotList[slotID], &slotInfo);
1823     if (crv == CKR_OK) {
1824         PKM_LogIt("C_GetSlotInfo succeeded\n");
1825     } else {
1826         PKM_Error("C_GetSlotInfo failed with 0x%08X, %-26s\n", crv,
1827                   PKM_CK_RVtoStr(crv));
1828         return crv;
1829     }
1830     PKM_LogIt("Information about slot %lu:\n", pSlotList[slotID]);
1831     PKM_LogIt("    slot description: %.64s\n", slotInfo.slotDescription);
1832     PKM_LogIt("    slot manufacturer ID: %.32s\n", slotInfo.manufacturerID);
1833     PKM_LogIt("    flags: 0x%08lX\n", slotInfo.flags);
1834     bitflag = 1;
1835     for (i = 0; i < sizeof(slotFlagName) / sizeof(slotFlagName[0]); i++) {
1836         if (slotInfo.flags & bitflag) {
1837             PKM_LogIt("           %s\n", slotFlagName[i]);
1838         }
1839         bitflag <<= 1;
1840     }
1841     PKM_LogIt("    slot's hardware version number: %d.%d\n",
1842               (int)slotInfo.hardwareVersion.major,
1843               (int)slotInfo.hardwareVersion.minor);
1844     PKM_LogIt("    slot's firmware version number: %d.%d\n",
1845               (int)slotInfo.firmwareVersion.major,
1846               (int)slotInfo.firmwareVersion.minor);
1847     PKM_LogIt("\n");
1848 
1849     crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
1850     if (crv == CKR_OK) {
1851         PKM_LogIt("C_GetTokenInfo succeeded\n");
1852     } else {
1853         PKM_Error("C_GetTokenInfo failed with 0x%08X, %-26s\n", crv,
1854                   PKM_CK_RVtoStr(crv));
1855         return crv;
1856     }
1857     PKM_LogIt("Information about the token in slot %lu:\n",
1858               pSlotList[slotID]);
1859     PKM_LogIt("    label: %.32s\n", tokenInfo.label);
1860     PKM_LogIt("    device manufacturer ID: %.32s\n",
1861               tokenInfo.manufacturerID);
1862     PKM_LogIt("    device model: %.16s\n", tokenInfo.model);
1863     PKM_LogIt("    device serial number: %.16s\n", tokenInfo.serialNumber);
1864     PKM_LogIt("    flags: 0x%08lX\n", tokenInfo.flags);
1865     bitflag = 1;
1866     for (i = 0; i < sizeof(tokenFlagName) / sizeof(tokenFlagName[0]); i++) {
1867         if (tokenInfo.flags & bitflag) {
1868             PKM_LogIt("           %s\n", tokenFlagName[i]);
1869         }
1870         bitflag <<= 1;
1871     }
1872     PKM_LogIt("    maximum session count: %lu\n",
1873               tokenInfo.ulMaxSessionCount);
1874     PKM_LogIt("    session count: %lu\n", tokenInfo.ulSessionCount);
1875     PKM_LogIt("    maximum read/write session count: %lu\n",
1876               tokenInfo.ulMaxRwSessionCount);
1877     PKM_LogIt("    read/write session count: %lu\n",
1878               tokenInfo.ulRwSessionCount);
1879     PKM_LogIt("    maximum PIN length: %lu\n", tokenInfo.ulMaxPinLen);
1880     PKM_LogIt("    minimum PIN length: %lu\n", tokenInfo.ulMinPinLen);
1881     PKM_LogIt("    total public memory: %lu\n",
1882               tokenInfo.ulTotalPublicMemory);
1883     PKM_LogIt("    free public memory: %lu\n",
1884               tokenInfo.ulFreePublicMemory);
1885     PKM_LogIt("    total private memory: %lu\n",
1886               tokenInfo.ulTotalPrivateMemory);
1887     PKM_LogIt("    free private memory: %lu\n",
1888               tokenInfo.ulFreePrivateMemory);
1889     PKM_LogIt("    hardware version number: %d.%d\n",
1890               (int)tokenInfo.hardwareVersion.major,
1891               (int)tokenInfo.hardwareVersion.minor);
1892     PKM_LogIt("    firmware version number: %d.%d\n",
1893               (int)tokenInfo.firmwareVersion.major,
1894               (int)tokenInfo.firmwareVersion.minor);
1895     if (tokenInfo.flags & CKF_CLOCK_ON_TOKEN) {
1896         PKM_LogIt("    current time: %.16s\n", tokenInfo.utcTime);
1897     }
1898     PKM_LogIt("PKM_ShowInfo done \n\n");
1899     free(pSlotList);
1900     return crv;
1901 }
1902 
1903 /* PKM_HybridMode                                                         */
1904 /* The NSS cryptographic module has two modes of operation: FIPS Approved */
1905 /* mode and NONFIPS Approved mode. The two modes of operation are         */
1906 /* independent of each other -- they have their own copies of data        */
1907 /* structures and they are even allowed to be active at the same time.    */
1908 /* The module is FIPS 140-2 compliant only when the NONFIPS mode          */
1909 /* is inactive.                                                           */
1910 /* PKM_HybridMode demostrates how an application can switch between the   */
1911 /* two modes: FIPS Approved mode and NONFIPS mode.                        */
1912 CK_RV
PKM_HybridMode(CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen,CK_C_INITIALIZE_ARGS_NSS * initArgs)1913 PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
1914                CK_C_INITIALIZE_ARGS_NSS *initArgs)
1915 {
1916 
1917     CK_C_GetFunctionList pC_GetFunctionList; /* NONFIPSMode */
1918     CK_FUNCTION_LIST_PTR pC_FunctionList;
1919     CK_SLOT_ID *pC_SlotList = NULL;
1920     CK_ULONG slotID_C = 1;
1921     CK_C_GetFunctionList pFC_GetFunctionList; /* FIPSMode */
1922     CK_FUNCTION_LIST_PTR pFC_FunctionList;
1923     CK_SLOT_ID *pFC_SlotList = NULL;
1924     CK_ULONG slotID_FC = 0;
1925     CK_RV crv = CKR_OK;
1926     CK_SESSION_HANDLE hSession;
1927     int origMode = MODE; /* remember the orginal MODE value */
1928 
1929     NUMTESTS++; /* increment NUMTESTS */
1930     MODE = NONFIPSMODE;
1931 #ifdef _WIN32
1932     /* NON FIPS mode  == C_GetFunctionList */
1933     pC_GetFunctionList = (CK_C_GetFunctionList)
1934         GetProcAddress(hModule, "C_GetFunctionList");
1935     if (pC_GetFunctionList == NULL) {
1936         PKM_Error("cannot load %s\n", LIB_NAME);
1937         return crv;
1938     }
1939 #else
1940     pC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
1941                                                                      "C_GetFunctionList");
1942     assert(pC_GetFunctionList != NULL);
1943 #endif
1944     PKM_LogIt("loading C_GetFunctionList for Non FIPS Mode; slotID %d \n",
1945               slotID_C);
1946     crv = (*pC_GetFunctionList)(&pC_FunctionList);
1947     assert(crv == CKR_OK);
1948 
1949     /* invoke C_Initialize as pC_FunctionList->C_Initialize */
1950     crv = pC_FunctionList->C_Initialize(initArgs);
1951     if (crv == CKR_OK) {
1952         PKM_LogIt("C_Initialize succeeded\n");
1953     } else {
1954         PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv,
1955                   PKM_CK_RVtoStr(crv));
1956         return crv;
1957     }
1958 
1959     pC_SlotList = PKM_GetSlotList(pC_FunctionList, slotID_C);
1960     if (pC_SlotList == NULL) {
1961         PKM_Error("PKM_GetSlotList failed with \n");
1962         return crv;
1963     }
1964     crv = pC_FunctionList->C_OpenSession(pC_SlotList[slotID_C],
1965                                          CKF_SERIAL_SESSION,
1966                                          NULL, NULL, &hSession);
1967     if (crv == CKR_OK) {
1968         PKM_LogIt("NONFIPS C_OpenSession succeeded\n");
1969     } else {
1970         PKM_Error("C_OpenSession failed for NONFIPS token "
1971                   "with 0x%08X, %-26s\n",
1972                   crv, PKM_CK_RVtoStr(crv));
1973         return crv;
1974     }
1975 
1976     crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
1977     if (crv == CKR_OK) {
1978         PKM_LogIt("able to login in NONFIPS token\n");
1979     } else {
1980         PKM_Error("Unable to login in to NONFIPS token "
1981                   "with 0x%08X, %-26s\n",
1982                   crv, PKM_CK_RVtoStr(crv));
1983         return crv;
1984     }
1985 
1986     crv = pC_FunctionList->C_Logout(hSession);
1987     if (crv == CKR_OK) {
1988         PKM_LogIt("C_Logout succeeded\n");
1989     } else {
1990         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
1991                   PKM_CK_RVtoStr(crv));
1992         return crv;
1993     }
1994 
1995     PKM_ShowInfo(pC_FunctionList, slotID_C);
1996     MODE = HYBRIDMODE;
1997 
1998     /* Now load the FIPS token */
1999     /* FIPS mode == FC_GetFunctionList */
2000     pFC_GetFunctionList = NULL;
2001 #ifdef _WIN32
2002     pFC_GetFunctionList = (CK_C_GetFunctionList)
2003         GetProcAddress(hModule, "FC_GetFunctionList");
2004 #else
2005     pFC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
2006                                                                       "FC_GetFunctionList");
2007     assert(pFC_GetFunctionList != NULL);
2008 #endif
2009 
2010     PKM_LogIt("loading FC_GetFunctionList for FIPS Mode; slotID %d \n",
2011               slotID_FC);
2012     PKM_LogIt("pFC_FunctionList->C_Foo == pFC_FunctionList->FC_Foo\n");
2013     if (pFC_GetFunctionList == NULL) {
2014         PKM_Error("unable to load pFC_GetFunctionList\n");
2015         return crv;
2016     }
2017 
2018     crv = (*pFC_GetFunctionList)(&pFC_FunctionList);
2019     assert(crv == CKR_OK);
2020 
2021     /* invoke FC_Initialize as pFunctionList->C_Initialize */
2022     crv = pFC_FunctionList->C_Initialize(initArgs);
2023     if (crv == CKR_OK) {
2024         PKM_LogIt("FC_Initialize succeeded\n");
2025     } else {
2026         PKM_Error("FC_Initialize failed with 0x%08X, %-26s\n", crv,
2027                   PKM_CK_RVtoStr(crv));
2028         return crv;
2029     }
2030     PKM_ShowInfo(pFC_FunctionList, slotID_FC);
2031 
2032     pFC_SlotList = PKM_GetSlotList(pFC_FunctionList, slotID_FC);
2033     if (pFC_SlotList == NULL) {
2034         PKM_Error("PKM_GetSlotList failed with \n");
2035         return crv;
2036     }
2037 
2038     crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
2039     if (crv != CKR_OK) {
2040         PKM_LogIt("NONFIPS token cannot log in when FIPS token is loaded\n");
2041     } else {
2042         PKM_Error("Able to login in to NONFIPS token\n");
2043         return crv;
2044     }
2045     crv = pC_FunctionList->C_CloseSession(hSession);
2046     if (crv == CKR_OK) {
2047         PKM_LogIt("NONFIPS pC_CloseSession succeeded\n");
2048     } else {
2049         PKM_Error("pC_CloseSession failed for NONFIPS token "
2050                   "with 0x%08X, %-26s\n",
2051                   crv, PKM_CK_RVtoStr(crv));
2052         return crv;
2053     }
2054 
2055     PKM_LogIt("The module is FIPS 140-2 compliant\n"
2056               "only when the NONFIPS Approved mode is inactive by \n"
2057               "calling C_Finalize on the NONFIPS token.\n");
2058 
2059     /* to go in FIPSMODE you must Finalize the NONFIPS mode pointer */
2060     crv = pC_FunctionList->C_Finalize(NULL);
2061     if (crv == CKR_OK) {
2062         PKM_LogIt("C_Finalize of NONFIPS Token succeeded\n");
2063         MODE = FIPSMODE;
2064     } else {
2065         PKM_Error("C_Finalize of NONFIPS Token failed with "
2066                   "0x%08X, %-26s\n",
2067                   crv,
2068                   PKM_CK_RVtoStr(crv));
2069         return crv;
2070     }
2071 
2072     PKM_LogIt("*** In FIPS mode!  ***\n");
2073 
2074     /* could do some operations in FIPS MODE */
2075 
2076     crv = pFC_FunctionList->C_Finalize(NULL);
2077     if (crv == CKR_OK) {
2078         PKM_LogIt("Exiting FIPSMODE by caling FC_Finalize.\n");
2079         MODE = NOMODE;
2080     } else {
2081         PKM_Error("FC_Finalize failed with 0x%08X, %-26s\n", crv,
2082                   PKM_CK_RVtoStr(crv));
2083         return crv;
2084     }
2085 
2086     if (pC_SlotList)
2087         free(pC_SlotList);
2088     if (pFC_SlotList)
2089         free(pFC_SlotList);
2090 
2091     MODE = origMode; /* set the mode back to the orginal Mode value */
2092     PKM_LogIt("PKM_HybridMode test Completed\n\n");
2093     return crv;
2094 }
2095 
2096 CK_RV
PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID)2097 PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
2098               CK_SLOT_ID *pSlotList, CK_ULONG slotID)
2099 {
2100 
2101     CK_RV crv = CKR_OK;
2102     CK_MECHANISM_TYPE *pMechanismList;
2103     CK_ULONG mechanismCount;
2104     CK_ULONG i;
2105     const char *mechName = NULL;
2106 
2107     NUMTESTS++; /* increment NUMTESTS */
2108 
2109     /* Get the mechanism list */
2110     crv = pFunctionList->C_GetMechanismList(pSlotList[slotID],
2111                                             NULL, &mechanismCount);
2112     if (crv != CKR_OK) {
2113         PKM_Error("C_GetMechanismList failed with 0x%08X, %-26s\n", crv,
2114                   PKM_CK_RVtoStr(crv));
2115         return crv;
2116     }
2117     PKM_LogIt("C_GetMechanismList reported there are %lu mechanisms\n",
2118               mechanismCount);
2119     pMechanismList = (CK_MECHANISM_TYPE *)
2120         malloc(mechanismCount * sizeof(CK_MECHANISM_TYPE));
2121     if (!pMechanismList) {
2122         PKM_Error("failed to allocate mechanism list\n");
2123         return crv;
2124     }
2125     crv = pFunctionList->C_GetMechanismList(pSlotList[slotID],
2126                                             pMechanismList, &mechanismCount);
2127     if (crv != CKR_OK) {
2128         PKM_Error("C_GetMechanismList failed with 0x%08X, %-26s\n", crv,
2129                   PKM_CK_RVtoStr(crv));
2130         return crv;
2131     }
2132     PKM_LogIt("C_GetMechanismList returned the mechanism types:\n");
2133     if (verbose) {
2134         for (i = 0; i < mechanismCount; i++) {
2135             mechName = getName(pMechanismList[(i)], ConstMechanism);
2136 
2137             /* output two mechanism name on each line */
2138             /* currently the longest known mechansim name length is 37 */
2139             if (mechName) {
2140                 printf("%-40s", mechName);
2141             } else {
2142                 printf("Unknown mechanism: 0x%08lX ", pMechanismList[i]);
2143             }
2144             if ((i % 2) == 1)
2145                 printf("\n");
2146         }
2147         printf("\n\n");
2148     }
2149 
2150     for (i = 0; i < mechanismCount; i++) {
2151         CK_MECHANISM_INFO minfo;
2152 
2153         memset(&minfo, 0, sizeof(CK_MECHANISM_INFO));
2154         crv = pFunctionList->C_GetMechanismInfo(pSlotList[slotID],
2155                                                 pMechanismList[i], &minfo);
2156         if (CKR_OK != crv) {
2157             PKM_Error("C_GetMechanismInfo(%lu, %lu) returned 0x%08X, %-26s\n",
2158                       pSlotList[slotID], pMechanismList[i], crv,
2159                       PKM_CK_RVtoStr(crv));
2160             return crv;
2161         }
2162 
2163         mechName = getName(pMechanismList[i], ConstMechanism);
2164         if (!mechName)
2165             mechName = "Unknown mechanism";
2166         PKM_LogIt("    [%lu]: CK_MECHANISM_TYPE = %s 0x%08lX\n", (i + 1),
2167                   mechName,
2168                   pMechanismList[i]);
2169         PKM_LogIt("    ulMinKeySize = %lu\n", minfo.ulMinKeySize);
2170         PKM_LogIt("    ulMaxKeySize = %lu\n", minfo.ulMaxKeySize);
2171         PKM_LogIt("    flags = 0x%08x\n", minfo.flags);
2172         PKM_LogIt("        -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" : "FALSE");
2173         PKM_LogIt("        -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE");
2174         PKM_LogIt("        -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE");
2175         PKM_LogIt("        -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE");
2176         PKM_LogIt("        -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE");
2177         PKM_LogIt("        -> SIGN_RECOVER = %s\n", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE");
2178         PKM_LogIt("        -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE");
2179         PKM_LogIt("        -> VERIFY_RECOVER = %s\n",
2180                   minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE");
2181         PKM_LogIt("        -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE");
2182         PKM_LogIt("        -> GENERATE_KEY_PAIR = %s\n",
2183                   minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE");
2184         PKM_LogIt("        -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE");
2185         PKM_LogIt("        -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE");
2186         PKM_LogIt("        -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE");
2187         PKM_LogIt("        -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE");
2188 
2189         PKM_LogIt("\n");
2190     }
2191 
2192     return crv;
2193 }
2194 
2195 CK_RV
PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID)2196 PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
2197         CK_ULONG slotID)
2198 {
2199     CK_SESSION_HANDLE hSession;
2200     CK_RV crv = CKR_OK;
2201     CK_BYTE randomData[16];
2202     CK_BYTE seed[] = { 0x01, 0x03, 0x35, 0x55, 0xFF };
2203 
2204     NUMTESTS++; /* increment NUMTESTS */
2205 
2206     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
2207                                        NULL, NULL, &hSession);
2208     if (crv != CKR_OK) {
2209         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
2210                   PKM_CK_RVtoStr(crv));
2211         return crv;
2212     }
2213 
2214     crv = pFunctionList->C_GenerateRandom(hSession,
2215                                           randomData, sizeof randomData);
2216     if (crv == CKR_OK) {
2217         PKM_LogIt("C_GenerateRandom without login succeeded\n");
2218     } else {
2219         PKM_Error("C_GenerateRandom without login failed "
2220                   "with 0x%08X, %-26s\n",
2221                   crv, PKM_CK_RVtoStr(crv));
2222         return crv;
2223     }
2224     crv = pFunctionList->C_SeedRandom(hSession, seed, sizeof(seed));
2225     if (crv == CKR_OK) {
2226         PKM_LogIt("C_SeedRandom without login succeeded\n");
2227     } else {
2228         PKM_Error("C_SeedRandom without login failed "
2229                   "with 0x%08X, %-26s\n",
2230                   crv, PKM_CK_RVtoStr(crv));
2231         return crv;
2232     }
2233     crv = pFunctionList->C_GenerateRandom(hSession,
2234                                           randomData, sizeof randomData);
2235     if (crv == CKR_OK) {
2236         PKM_LogIt("C_GenerateRandom without login succeeded\n");
2237     } else {
2238         PKM_Error("C_GenerateRandom without login failed "
2239                   "with 0x%08X, %-26s\n",
2240                   crv, PKM_CK_RVtoStr(crv));
2241         return crv;
2242     }
2243     crv = pFunctionList->C_CloseSession(hSession);
2244     if (crv != CKR_OK) {
2245         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
2246                   PKM_CK_RVtoStr(crv));
2247         return crv;
2248     }
2249 
2250     return crv;
2251 }
2252 
2253 CK_RV
PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)2254 PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,
2255                  CK_SLOT_ID *pSlotList, CK_ULONG slotID,
2256                  CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
2257 {
2258     CK_SESSION_HANDLE hSession;
2259     CK_RV crv = CKR_OK;
2260 
2261     NUMTESTS++; /* increment NUMTESTS */
2262 
2263     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
2264                                        NULL, NULL, &hSession);
2265     if (crv != CKR_OK) {
2266         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
2267                   PKM_CK_RVtoStr(crv));
2268         return crv;
2269     }
2270 
2271     crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *)"netscape", 8);
2272     if (crv == CKR_OK) {
2273         PKM_Error("C_Login with wrong password succeeded\n");
2274         return CKR_FUNCTION_FAILED;
2275     } else {
2276         PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
2277                   "%-26s.\n ",
2278                   crv, PKM_CK_RVtoStr(crv));
2279     }
2280     crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *)"red hat", 7);
2281     if (crv == CKR_OK) {
2282         PKM_Error("C_Login with wrong password succeeded\n");
2283         return CKR_FUNCTION_FAILED;
2284     } else {
2285         PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
2286                   "%-26s.\n ",
2287                   crv, PKM_CK_RVtoStr(crv));
2288     }
2289     crv = pFunctionList->C_Login(hSession, CKU_USER,
2290                                  (unsigned char *)"sun", 3);
2291     if (crv == CKR_OK) {
2292         PKM_Error("C_Login with wrong password succeeded\n");
2293         return CKR_FUNCTION_FAILED;
2294     } else {
2295         PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
2296                   "%-26s.\n ",
2297                   crv, PKM_CK_RVtoStr(crv));
2298     }
2299     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
2300     if (crv == CKR_OK) {
2301         PKM_LogIt("C_Login with correct password succeeded\n");
2302     } else {
2303         PKM_Error("C_Login with correct password failed "
2304                   "with 0x%08X, %-26s\n",
2305                   crv, PKM_CK_RVtoStr(crv));
2306         return crv;
2307     }
2308 
2309     crv = pFunctionList->C_Logout(hSession);
2310     if (crv == CKR_OK) {
2311         PKM_LogIt("C_Logout succeeded\n");
2312     } else {
2313         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
2314                   PKM_CK_RVtoStr(crv));
2315         return crv;
2316     }
2317 
2318     crv = pFunctionList->C_CloseSession(hSession);
2319     if (crv != CKR_OK) {
2320         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
2321                   PKM_CK_RVtoStr(crv));
2322         return crv;
2323     }
2324 
2325     return crv;
2326 }
2327 
2328 /*
2329 * PKM_LegacyFunctions
2330 *
2331 * Legacyfunctions exist only for backwards compatibility.
2332 * C_GetFunctionStatus and C_CancelFunction functions were
2333 * meant for managing parallel execution of cryptographic functions.
2334 *
2335 * C_GetFunctionStatus is a legacy function which should simply return
2336 * the value CKR_FUNCTION_NOT_PARALLEL.
2337 *
2338 * C_CancelFunction is a legacy function which should simply return the
2339 * value CKR_FUNCTION_NOT_PARALLEL.
2340 *
2341 */
2342 CK_RV
PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)2343 PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
2344                     CK_SLOT_ID *pSlotList, CK_ULONG slotID,
2345                     CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
2346 {
2347     CK_SESSION_HANDLE hSession;
2348     CK_RV crv = CKR_OK;
2349     NUMTESTS++; /* increment NUMTESTS */
2350 
2351     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
2352                                        NULL, NULL, &hSession);
2353     if (crv != CKR_OK) {
2354         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
2355                   PKM_CK_RVtoStr(crv));
2356         return crv;
2357     }
2358 
2359     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
2360     if (crv == CKR_OK) {
2361         PKM_LogIt("C_Login with correct password succeeded\n");
2362     } else {
2363         PKM_Error("C_Login with correct password failed "
2364                   "with 0x%08X, %-26s\n",
2365                   crv, PKM_CK_RVtoStr(crv));
2366         return crv;
2367     }
2368 
2369     crv = pFunctionList->C_GetFunctionStatus(hSession);
2370     if (crv == CKR_FUNCTION_NOT_PARALLEL) {
2371         PKM_LogIt("C_GetFunctionStatus correctly"
2372                   "returned CKR_FUNCTION_NOT_PARALLEL \n");
2373     } else {
2374         PKM_Error("C_GetFunctionStatus failed "
2375                   "with 0x%08X, %-26s\n",
2376                   crv, PKM_CK_RVtoStr(crv));
2377         return crv;
2378     }
2379 
2380     crv = pFunctionList->C_CancelFunction(hSession);
2381     if (crv == CKR_FUNCTION_NOT_PARALLEL) {
2382         PKM_LogIt("C_CancelFunction correctly "
2383                   "returned CKR_FUNCTION_NOT_PARALLEL \n");
2384     } else {
2385         PKM_Error("C_CancelFunction failed "
2386                   "with 0x%08X, %-26s\n",
2387                   crv, PKM_CK_RVtoStr(crv));
2388         return crv;
2389     }
2390 
2391     crv = pFunctionList->C_Logout(hSession);
2392     if (crv == CKR_OK) {
2393         PKM_LogIt("C_Logout succeeded\n");
2394     } else {
2395         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
2396                   PKM_CK_RVtoStr(crv));
2397         return crv;
2398     }
2399 
2400     crv = pFunctionList->C_CloseSession(hSession);
2401     if (crv != CKR_OK) {
2402         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
2403                   PKM_CK_RVtoStr(crv));
2404         return crv;
2405     }
2406 
2407     return crv;
2408 }
2409 
2410 /*
2411 *  PKM_DualFuncDigest - demostrates the Dual-function
2412 *  cryptograpic functions:
2413 *
2414 *   C_DigestEncryptUpdate - multi-part Digest and Encrypt
2415 *   C_DecryptDigestUpdate - multi-part Decrypt and Digest
2416 *
2417 *
2418 */
2419 
2420 CK_RV
PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hSecKey,CK_MECHANISM * cryptMech,CK_OBJECT_HANDLE hSecKeyDigest,CK_MECHANISM * digestMech,const CK_BYTE * pData,CK_ULONG pDataLen)2421 PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,
2422                    CK_SESSION_HANDLE hSession,
2423                    CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech,
2424                    CK_OBJECT_HANDLE hSecKeyDigest,
2425                    CK_MECHANISM *digestMech,
2426                    const CK_BYTE *pData, CK_ULONG pDataLen)
2427 {
2428     CK_RV crv = CKR_OK;
2429     CK_BYTE eDigest[MAX_DIGEST_SZ];
2430     CK_BYTE dDigest[MAX_DIGEST_SZ];
2431     CK_ULONG ulDigestLen;
2432     CK_BYTE ciphertext[MAX_CIPHER_SZ];
2433     CK_ULONG ciphertextLen, lastLen;
2434     CK_BYTE plaintext[MAX_DATA_SZ];
2435     CK_ULONG plaintextLen;
2436     unsigned int i;
2437 
2438     memset(eDigest, 0, sizeof(eDigest));
2439     memset(dDigest, 0, sizeof(dDigest));
2440     memset(ciphertext, 0, sizeof(ciphertext));
2441     memset(plaintext, 0, sizeof(plaintext));
2442 
2443     NUMTESTS++; /* increment NUMTESTS */
2444 
2445     /*
2446      * First init the Digest and Ecrypt operations
2447      */
2448     crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSecKey);
2449     if (crv != CKR_OK) {
2450         PKM_Error("C_EncryptInit failed with 0x%08X, %-26s\n", crv,
2451                   PKM_CK_RVtoStr(crv));
2452         return crv;
2453     }
2454     crv = pFunctionList->C_DigestInit(hSession, digestMech);
2455     if (crv != CKR_OK) {
2456         PKM_Error("C_DigestInit failed with 0x%08X, %-26s\n", crv,
2457                   PKM_CK_RVtoStr(crv));
2458         return crv;
2459     }
2460 
2461     ciphertextLen = sizeof(ciphertext);
2462     crv = pFunctionList->C_DigestEncryptUpdate(hSession, (CK_BYTE *)pData,
2463                                                pDataLen,
2464                                                ciphertext, &ciphertextLen);
2465     if (crv != CKR_OK) {
2466         PKM_Error("C_DigestEncryptUpdate failed with 0x%08X, %-26s\n", crv,
2467                   PKM_CK_RVtoStr(crv));
2468         return crv;
2469     }
2470 
2471     ulDigestLen = sizeof(eDigest);
2472     crv = pFunctionList->C_DigestFinal(hSession, eDigest, &ulDigestLen);
2473     if (crv != CKR_OK) {
2474         PKM_Error("C_DigestFinal failed with 0x%08X, %-26s\n", crv,
2475                   PKM_CK_RVtoStr(crv));
2476         return crv;
2477     }
2478 
2479     /* get the last piece of ciphertext (length should be 0 */
2480     lastLen = sizeof(ciphertext) - ciphertextLen;
2481     crv = pFunctionList->C_EncryptFinal(hSession,
2482                                         (CK_BYTE *)&ciphertext[ciphertextLen],
2483                                         &lastLen);
2484     if (crv != CKR_OK) {
2485         PKM_Error("C_EncryptFinal failed with 0x%08X, %-26s\n", crv,
2486                   PKM_CK_RVtoStr(crv));
2487         return crv;
2488     }
2489     ciphertextLen = ciphertextLen + lastLen;
2490     if (verbose) {
2491         printf("ciphertext = ");
2492         for (i = 0; i < ciphertextLen; i++) {
2493             printf("%02x", (unsigned)ciphertext[i]);
2494         }
2495         printf("\n");
2496         printf("eDigest = ");
2497         for (i = 0; i < ulDigestLen; i++) {
2498             printf("%02x", (unsigned)eDigest[i]);
2499         }
2500         printf("\n");
2501     }
2502 
2503     /* Decrypt the text */
2504     crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSecKey);
2505     if (crv != CKR_OK) {
2506         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2507                   PKM_CK_RVtoStr(crv));
2508         return crv;
2509     }
2510     crv = pFunctionList->C_DigestInit(hSession, digestMech);
2511     if (crv != CKR_OK) {
2512         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2513                   PKM_CK_RVtoStr(crv));
2514         return crv;
2515     }
2516 
2517     plaintextLen = sizeof(plaintext);
2518     crv = pFunctionList->C_DecryptDigestUpdate(hSession, ciphertext,
2519                                                ciphertextLen,
2520                                                plaintext,
2521                                                &plaintextLen);
2522     if (crv != CKR_OK) {
2523         PKM_Error("C_DecryptDigestUpdate failed with 0x%08X, %-26s\n", crv,
2524                   PKM_CK_RVtoStr(crv));
2525         return crv;
2526     }
2527     lastLen = sizeof(plaintext) - plaintextLen;
2528 
2529     crv = pFunctionList->C_DecryptFinal(hSession,
2530                                         (CK_BYTE *)&plaintext[plaintextLen],
2531                                         &lastLen);
2532     if (crv != CKR_OK) {
2533         PKM_Error("C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
2534                   PKM_CK_RVtoStr(crv));
2535         return crv;
2536     }
2537     plaintextLen = plaintextLen + lastLen;
2538 
2539     ulDigestLen = sizeof(dDigest);
2540     crv = pFunctionList->C_DigestFinal(hSession, dDigest, &ulDigestLen);
2541     if (crv != CKR_OK) {
2542         PKM_Error("C_DigestFinal failed with 0x%08X, %-26s\n", crv,
2543                   PKM_CK_RVtoStr(crv));
2544         return crv;
2545     }
2546 
2547     if (plaintextLen != pDataLen) {
2548         PKM_Error("plaintextLen is %lu\n", plaintextLen);
2549         return crv;
2550     }
2551 
2552     if (verbose) {
2553         printf("plaintext = ");
2554         for (i = 0; i < plaintextLen; i++) {
2555             printf("%02x", (unsigned)plaintext[i]);
2556         }
2557         printf("\n");
2558         printf("dDigest = ");
2559         for (i = 0; i < ulDigestLen; i++) {
2560             printf("%02x", (unsigned)dDigest[i]);
2561         }
2562         printf("\n");
2563     }
2564 
2565     if (memcmp(eDigest, dDigest, ulDigestLen) == 0) {
2566         PKM_LogIt("Encrypted Digest equals Decrypted Digest\n");
2567     } else {
2568         PKM_Error("Digests don't match\n");
2569     }
2570 
2571     if ((plaintextLen == pDataLen) &&
2572         (memcmp(plaintext, pData, pDataLen)) == 0) {
2573         PKM_LogIt("DualFuncDigest decrypt test case passed\n");
2574     } else {
2575         PKM_Error("DualFuncDigest derypt test case failed\n");
2576     }
2577 
2578     return crv;
2579 }
2580 
2581 /*
2582 * PKM_SecKeyCrypt - Symmetric key encrypt/decyprt
2583 *
2584 */
2585 
2586 CK_RV
PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hSymKey,CK_MECHANISM * cryptMech,const CK_BYTE * pData,CK_ULONG dataLen)2587 PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList,
2588                 CK_SESSION_HANDLE hSession,
2589                 CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech,
2590                 const CK_BYTE *pData, CK_ULONG dataLen)
2591 {
2592     CK_RV crv = CKR_OK;
2593 
2594     CK_BYTE cipher1[MAX_CIPHER_SZ];
2595     CK_BYTE cipher2[MAX_CIPHER_SZ];
2596     CK_BYTE data1[MAX_DATA_SZ];
2597     CK_BYTE data2[MAX_DATA_SZ];
2598     CK_ULONG cipher1Len = 0, cipher2Len = 0, lastLen = 0;
2599     CK_ULONG data1Len = 0, data2Len = 0;
2600 
2601     NUMTESTS++; /* increment NUMTESTS */
2602 
2603     memset(cipher1, 0, sizeof(cipher1));
2604     memset(cipher2, 0, sizeof(cipher2));
2605     memset(data1, 0, sizeof(data1));
2606     memset(data2, 0, sizeof(data2));
2607 
2608     /* C_Encrypt */
2609     crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey);
2610     if (crv != CKR_OK) {
2611         PKM_Error("C_EncryptInit failed with 0x%08X, %-26s\n", crv,
2612                   PKM_CK_RVtoStr(crv));
2613         return crv;
2614     }
2615     cipher1Len = sizeof(cipher1);
2616     crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE *)pData, dataLen,
2617                                    cipher1, &cipher1Len);
2618     if (crv != CKR_OK) {
2619         PKM_Error("C_Encrypt failed with 0x%08X, %-26s\n", crv,
2620                   PKM_CK_RVtoStr(crv));
2621         return crv;
2622     }
2623 
2624     /* C_EncryptUpdate */
2625     crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey);
2626     if (crv != CKR_OK) {
2627         PKM_Error("C_EncryptInit failed with 0x%08X, %-26s\n", crv,
2628                   PKM_CK_RVtoStr(crv));
2629         return crv;
2630     }
2631     cipher2Len = sizeof(cipher2);
2632     crv = pFunctionList->C_EncryptUpdate(hSession, (CK_BYTE *)pData,
2633                                          dataLen,
2634                                          cipher2, &cipher2Len);
2635     if (crv != CKR_OK) {
2636         PKM_Error("C_EncryptUpdate failed with 0x%08X, %-26s\n", crv,
2637                   PKM_CK_RVtoStr(crv));
2638         return crv;
2639     }
2640     lastLen = sizeof(cipher2) - cipher2Len;
2641 
2642     crv = pFunctionList->C_EncryptFinal(hSession,
2643                                         (CK_BYTE *)&cipher2[cipher2Len],
2644                                         &lastLen);
2645     cipher2Len = cipher2Len + lastLen;
2646 
2647     if ((cipher1Len == cipher2Len) &&
2648         (memcmp(cipher1, cipher2, sizeof(cipher1Len)) == 0)) {
2649         PKM_LogIt("encrypt test case passed\n");
2650     } else {
2651         PKM_Error("encrypt test case failed\n");
2652         return CKR_GENERAL_ERROR;
2653     }
2654 
2655     /* C_Decrypt */
2656     crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey);
2657     if (crv != CKR_OK) {
2658         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2659                   PKM_CK_RVtoStr(crv));
2660         return crv;
2661     }
2662     data1Len = sizeof(data1);
2663     crv = pFunctionList->C_Decrypt(hSession, cipher1, cipher1Len,
2664                                    data1, &data1Len);
2665     if (crv != CKR_OK) {
2666         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2667                   PKM_CK_RVtoStr(crv));
2668         return crv;
2669     }
2670     /* now use C_DecryptUpdate the text */
2671     crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey);
2672     if (crv != CKR_OK) {
2673         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2674                   PKM_CK_RVtoStr(crv));
2675         return crv;
2676     }
2677     data2Len = sizeof(data2);
2678     crv = pFunctionList->C_DecryptUpdate(hSession, cipher2,
2679                                          cipher2Len,
2680                                          data2, &data2Len);
2681     if (crv != CKR_OK) {
2682         PKM_Error("C_DecryptUpdate failed with 0x%08X, %-26s\n", crv,
2683                   PKM_CK_RVtoStr(crv));
2684         return crv;
2685     }
2686     lastLen = sizeof(data2) - data2Len;
2687     crv = pFunctionList->C_DecryptFinal(hSession,
2688                                         (CK_BYTE *)&data2[data2Len],
2689                                         &lastLen);
2690     if (crv != CKR_OK) {
2691         PKM_Error("C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
2692                   PKM_CK_RVtoStr(crv));
2693         return crv;
2694     }
2695     data2Len = data2Len + lastLen;
2696 
2697     /* Comparison of Decrypt data */
2698 
2699     if ((data1Len == data2Len) && (dataLen == data1Len) &&
2700         (memcmp(data1, pData, dataLen) == 0) &&
2701         (memcmp(data2, pData, dataLen) == 0)) {
2702         PKM_LogIt("decrypt test case passed\n");
2703     } else {
2704         PKM_Error("derypt test case failed\n");
2705     }
2706 
2707     return crv;
2708 }
2709 
2710 CK_RV
PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)2711 PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList,
2712               CK_SLOT_ID *pSlotList, CK_ULONG slotID,
2713               CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
2714 {
2715     CK_SESSION_HANDLE hSession;
2716     CK_RV crv = CKR_OK;
2717     CK_MECHANISM sAESKeyMech = {
2718         CKM_AES_KEY_GEN, NULL, 0
2719     };
2720     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
2721     CK_KEY_TYPE keyAESType = CKK_AES;
2722     CK_UTF8CHAR AESlabel[] = "An AES secret key object";
2723     CK_ULONG AESvalueLen = 16;
2724     CK_ATTRIBUTE sAESKeyTemplate[9];
2725     CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
2726 
2727     CK_BYTE KEY[16];
2728     CK_BYTE IV[16];
2729     static const CK_BYTE CIPHERTEXT[] = {
2730         0x7e, 0x6a, 0x3f, 0x3b, 0x39, 0x3c, 0xf2, 0x4b,
2731         0xce, 0xcc, 0x23, 0x6d, 0x80, 0xfd, 0xe0, 0xff
2732     };
2733     CK_BYTE ciphertext[64];
2734     CK_BYTE ciphertext2[64];
2735     CK_ULONG ciphertextLen, ciphertext2Len, lastLen;
2736     CK_BYTE plaintext[32];
2737     CK_BYTE plaintext2[32];
2738     CK_ULONG plaintextLen, plaintext2Len;
2739     CK_BYTE wrappedKey[16];
2740     CK_ULONG wrappedKeyLen;
2741     CK_MECHANISM aesEcbMech = {
2742         CKM_AES_ECB, NULL, 0
2743     };
2744     CK_OBJECT_HANDLE hTestKey;
2745     CK_MECHANISM mech_AES_CBC;
2746 
2747     NUMTESTS++; /* increment NUMTESTS */
2748 
2749     memset(ciphertext, 0, sizeof(ciphertext));
2750     memset(ciphertext2, 0, sizeof(ciphertext2));
2751     memset(IV, 0x00, sizeof(IV));
2752     memset(KEY, 0x00, sizeof(KEY));
2753 
2754     mech_AES_CBC.mechanism = CKM_AES_CBC;
2755     mech_AES_CBC.pParameter = IV;
2756     mech_AES_CBC.ulParameterLen = sizeof(IV);
2757 
2758     /* AES key template */
2759     sAESKeyTemplate[0].type = CKA_CLASS;
2760     sAESKeyTemplate[0].pValue = &class;
2761     sAESKeyTemplate[0].ulValueLen = sizeof(class);
2762     sAESKeyTemplate[1].type = CKA_KEY_TYPE;
2763     sAESKeyTemplate[1].pValue = &keyAESType;
2764     sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
2765     sAESKeyTemplate[2].type = CKA_LABEL;
2766     sAESKeyTemplate[2].pValue = AESlabel;
2767     sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel) - 1;
2768     sAESKeyTemplate[3].type = CKA_ENCRYPT;
2769     sAESKeyTemplate[3].pValue = &true;
2770     sAESKeyTemplate[3].ulValueLen = sizeof(true);
2771     sAESKeyTemplate[4].type = CKA_DECRYPT;
2772     sAESKeyTemplate[4].pValue = &true;
2773     sAESKeyTemplate[4].ulValueLen = sizeof(true);
2774     sAESKeyTemplate[5].type = CKA_SIGN;
2775     sAESKeyTemplate[5].pValue = &true;
2776     sAESKeyTemplate[5].ulValueLen = sizeof(true);
2777     sAESKeyTemplate[6].type = CKA_VERIFY;
2778     sAESKeyTemplate[6].pValue = &true;
2779     sAESKeyTemplate[6].ulValueLen = sizeof(true);
2780     sAESKeyTemplate[7].type = CKA_UNWRAP;
2781     sAESKeyTemplate[7].pValue = &true;
2782     sAESKeyTemplate[7].ulValueLen = sizeof(true);
2783     sAESKeyTemplate[8].type = CKA_VALUE_LEN;
2784     sAESKeyTemplate[8].pValue = &AESvalueLen;
2785     sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
2786 
2787     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
2788                                        NULL, NULL, &hSession);
2789     if (crv != CKR_OK) {
2790         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
2791                   PKM_CK_RVtoStr(crv));
2792         return crv;
2793     }
2794 
2795     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
2796     if (crv == CKR_OK) {
2797         PKM_LogIt("C_Login with correct password succeeded\n");
2798     } else {
2799         PKM_Error("C_Login with correct password failed "
2800                   "with 0x%08X, %-26s\n",
2801                   crv, PKM_CK_RVtoStr(crv));
2802         return crv;
2803     }
2804 
2805     PKM_LogIt("Generate an AES key ... \n");
2806     /* generate an AES Secret Key */
2807     crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech,
2808                                        sAESKeyTemplate,
2809                                        NUM_ELEM(sAESKeyTemplate),
2810                                        &hKey);
2811     if (crv == CKR_OK) {
2812         PKM_LogIt("C_GenerateKey AES succeeded\n");
2813     } else {
2814         PKM_Error("C_GenerateKey AES failed with 0x%08X, %-26s\n",
2815                   crv, PKM_CK_RVtoStr(crv));
2816         return crv;
2817     }
2818 
2819     crv = pFunctionList->C_EncryptInit(hSession, &aesEcbMech, hKey);
2820     if (crv != CKR_OK) {
2821         PKM_Error("C_EncryptInit failed with 0x%08X, %-26s\n", crv,
2822                   PKM_CK_RVtoStr(crv));
2823         return crv;
2824     }
2825     wrappedKeyLen = sizeof(wrappedKey);
2826     crv = pFunctionList->C_Encrypt(hSession, KEY, sizeof(KEY),
2827                                    wrappedKey, &wrappedKeyLen);
2828     if (crv != CKR_OK) {
2829         PKM_Error("C_Encrypt failed with 0x%08X, %-26s\n", crv,
2830                   PKM_CK_RVtoStr(crv));
2831         return crv;
2832     }
2833     if (wrappedKeyLen != sizeof(wrappedKey)) {
2834         PKM_Error("wrappedKeyLen is %lu\n", wrappedKeyLen);
2835         return crv;
2836     }
2837     /* Import an encrypted key */
2838     crv = pFunctionList->C_UnwrapKey(hSession, &aesEcbMech, hKey,
2839                                      wrappedKey, wrappedKeyLen,
2840                                      sAESKeyTemplate,
2841                                      NUM_ELEM(sAESKeyTemplate),
2842                                      &hTestKey);
2843     if (crv != CKR_OK) {
2844         PKM_Error("C_UnwraPKey failed with 0x%08X, %-26s\n", crv,
2845                   PKM_CK_RVtoStr(crv));
2846         return crv;
2847     }
2848     /* AES Encrypt the text */
2849     crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey);
2850     if (crv != CKR_OK) {
2851         PKM_Error("C_EncryptInit failed with 0x%08X, %-26s\n", crv,
2852                   PKM_CK_RVtoStr(crv));
2853         return crv;
2854     }
2855     ciphertextLen = sizeof(ciphertext);
2856     crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE *)PLAINTEXT,
2857                                    sizeof(PLAINTEXT),
2858                                    ciphertext, &ciphertextLen);
2859     if (crv != CKR_OK) {
2860         PKM_Error("C_Encrypt failed with 0x%08X, %-26s\n", crv,
2861                   PKM_CK_RVtoStr(crv));
2862         return crv;
2863     }
2864 
2865     if ((ciphertextLen == sizeof(CIPHERTEXT)) &&
2866         (memcmp(ciphertext, CIPHERTEXT, ciphertextLen) == 0)) {
2867         PKM_LogIt("AES CBCVarKey128 encrypt test case 1 passed\n");
2868     } else {
2869         PKM_Error("AES CBCVarKey128 encrypt test case 1 failed\n");
2870         return crv;
2871     }
2872 
2873     /* now use EncryptUpdate the text */
2874     crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey);
2875     if (crv != CKR_OK) {
2876         PKM_Error("C_EncryptInit failed with 0x%08X, %-26s\n", crv,
2877                   PKM_CK_RVtoStr(crv));
2878         return crv;
2879     }
2880     ciphertext2Len = sizeof(ciphertext2);
2881     crv = pFunctionList->C_EncryptUpdate(hSession, (CK_BYTE *)PLAINTEXT,
2882                                          sizeof(PLAINTEXT),
2883                                          ciphertext2, &ciphertext2Len);
2884     if (crv != CKR_OK) {
2885         PKM_Error("C_EncryptUpdate failed with 0x%08X, %-26s\n", crv,
2886                   PKM_CK_RVtoStr(crv));
2887         return crv;
2888     }
2889     lastLen = sizeof(ciphertext2) - ciphertext2Len;
2890 
2891     crv = pFunctionList->C_EncryptFinal(hSession,
2892                                         (CK_BYTE *)&ciphertext2[ciphertext2Len],
2893                                         &lastLen);
2894     ciphertext2Len = ciphertext2Len + lastLen;
2895 
2896     if ((ciphertextLen == ciphertext2Len) &&
2897         (memcmp(ciphertext, ciphertext2, sizeof(CIPHERTEXT)) == 0) &&
2898         (memcmp(ciphertext2, CIPHERTEXT, sizeof(CIPHERTEXT)) == 0)) {
2899         PKM_LogIt("AES CBCVarKey128 encrypt test case 2 passed\n");
2900     } else {
2901         PKM_Error("AES CBCVarKey128 encrypt test case 2 failed\n");
2902         return CKR_GENERAL_ERROR;
2903     }
2904 
2905     /* AES CBC Decrypt the text */
2906     crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey);
2907     if (crv != CKR_OK) {
2908         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2909                   PKM_CK_RVtoStr(crv));
2910         return crv;
2911     }
2912     plaintextLen = sizeof(plaintext);
2913     crv = pFunctionList->C_Decrypt(hSession, ciphertext, ciphertextLen,
2914                                    plaintext, &plaintextLen);
2915     if (crv != CKR_OK) {
2916         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2917                   PKM_CK_RVtoStr(crv));
2918         return crv;
2919     }
2920     if ((plaintextLen == sizeof(PLAINTEXT)) &&
2921         (memcmp(plaintext, PLAINTEXT, plaintextLen) == 0)) {
2922         PKM_LogIt("AES CBCVarKey128 decrypt test case 1 passed\n");
2923     } else {
2924         PKM_Error("AES CBCVarKey128 derypt test case 1 failed\n");
2925     }
2926     /* now use DecryptUpdate the text */
2927     crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey);
2928     if (crv != CKR_OK) {
2929         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
2930                   PKM_CK_RVtoStr(crv));
2931         return crv;
2932     }
2933     plaintext2Len = sizeof(plaintext2);
2934     crv = pFunctionList->C_DecryptUpdate(hSession, ciphertext2,
2935                                          ciphertext2Len,
2936                                          plaintext2, &plaintext2Len);
2937     if (crv != CKR_OK) {
2938         PKM_Error("C_DecryptUpdate failed with 0x%08X, %-26s\n", crv,
2939                   PKM_CK_RVtoStr(crv));
2940         return crv;
2941     }
2942     lastLen = sizeof(plaintext2) - plaintext2Len;
2943     crv = pFunctionList->C_DecryptFinal(hSession,
2944                                         (CK_BYTE *)&plaintext2[plaintext2Len],
2945                                         &lastLen);
2946     plaintext2Len = plaintext2Len + lastLen;
2947 
2948     if ((plaintextLen == plaintext2Len) &&
2949         (memcmp(plaintext, plaintext2, plaintext2Len) == 0) &&
2950         (memcmp(plaintext2, PLAINTEXT, sizeof(PLAINTEXT)) == 0)) {
2951         PKM_LogIt("AES CBCVarKey128 decrypt test case 2 passed\n");
2952     } else {
2953         PKM_Error("AES CBCVarKey128 decrypt test case 2 failed\n");
2954         return CKR_GENERAL_ERROR;
2955     }
2956 
2957     crv = pFunctionList->C_Logout(hSession);
2958     if (crv == CKR_OK) {
2959         PKM_LogIt("C_Logout succeeded\n");
2960     } else {
2961         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
2962                   PKM_CK_RVtoStr(crv));
2963         return crv;
2964     }
2965     crv = pFunctionList->C_CloseSession(hSession);
2966     if (crv != CKR_OK) {
2967         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
2968                   PKM_CK_RVtoStr(crv));
2969         return crv;
2970     }
2971 
2972     return crv;
2973 }
2974 
2975 CK_RV
PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hRwSession,CK_OBJECT_HANDLE hPubKey,CK_OBJECT_HANDLE hPrivKey,CK_MECHANISM * signMech,const CK_BYTE * pData,CK_ULONG pDataLen)2976 PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList,
2977                CK_SESSION_HANDLE hRwSession,
2978                CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
2979                CK_MECHANISM *signMech, const CK_BYTE *pData,
2980                CK_ULONG pDataLen)
2981 {
2982     CK_RV crv = CKR_OK;
2983     CK_BYTE sig[MAX_SIG_SZ];
2984     CK_ULONG sigLen = 0;
2985 
2986     NUMTESTS++; /* increment NUMTESTS */
2987     memset(sig, 0, sizeof(sig));
2988 
2989     /* C_Sign  */
2990     crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey);
2991     if (crv != CKR_OK) {
2992         PKM_Error("C_SignInit failed with 0x%08X, %-26s\n", crv,
2993                   PKM_CK_RVtoStr(crv));
2994         return crv;
2995     }
2996     sigLen = sizeof(sig);
2997     crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE *)pData, pDataLen,
2998                                 sig, &sigLen);
2999     if (crv != CKR_OK) {
3000         PKM_Error("C_Sign failed with 0x%08X, %-26s\n", crv,
3001                   PKM_CK_RVtoStr(crv));
3002         return crv;
3003     }
3004 
3005     /* C_Verify the signature */
3006     crv = pFunctionList->C_VerifyInit(hRwSession, signMech, hPubKey);
3007     if (crv != CKR_OK) {
3008         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
3009                   PKM_CK_RVtoStr(crv));
3010         return crv;
3011     }
3012     crv = pFunctionList->C_Verify(hRwSession, (CK_BYTE *)pData, pDataLen,
3013                                   sig, sigLen);
3014     if (crv == CKR_OK) {
3015         PKM_LogIt("C_Verify succeeded\n");
3016     } else {
3017         PKM_Error("C_Verify failed with 0x%08X, %-26s\n", crv,
3018                   PKM_CK_RVtoStr(crv));
3019         return crv;
3020     }
3021 
3022     /* Check that the mechanism is Multi-part */
3023     if (signMech->mechanism == CKM_DSA ||
3024         signMech->mechanism == CKM_RSA_PKCS) {
3025         return crv;
3026     }
3027 
3028     memset(sig, 0, sizeof(sig));
3029     /* SignUpdate  */
3030     crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey);
3031     if (crv != CKR_OK) {
3032         PKM_Error("C_SignInit failed with 0x%08lX %-26s\n", crv,
3033                   PKM_CK_RVtoStr(crv));
3034         return crv;
3035     }
3036     crv = pFunctionList->C_SignUpdate(hRwSession, (CK_BYTE *)pData, pDataLen);
3037     if (crv != CKR_OK) {
3038         PKM_Error("C_Sign failed with 0x%08lX %-26s\n", crv,
3039                   PKM_CK_RVtoStr(crv));
3040         return crv;
3041     }
3042 
3043     sigLen = sizeof(sig);
3044     crv = pFunctionList->C_SignFinal(hRwSession, sig, &sigLen);
3045     if (crv != CKR_OK) {
3046         PKM_Error("C_Sign failed with 0x%08X, %-26s\n", crv,
3047                   PKM_CK_RVtoStr(crv));
3048         return crv;
3049     }
3050 
3051     /* C_VerifyUpdate the signature  */
3052     crv = pFunctionList->C_VerifyInit(hRwSession, signMech,
3053                                       hPubKey);
3054     if (crv != CKR_OK) {
3055         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
3056                   PKM_CK_RVtoStr(crv));
3057         return crv;
3058     }
3059     crv = pFunctionList->C_VerifyUpdate(hRwSession, (CK_BYTE *)pData,
3060                                         pDataLen);
3061     if (crv != CKR_OK) {
3062         PKM_Error("C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
3063                   PKM_CK_RVtoStr(crv));
3064         return crv;
3065     }
3066     crv = pFunctionList->C_VerifyFinal(hRwSession, sig, sigLen);
3067     if (crv == CKR_OK) {
3068         PKM_LogIt("C_VerifyFinal succeeded\n");
3069     } else {
3070         PKM_Error("C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
3071                   PKM_CK_RVtoStr(crv));
3072         return crv;
3073     }
3074     return crv;
3075 }
3076 
3077 CK_RV
PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)3078 PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList,
3079               CK_SLOT_ID *pSlotList,
3080               CK_ULONG slotID, CK_UTF8CHAR_PTR pwd,
3081               CK_ULONG pwdLen)
3082 {
3083     CK_SESSION_HANDLE hSession;
3084     CK_RV crv = CKR_OK;
3085 
3086     /*** DSA Key ***/
3087     CK_MECHANISM dsaParamGenMech;
3088     CK_ULONG primeBits = 1024;
3089     CK_ATTRIBUTE dsaParamGenTemplate[1];
3090     CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE;
3091     CK_BYTE DSA_P[128];
3092     CK_BYTE DSA_Q[20];
3093     CK_BYTE DSA_G[128];
3094     CK_MECHANISM dsaKeyPairGenMech;
3095     CK_ATTRIBUTE dsaPubKeyTemplate[5];
3096     CK_ATTRIBUTE dsaPrivKeyTemplate[5];
3097     CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
3098     CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
3099 
3100     /* From SHA1ShortMsg.req, Len = 136 */
3101     CK_BYTE MSG[] = {
3102         0xba, 0x33, 0x95, 0xfb,
3103         0x5a, 0xfa, 0x8e, 0x6a,
3104         0x43, 0xdf, 0x41, 0x6b,
3105         0x32, 0x7b, 0x74, 0xfa,
3106         0x44
3107     };
3108     CK_BYTE MD[] = {
3109         0xf7, 0x5d, 0x92, 0xa4,
3110         0xbb, 0x4d, 0xec, 0xc3,
3111         0x7c, 0x5c, 0x72, 0xfa,
3112         0x04, 0x75, 0x71, 0x0a,
3113         0x06, 0x75, 0x8c, 0x1d
3114     };
3115 
3116     CK_BYTE sha1Digest[20];
3117     CK_ULONG sha1DigestLen;
3118     CK_BYTE dsaSig[40];
3119     CK_ULONG dsaSigLen;
3120     CK_MECHANISM sha1Mech = {
3121         CKM_SHA_1, NULL, 0
3122     };
3123     CK_MECHANISM dsaMech = {
3124         CKM_DSA, NULL, 0
3125     };
3126     CK_MECHANISM dsaWithSha1Mech = {
3127         CKM_DSA_SHA1, NULL, 0
3128     };
3129 
3130     NUMTESTS++; /* increment NUMTESTS */
3131 
3132     /* DSA key init */
3133     dsaParamGenMech.mechanism = CKM_DSA_PARAMETER_GEN;
3134     dsaParamGenMech.pParameter = NULL_PTR;
3135     dsaParamGenMech.ulParameterLen = 0;
3136     dsaParamGenTemplate[0].type = CKA_PRIME_BITS;
3137     dsaParamGenTemplate[0].pValue = &primeBits;
3138     dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits);
3139     dsaPubKeyTemplate[0].type = CKA_PRIME;
3140     dsaPubKeyTemplate[0].pValue = DSA_P;
3141     dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P);
3142     dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
3143     dsaPubKeyTemplate[1].pValue = DSA_Q;
3144     dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q);
3145     dsaPubKeyTemplate[2].type = CKA_BASE;
3146     dsaPubKeyTemplate[2].pValue = DSA_G;
3147     dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G);
3148     dsaPubKeyTemplate[3].type = CKA_TOKEN;
3149     dsaPubKeyTemplate[3].pValue = &true;
3150     dsaPubKeyTemplate[3].ulValueLen = sizeof(true);
3151     dsaPubKeyTemplate[4].type = CKA_VERIFY;
3152     dsaPubKeyTemplate[4].pValue = &true;
3153     dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
3154     dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN;
3155     dsaKeyPairGenMech.pParameter = NULL_PTR;
3156     dsaKeyPairGenMech.ulParameterLen = 0;
3157     dsaPrivKeyTemplate[0].type = CKA_TOKEN;
3158     dsaPrivKeyTemplate[0].pValue = &true;
3159     dsaPrivKeyTemplate[0].ulValueLen = sizeof(true);
3160     dsaPrivKeyTemplate[1].type = CKA_PRIVATE;
3161     dsaPrivKeyTemplate[1].pValue = &true;
3162     dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
3163     dsaPrivKeyTemplate[2].type = CKA_SENSITIVE;
3164     dsaPrivKeyTemplate[2].pValue = &true;
3165     dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
3166     dsaPrivKeyTemplate[3].type = CKA_SIGN,
3167     dsaPrivKeyTemplate[3].pValue = &true;
3168     dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
3169     dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE;
3170     dsaPrivKeyTemplate[4].pValue = &true;
3171     dsaPrivKeyTemplate[4].ulValueLen = sizeof(true);
3172 
3173     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
3174                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
3175                                        NULL, NULL, &hSession);
3176     if (crv != CKR_OK) {
3177         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
3178                   PKM_CK_RVtoStr(crv));
3179         return crv;
3180     }
3181 
3182     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
3183     if (crv == CKR_OK) {
3184         PKM_LogIt("C_Login with correct password succeeded\n");
3185     } else {
3186         PKM_Error("C_Login with correct password failed "
3187                   "with 0x%08X, %-26s\n",
3188                   crv, PKM_CK_RVtoStr(crv));
3189         return crv;
3190     }
3191 
3192     PKM_LogIt("Generate DSA PQG domain parameters ... \n");
3193     /* Generate DSA domain parameters PQG */
3194     crv = pFunctionList->C_GenerateKey(hSession, &dsaParamGenMech,
3195                                        dsaParamGenTemplate,
3196                                        1,
3197                                        &hDsaParams);
3198     if (crv == CKR_OK) {
3199         PKM_LogIt("DSA domain parameter generation succeeded\n");
3200     } else {
3201         PKM_Error("DSA domain parameter generation failed "
3202                   "with 0x%08X, %-26s\n",
3203                   crv, PKM_CK_RVtoStr(crv));
3204         return crv;
3205     }
3206     crv = pFunctionList->C_GetAttributeValue(hSession, hDsaParams,
3207                                              dsaPubKeyTemplate, 3);
3208     if (crv == CKR_OK) {
3209         PKM_LogIt("Getting DSA domain parameters succeeded\n");
3210     } else {
3211         PKM_Error("Getting DSA domain parameters failed "
3212                   "with 0x%08X, %-26s\n",
3213                   crv, PKM_CK_RVtoStr(crv));
3214         return crv;
3215     }
3216     crv = pFunctionList->C_DestroyObject(hSession, hDsaParams);
3217     if (crv == CKR_OK) {
3218         PKM_LogIt("Destroying DSA domain parameters succeeded\n");
3219     } else {
3220         PKM_Error("Destroying DSA domain parameters failed "
3221                   "with 0x%08X, %-26s\n",
3222                   crv, PKM_CK_RVtoStr(crv));
3223         return crv;
3224     }
3225 
3226     PKM_LogIt("Generate a DSA key pair ... \n");
3227     /* Generate a persistent DSA key pair */
3228     crv = pFunctionList->C_GenerateKeyPair(hSession, &dsaKeyPairGenMech,
3229                                            dsaPubKeyTemplate,
3230                                            NUM_ELEM(dsaPubKeyTemplate),
3231                                            dsaPrivKeyTemplate,
3232                                            NUM_ELEM(dsaPrivKeyTemplate),
3233                                            &hDSApubKey, &hDSAprivKey);
3234     if (crv == CKR_OK) {
3235         PKM_LogIt("DSA key pair generation succeeded\n");
3236     } else {
3237         PKM_Error("DSA key pair generation failed "
3238                   "with 0x%08X, %-26s\n",
3239                   crv, PKM_CK_RVtoStr(crv));
3240         return crv;
3241     }
3242 
3243     /* Compute SHA-1 digest */
3244     crv = pFunctionList->C_DigestInit(hSession, &sha1Mech);
3245     if (crv != CKR_OK) {
3246         PKM_Error("C_DigestInit failed with 0x%08X, %-26s\n", crv,
3247                   PKM_CK_RVtoStr(crv));
3248         return crv;
3249     }
3250     sha1DigestLen = sizeof(sha1Digest);
3251     crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG),
3252                                   sha1Digest, &sha1DigestLen);
3253     if (crv != CKR_OK) {
3254         PKM_Error("C_Digest failed with 0x%08X, %-26s\n", crv,
3255                   PKM_CK_RVtoStr(crv));
3256         return crv;
3257     }
3258     if (sha1DigestLen != sizeof(sha1Digest)) {
3259         PKM_Error("sha1DigestLen is %lu\n", sha1DigestLen);
3260         return crv;
3261     }
3262 
3263     if (memcmp(sha1Digest, MD, sizeof(MD)) == 0) {
3264         PKM_LogIt("SHA-1 SHA1ShortMsg test case Len = 136 passed\n");
3265     } else {
3266         PKM_Error("SHA-1 SHA1ShortMsg test case Len = 136 failed\n");
3267     }
3268 
3269     crv = PKM_PubKeySign(pFunctionList, hSession,
3270                          hDSApubKey, hDSAprivKey,
3271                          &dsaMech, sha1Digest, sizeof(sha1Digest));
3272     if (crv == CKR_OK) {
3273         PKM_LogIt("PKM_PubKeySign CKM_DSA succeeded \n");
3274     } else {
3275         PKM_Error("PKM_PubKeySign failed "
3276                   "with 0x%08X, %-26s\n",
3277                   crv, PKM_CK_RVtoStr(crv));
3278         return crv;
3279     }
3280     crv = PKM_PubKeySign(pFunctionList, hSession,
3281                          hDSApubKey, hDSAprivKey,
3282                          &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT));
3283     if (crv == CKR_OK) {
3284         PKM_LogIt("PKM_PubKeySign CKM_DSA_SHA1 succeeded \n");
3285     } else {
3286         PKM_Error("PKM_PubKeySign failed "
3287                   "with 0x%08X, %-26s\n",
3288                   crv, PKM_CK_RVtoStr(crv));
3289         return crv;
3290     }
3291 
3292     /* Sign with DSA */
3293     crv = pFunctionList->C_SignInit(hSession, &dsaMech, hDSAprivKey);
3294     if (crv != CKR_OK) {
3295         PKM_Error("C_SignInit failed with 0x%08X, %-26s\n", crv,
3296                   PKM_CK_RVtoStr(crv));
3297         return crv;
3298     }
3299     dsaSigLen = sizeof(dsaSig);
3300     crv = pFunctionList->C_Sign(hSession, sha1Digest, sha1DigestLen,
3301                                 dsaSig, &dsaSigLen);
3302     if (crv != CKR_OK) {
3303         PKM_Error("C_Sign failed with 0x%08X, %-26s\n", crv,
3304                   PKM_CK_RVtoStr(crv));
3305         return crv;
3306     }
3307 
3308     /* Verify the DSA signature */
3309     crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey);
3310     if (crv != CKR_OK) {
3311         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
3312                   PKM_CK_RVtoStr(crv));
3313         return crv;
3314     }
3315     crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen,
3316                                   dsaSig, dsaSigLen);
3317     if (crv == CKR_OK) {
3318         PKM_LogIt("C_Verify succeeded\n");
3319     } else {
3320         PKM_Error("C_Verify failed with 0x%08X, %-26s\n", crv,
3321                   PKM_CK_RVtoStr(crv));
3322         return crv;
3323     }
3324 
3325     /* Verify the signature in a different way */
3326     crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech,
3327                                       hDSApubKey);
3328     if (crv != CKR_OK) {
3329         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
3330                   PKM_CK_RVtoStr(crv));
3331         return crv;
3332     }
3333     crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1);
3334     if (crv != CKR_OK) {
3335         PKM_Error("C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
3336                   PKM_CK_RVtoStr(crv));
3337         return crv;
3338     }
3339     crv = pFunctionList->C_VerifyUpdate(hSession, MSG + 1, sizeof(MSG) - 1);
3340     if (crv != CKR_OK) {
3341         PKM_Error("C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
3342                   PKM_CK_RVtoStr(crv));
3343         return crv;
3344     }
3345     crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen);
3346     if (crv == CKR_OK) {
3347         PKM_LogIt("C_VerifyFinal succeeded\n");
3348     } else {
3349         PKM_Error("C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
3350                   PKM_CK_RVtoStr(crv));
3351         return crv;
3352     }
3353 
3354     /* Verify the signature in a different way */
3355     crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech,
3356                                       hDSApubKey);
3357     if (crv != CKR_OK) {
3358         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n",
3359                   crv, PKM_CK_RVtoStr(crv));
3360         return crv;
3361     }
3362     crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1);
3363     if (crv != CKR_OK) {
3364         PKM_Error("C_VerifyUpdate failed with 0x%08X, %-26s\n",
3365                   crv, PKM_CK_RVtoStr(crv));
3366         return crv;
3367     }
3368     crv = pFunctionList->C_VerifyUpdate(hSession, MSG + 1, sizeof(MSG) - 1);
3369     if (crv != CKR_OK) {
3370         PKM_Error("C_VerifyUpdate failed with 0x%08X, %-26s\n",
3371                   crv, PKM_CK_RVtoStr(crv));
3372         return crv;
3373     }
3374     crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen);
3375     if (crv == CKR_OK) {
3376         PKM_LogIt("C_VerifyFinal of multi update succeeded.\n");
3377     } else {
3378         PKM_Error("C_VerifyFinal of multi update failed with 0x%08X, %-26s\n",
3379                   crv, PKM_CK_RVtoStr(crv));
3380         return crv;
3381     }
3382     /* Now modify the data */
3383     MSG[0] += 1;
3384     /* Compute SHA-1 digest */
3385     crv = pFunctionList->C_DigestInit(hSession, &sha1Mech);
3386     if (crv != CKR_OK) {
3387         PKM_Error("C_DigestInit failed with 0x%08X, %-26s\n", crv,
3388                   PKM_CK_RVtoStr(crv));
3389         return crv;
3390     }
3391     sha1DigestLen = sizeof(sha1Digest);
3392     crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG),
3393                                   sha1Digest, &sha1DigestLen);
3394     if (crv != CKR_OK) {
3395         PKM_Error("C_Digest failed with 0x%08X, %-26s\n", crv,
3396                   PKM_CK_RVtoStr(crv));
3397         return crv;
3398     }
3399     crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey);
3400     if (crv != CKR_OK) {
3401         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
3402                   PKM_CK_RVtoStr(crv));
3403         return crv;
3404     }
3405     crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen,
3406                                   dsaSig, dsaSigLen);
3407     if (crv != CKR_SIGNATURE_INVALID) {
3408         PKM_Error("C_Verify of modified data succeeded\n");
3409         return crv;
3410     } else {
3411         PKM_LogIt("C_Verify of modified data returned as EXPECTED "
3412                   " with 0x%08X, %-26s\n",
3413                   crv, PKM_CK_RVtoStr(crv));
3414     }
3415 
3416     crv = pFunctionList->C_Logout(hSession);
3417     if (crv == CKR_OK) {
3418         PKM_LogIt("C_Logout succeeded\n");
3419     } else {
3420         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
3421                   PKM_CK_RVtoStr(crv));
3422         return crv;
3423     }
3424 
3425     crv = pFunctionList->C_CloseSession(hSession);
3426     if (crv != CKR_OK) {
3427         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
3428                   PKM_CK_RVtoStr(crv));
3429         return crv;
3430     }
3431 
3432     return crv;
3433 }
3434 
3435 CK_RV
PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE sKey,CK_MECHANISM * hmacMech,const CK_BYTE * pData,CK_ULONG pDataLen)3436 PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
3437          CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech,
3438          const CK_BYTE *pData, CK_ULONG pDataLen)
3439 {
3440 
3441     CK_RV crv = CKR_OK;
3442 
3443     CK_BYTE hmac1[HMAC_MAX_LENGTH];
3444     CK_ULONG hmac1Len = 0;
3445     CK_BYTE hmac2[HMAC_MAX_LENGTH];
3446     CK_ULONG hmac2Len = 0;
3447 
3448     memset(hmac1, 0, sizeof(hmac1));
3449     memset(hmac2, 0, sizeof(hmac2));
3450 
3451     NUMTESTS++; /* increment NUMTESTS */
3452 
3453     crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey);
3454     if (crv == CKR_OK) {
3455         PKM_LogIt("C_SignInit succeeded\n");
3456     } else {
3457         PKM_Error("C_SignInit failed with 0x%08X, %-26s\n", crv,
3458                   PKM_CK_RVtoStr(crv));
3459         return crv;
3460     }
3461 
3462     hmac1Len = sizeof(hmac1);
3463     crv = pFunctionList->C_Sign(hSession, (CK_BYTE *)pData,
3464                                 pDataLen,
3465                                 (CK_BYTE *)hmac1, &hmac1Len);
3466     if (crv == CKR_OK) {
3467         PKM_LogIt("C_Sign succeeded\n");
3468     } else {
3469         PKM_Error("C_Sign failed with 0x%08X, %-26s\n", crv,
3470                   PKM_CK_RVtoStr(crv));
3471         return crv;
3472     }
3473 
3474     crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey);
3475     if (crv == CKR_OK) {
3476         PKM_LogIt("C_SignInit succeeded\n");
3477     } else {
3478         PKM_Error("C_SignInit failed with 0x%08X, %-26s\n", crv,
3479                   PKM_CK_RVtoStr(crv));
3480         return crv;
3481     }
3482 
3483     crv = pFunctionList->C_SignUpdate(hSession, (CK_BYTE *)pData,
3484                                       pDataLen);
3485     if (crv == CKR_OK) {
3486         PKM_LogIt("C_SignUpdate succeeded\n");
3487     } else {
3488         PKM_Error("C_SignUpdate failed with 0x%08X, %-26s\n", crv,
3489                   PKM_CK_RVtoStr(crv));
3490         return crv;
3491     }
3492 
3493     hmac2Len = sizeof(hmac2);
3494     crv = pFunctionList->C_SignFinal(hSession, (CK_BYTE *)hmac2, &hmac2Len);
3495     if (crv == CKR_OK) {
3496         PKM_LogIt("C_SignFinal succeeded\n");
3497     } else {
3498         PKM_Error("C_SignFinal failed with 0x%08X, %-26s\n", crv,
3499                   PKM_CK_RVtoStr(crv));
3500         return crv;
3501     }
3502 
3503     if ((hmac1Len == hmac2Len) && (memcmp(hmac1, hmac2, hmac1Len) == 0)) {
3504         PKM_LogIt("hmacs are equal!\n");
3505     } else {
3506         PKM_Error("hmacs are not equal!\n");
3507     }
3508     crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey);
3509     if (crv != CKR_OK) {
3510         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
3511                   PKM_CK_RVtoStr(crv));
3512         return crv;
3513     }
3514     crv = pFunctionList->C_Verify(hSession, (CK_BYTE *)pData,
3515                                   pDataLen,
3516                                   (CK_BYTE *)hmac2, hmac2Len);
3517     if (crv == CKR_OK) {
3518         PKM_LogIt("C_Verify of hmac succeeded\n");
3519     } else {
3520         PKM_Error("C_Verify failed with 0x%08X, %-26s\n", crv,
3521                   PKM_CK_RVtoStr(crv));
3522         return crv;
3523     }
3524     crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey);
3525     if (crv != CKR_OK) {
3526         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
3527                   PKM_CK_RVtoStr(crv));
3528         return crv;
3529     }
3530     crv = pFunctionList->C_VerifyUpdate(hSession, (CK_BYTE *)pData,
3531                                         pDataLen);
3532     if (crv == CKR_OK) {
3533         PKM_LogIt("C_VerifyUpdate of hmac succeeded\n");
3534     } else {
3535         PKM_Error("C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
3536                   PKM_CK_RVtoStr(crv));
3537         return crv;
3538     }
3539     crv = pFunctionList->C_VerifyFinal(hSession, (CK_BYTE *)hmac1,
3540                                        hmac1Len);
3541     if (crv == CKR_OK) {
3542         PKM_LogIt("C_VerifyFinal of hmac succeeded\n");
3543     } else {
3544         PKM_Error("C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
3545                   PKM_CK_RVtoStr(crv));
3546         return crv;
3547     }
3548     return crv;
3549 }
3550 
3551 CK_RV
PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)3552 PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,
3553                    CK_SLOT_ID *pSlotList, CK_ULONG slotID,
3554                    CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
3555 {
3556     CK_RV crv = CKR_OK;
3557 
3558     CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
3559     CK_SESSION_INFO sinfo;
3560     CK_ATTRIBUTE_PTR pTemplate;
3561     CK_ULONG tnObjects = 0;
3562     int curMode;
3563     unsigned int i;
3564     unsigned int number_of_all_known_attribute_types = totalKnownType(ConstAttribute);
3565 
3566     NUMTESTS++; /* increment NUMTESTS */
3567 
3568     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
3569                                        NULL, NULL, &h);
3570     if (CKR_OK != crv) {
3571         PKM_Error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
3572                   "returned 0x%08X, %-26s\n",
3573                   pSlotList[slotID], crv,
3574                   PKM_CK_RVtoStr(crv));
3575         return crv;
3576     }
3577 
3578     PKM_LogIt("    Opened a session: handle = 0x%08x\n", h);
3579 
3580     (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO));
3581     crv = pFunctionList->C_GetSessionInfo(h, &sinfo);
3582     if (CKR_OK != crv) {
3583         PKM_LogIt("C_GetSessionInfo(%lu, ) returned 0x%08X, %-26s\n", h, crv,
3584                   PKM_CK_RVtoStr(crv));
3585         return crv;
3586     }
3587 
3588     PKM_LogIt("    SESSION INFO:\n");
3589     PKM_LogIt("        slotID = %lu\n", sinfo.slotID);
3590     PKM_LogIt("        state = %lu\n", sinfo.state);
3591     PKM_LogIt("        flags = 0x%08x\n", sinfo.flags);
3592 #ifdef CKF_EXCLUSIVE_SESSION
3593     PKM_LogIt("            -> EXCLUSIVE SESSION = %s\n", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE");
3594 #endif /* CKF_EXCLUSIVE_SESSION */
3595     PKM_LogIt("            -> RW SESSION = %s\n", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE");
3596     PKM_LogIt("            -> SERIAL SESSION = %s\n", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE");
3597 #ifdef CKF_INSERTION_CALLBACK
3598     PKM_LogIt("            -> INSERTION CALLBACK = %s\n", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE");
3599 #endif /* CKF_INSERTION_CALLBACK */
3600     PKM_LogIt("        ulDeviceError = %lu\n", sinfo.ulDeviceError);
3601     PKM_LogIt("\n");
3602 
3603     crv = pFunctionList->C_FindObjectsInit(h, NULL, 0);
3604     if (CKR_OK != crv) {
3605         PKM_LogIt("C_FindObjectsInit(%lu, NULL, 0) returned "
3606                   "0x%08X, %-26s\n",
3607                   h, crv, PKM_CK_RVtoStr(crv));
3608         return crv;
3609     }
3610 
3611     pTemplate = (CK_ATTRIBUTE_PTR)calloc(number_of_all_known_attribute_types,
3612                                          sizeof(CK_ATTRIBUTE));
3613     if ((CK_ATTRIBUTE_PTR)NULL == pTemplate) {
3614         PKM_Error("[pTemplate memory allocation of %lu bytes failed]\n",
3615                   number_of_all_known_attribute_types *
3616                       sizeof(CK_ATTRIBUTE));
3617         return crv;
3618     }
3619 
3620     PKM_LogIt("    All objects:\n");
3621     /* Printing table set to NOMODE */
3622     curMode = MODE;
3623     MODE = NOMODE;
3624 
3625     while (1) {
3626         CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
3627         CK_ULONG nObjects = 0;
3628         CK_ULONG k;
3629         CK_ULONG nAttributes = 0;
3630         CK_ATTRIBUTE_PTR pT2;
3631         CK_ULONG l;
3632         const char *attName = NULL;
3633 
3634         crv = pFunctionList->C_FindObjects(h, &o, 1, &nObjects);
3635         if (CKR_OK != crv) {
3636             PKM_Error("C_FindObjects(%lu, , 1, ) returned 0x%08X, %-26s\n",
3637                       h, crv, PKM_CK_RVtoStr(crv));
3638             return crv;
3639         }
3640 
3641         if (0 == nObjects) {
3642             PKM_LogIt("\n");
3643             break;
3644         }
3645 
3646         tnObjects++;
3647 
3648         PKM_LogIt("        OBJECT HANDLE %lu:\n", o);
3649 
3650         k = 0;
3651         for (i = 0; i < constCount; i++) {
3652             if (consts[i].type == ConstAttribute) {
3653                 pTemplate[k].type = consts[i].value;
3654                 pTemplate[k].pValue = (CK_VOID_PTR)NULL;
3655                 pTemplate[k].ulValueLen = 0;
3656                 k++;
3657             }
3658             assert(k <= number_of_all_known_attribute_types);
3659         }
3660 
3661         crv = pFunctionList->C_GetAttributeValue(h, o, pTemplate,
3662                                                  number_of_all_known_attribute_types);
3663         switch (crv) {
3664             case CKR_OK:
3665             case CKR_ATTRIBUTE_SENSITIVE:
3666             case CKR_ATTRIBUTE_TYPE_INVALID:
3667             case CKR_BUFFER_TOO_SMALL:
3668                 break;
3669             default:
3670                 PKM_Error("C_GetAtributeValue(%lu, %lu, {all attribute types},"
3671                           "%lu) returned 0x%08X, %-26s\n",
3672                           h, o, number_of_all_known_attribute_types, crv,
3673                           PKM_CK_RVtoStr(crv));
3674                 return crv;
3675         }
3676 
3677         for (k = 0; k < (CK_ULONG)number_of_all_known_attribute_types; k++) {
3678             if (-1 != (CK_LONG)pTemplate[k].ulValueLen) {
3679                 nAttributes++;
3680             }
3681         }
3682 
3683         PKM_LogIt("            %lu attributes:\n", nAttributes);
3684         for (k = 0; k < (CK_ULONG)number_of_all_known_attribute_types;
3685              k++) {
3686             if (-1 != (CK_LONG)pTemplate[k].ulValueLen) {
3687                 attName = getNameFromAttribute(pTemplate[k].type);
3688                 if (!attName) {
3689                     PKM_Error("Unable to find attribute name update pk11table.c\n");
3690                 }
3691                 PKM_LogIt("                %s 0x%08x (len = %lu)\n",
3692                           attName,
3693                           pTemplate[k].type,
3694                           pTemplate[k].ulValueLen);
3695             }
3696         }
3697         PKM_LogIt("\n");
3698 
3699         pT2 = (CK_ATTRIBUTE_PTR)calloc(nAttributes, sizeof(CK_ATTRIBUTE));
3700         if ((CK_ATTRIBUTE_PTR)NULL == pT2) {
3701             PKM_Error("[pT2 memory allocation of %lu bytes failed]\n",
3702                       nAttributes * sizeof(CK_ATTRIBUTE));
3703             return crv;
3704         }
3705 
3706         /* allocate memory for the attribute values */
3707         for (l = 0, k = 0; k < (CK_ULONG)number_of_all_known_attribute_types;
3708              k++) {
3709             if (-1 != (CK_LONG)pTemplate[k].ulValueLen) {
3710                 pT2[l].type = pTemplate[k].type;
3711                 pT2[l].ulValueLen = pTemplate[k].ulValueLen;
3712                 if (pT2[l].ulValueLen > 0) {
3713                     pT2[l].pValue = (CK_VOID_PTR)malloc(pT2[l].ulValueLen);
3714                     if ((CK_VOID_PTR)NULL == pT2[l].pValue) {
3715                         PKM_Error("pValue memory allocation of %lu bytes failed]\n",
3716                                   pT2[l].ulValueLen);
3717                         return crv;
3718                     }
3719                 } else
3720                     pT2[l].pValue = (CK_VOID_PTR)NULL;
3721                 l++;
3722             }
3723         }
3724 
3725         assert(l == nAttributes);
3726 
3727         crv = pFunctionList->C_GetAttributeValue(h, o, pT2, nAttributes);
3728         switch (crv) {
3729             case CKR_OK:
3730             case CKR_ATTRIBUTE_SENSITIVE:
3731             case CKR_ATTRIBUTE_TYPE_INVALID:
3732             case CKR_BUFFER_TOO_SMALL:
3733                 break;
3734             default:
3735                 PKM_Error("C_GetAtributeValue(%lu, %lu, {existent attribute"
3736                           " types}, %lu) returned 0x%08X, %-26s\n",
3737                           h, o, nAttributes, crv, PKM_CK_RVtoStr(crv));
3738                 return crv;
3739         }
3740 
3741         for (l = 0; l < nAttributes; l++) {
3742             attName = getNameFromAttribute(pT2[l].type);
3743             if (!attName)
3744                 attName = "unknown attribute";
3745             PKM_LogIt("            type = %s len = %ld",
3746                       attName, (CK_LONG)pT2[l].ulValueLen);
3747 
3748             if (-1 == (CK_LONG)pT2[l].ulValueLen) {
3749                 ;
3750             } else {
3751                 CK_ULONG m;
3752 
3753                 if (pT2[l].ulValueLen <= 8) {
3754                     PKM_LogIt(", value = ");
3755                 } else {
3756                     PKM_LogIt(", value = \n                ");
3757                 }
3758 
3759                 for (m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++) {
3760                     PKM_LogIt("%02x", (CK_ULONG)(0xff &
3761                                                  ((CK_CHAR_PTR)pT2[l].pValue)[m]));
3762                 }
3763 
3764                 PKM_LogIt(" ");
3765 
3766                 for (m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++) {
3767                     CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m];
3768                     if ((c < 0x20) || (c >= 0x7f)) {
3769                         c = '.';
3770                     }
3771                     PKM_LogIt("%c", c);
3772                 }
3773             }
3774 
3775             PKM_LogIt("\n");
3776         }
3777 
3778         PKM_LogIt("\n");
3779 
3780         for (l = 0; l < nAttributes; l++) {
3781             if (pT2[l].pValue) {
3782                 free(pT2[l].pValue);
3783             }
3784         }
3785         free(pT2);
3786     } /* while(1) */
3787 
3788     MODE = curMode; /* reset the logging MODE */
3789 
3790     crv = pFunctionList->C_FindObjectsFinal(h);
3791     if (CKR_OK != crv) {
3792         PKM_Error("C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h, crv,
3793                   PKM_CK_RVtoStr(crv));
3794         return crv;
3795     }
3796 
3797     PKM_LogIt("    (%lu objects total)\n", tnObjects);
3798 
3799     crv = pFunctionList->C_CloseSession(h);
3800     if (CKR_OK != crv) {
3801         PKM_Error("C_CloseSession(%lu) returned 0x%08X, %-26s\n", h, crv,
3802                   PKM_CK_RVtoStr(crv));
3803         return crv;
3804     }
3805 
3806     return crv;
3807 }
3808 /* session to create, find, and delete a couple session objects */
3809 CK_RV
PKM_MultiObjectManagement(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)3810 PKM_MultiObjectManagement(CK_FUNCTION_LIST_PTR pFunctionList,
3811                           CK_SLOT_ID *pSlotList, CK_ULONG slotID,
3812                           CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
3813 {
3814 
3815     CK_RV crv = CKR_OK;
3816 
3817     CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
3818     CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0;
3819     CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1];
3820     CK_OBJECT_CLASS cko_data = CKO_DATA;
3821     char *key = "TEST PROGRAM";
3822     CK_ULONG key_len = 0;
3823     CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0;
3824     CK_OBJECT_HANDLE hTwoIn = (CK_OBJECT_HANDLE)0;
3825     CK_OBJECT_HANDLE hThreeIn = (CK_OBJECT_HANDLE)0;
3826     CK_OBJECT_HANDLE hDeltaIn = (CK_OBJECT_HANDLE)0;
3827     CK_OBJECT_HANDLE found[10];
3828     CK_ULONG nFound;
3829     CK_ULONG hDeltaLen, hThreeLen = 0;
3830 
3831     CK_TOKEN_INFO tinfo;
3832 
3833     NUMTESTS++; /* increment NUMTESTS */
3834     key_len = sizeof(key);
3835     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
3836                                        CKF_SERIAL_SESSION, NULL, NULL, &h);
3837     if (CKR_OK != crv) {
3838         PKM_Error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
3839                   "returned 0x%08X, %-26s\n",
3840                   pSlotList[slotID], crv,
3841                   PKM_CK_RVtoStr(crv));
3842         return crv;
3843     }
3844     crv = pFunctionList->C_Login(h, CKU_USER, pwd, pwdLen);
3845     if (crv == CKR_OK) {
3846         PKM_LogIt("C_Login with correct password succeeded\n");
3847     } else {
3848         PKM_Error("C_Login with correct password failed "
3849                   "with 0x%08X, %-26s\n",
3850                   crv, PKM_CK_RVtoStr(crv));
3851         return crv;
3852     }
3853 
3854     (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
3855     crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tinfo);
3856     if (CKR_OK != crv) {
3857         PKM_Error("C_GetTokenInfo(%lu, ) returned 0x%08X, %-26s\n",
3858                   pSlotList[slotID], crv, PKM_CK_RVtoStr(crv));
3859         return crv;
3860     }
3861 
3862     PKM_LogIt("    Opened a session: handle = 0x%08x\n", h);
3863 
3864     one[0].type = CKA_CLASS;
3865     one[0].pValue = &cko_data;
3866     one[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
3867     one[1].type = CKA_TOKEN;
3868     one[1].pValue = &false;
3869     one[1].ulValueLen = sizeof(CK_BBOOL);
3870     one[2].type = CKA_PRIVATE;
3871     one[2].pValue = &false;
3872     one[2].ulValueLen = sizeof(CK_BBOOL);
3873     one[3].type = CKA_MODIFIABLE;
3874     one[3].pValue = &true;
3875     one[3].ulValueLen = sizeof(CK_BBOOL);
3876     one[4].type = CKA_LABEL;
3877     one[4].pValue = "Test data object one";
3878     one[4].ulValueLen = strlen(one[4].pValue);
3879     one[5].type = CKA_APPLICATION;
3880     one[5].pValue = key;
3881     one[5].ulValueLen = key_len;
3882     one[6].type = CKA_VALUE;
3883     one[6].pValue = "Object one";
3884     one[6].ulValueLen = strlen(one[6].pValue);
3885 
3886     two[0].type = CKA_CLASS;
3887     two[0].pValue = &cko_data;
3888     two[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
3889     two[1].type = CKA_TOKEN;
3890     two[1].pValue = &false;
3891     two[1].ulValueLen = sizeof(CK_BBOOL);
3892     two[2].type = CKA_PRIVATE;
3893     two[2].pValue = &false;
3894     two[2].ulValueLen = sizeof(CK_BBOOL);
3895     two[3].type = CKA_MODIFIABLE;
3896     two[3].pValue = &true;
3897     two[3].ulValueLen = sizeof(CK_BBOOL);
3898     two[4].type = CKA_LABEL;
3899     two[4].pValue = "Test data object two";
3900     two[4].ulValueLen = strlen(two[4].pValue);
3901     two[5].type = CKA_APPLICATION;
3902     two[5].pValue = key;
3903     two[5].ulValueLen = key_len;
3904     two[6].type = CKA_VALUE;
3905     two[6].pValue = "Object two";
3906     two[6].ulValueLen = strlen(two[6].pValue);
3907 
3908     three[0].type = CKA_CLASS;
3909     three[0].pValue = &cko_data;
3910     three[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
3911     three[1].type = CKA_TOKEN;
3912     three[1].pValue = &false;
3913     three[1].ulValueLen = sizeof(CK_BBOOL);
3914     three[2].type = CKA_PRIVATE;
3915     three[2].pValue = &false;
3916     three[2].ulValueLen = sizeof(CK_BBOOL);
3917     three[3].type = CKA_MODIFIABLE;
3918     three[3].pValue = &true;
3919     three[3].ulValueLen = sizeof(CK_BBOOL);
3920     three[4].type = CKA_LABEL;
3921     three[4].pValue = "Test data object three";
3922     three[4].ulValueLen = strlen(three[4].pValue);
3923     three[5].type = CKA_APPLICATION;
3924     three[5].pValue = key;
3925     three[5].ulValueLen = key_len;
3926     three[6].type = CKA_VALUE;
3927     three[6].pValue = "Object three";
3928     three[6].ulValueLen = strlen(three[6].pValue);
3929 
3930     crv = pFunctionList->C_CreateObject(h, one, 7, &hOneIn);
3931     if (CKR_OK != crv) {
3932         PKM_Error("C_CreateObject(%lu, one, 7, ) returned 0x%08X, %-26s\n",
3933                   h, crv, PKM_CK_RVtoStr(crv));
3934         return crv;
3935     }
3936 
3937     PKM_LogIt("    Created object one: handle = %lu\n", hOneIn);
3938 
3939     crv = pFunctionList->C_CreateObject(h, two, 7, &hTwoIn);
3940     if (CKR_OK != crv) {
3941         PKM_Error("C_CreateObject(%lu, two, 7, ) returned 0x%08X, %-26s\n",
3942                   h, crv, PKM_CK_RVtoStr(crv));
3943         return crv;
3944     }
3945 
3946     PKM_LogIt("    Created object two: handle = %lu\n", hTwoIn);
3947 
3948     crv = pFunctionList->C_CreateObject(h, three, 7, &hThreeIn);
3949     if (CKR_OK != crv) {
3950         PKM_Error("C_CreateObject(%lu, three, 7, ) returned 0x%08x\n",
3951                   h, crv, PKM_CK_RVtoStr(crv));
3952         return crv;
3953     }
3954     crv = pFunctionList->C_GetObjectSize(h, hThreeIn, &hThreeLen);
3955     if (crv == CKR_OK) {
3956         PKM_LogIt("C_GetObjectSize succeeded\n");
3957     } else {
3958         PKM_Error("C_GetObjectSize failed "
3959                   "with 0x%08X, %-26s\n",
3960                   crv, PKM_CK_RVtoStr(crv));
3961         return crv;
3962     }
3963 
3964     PKM_LogIt("    Created object three: handle = %lu\n", hThreeIn);
3965 
3966     delta[0].type = CKA_VALUE;
3967     delta[0].pValue = "Copied object";
3968     delta[0].ulValueLen = strlen(delta[0].pValue);
3969 
3970     crv = pFunctionList->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn);
3971     if (CKR_OK != crv) {
3972         PKM_Error("C_CopyObject(%lu, %lu, delta, 1, ) returned "
3973                   "0x%08X, %-26s\n",
3974                   h, hThreeIn, crv, PKM_CK_RVtoStr(crv));
3975         return crv;
3976     }
3977     crv = pFunctionList->C_GetObjectSize(h, hDeltaIn, &hDeltaLen);
3978     if (crv == CKR_OK) {
3979         PKM_LogIt("C_GetObjectSize succeeded\n");
3980     } else {
3981         PKM_Error("C_GetObjectSize failed "
3982                   "with 0x%08X, %-26s\n",
3983                   crv, PKM_CK_RVtoStr(crv));
3984         return crv;
3985     }
3986 
3987     if (hThreeLen == hDeltaLen) {
3988         PKM_LogIt("Copied object size same as orginal\n");
3989     } else {
3990         PKM_Error("Copied object different from original\n");
3991         return CKR_DEVICE_ERROR;
3992     }
3993 
3994     PKM_LogIt("    Copied object three: new handle = %lu\n", hDeltaIn);
3995 
3996     mask[0].type = CKA_APPLICATION;
3997     mask[0].pValue = key;
3998     mask[0].ulValueLen = key_len;
3999 
4000     crv = pFunctionList->C_FindObjectsInit(h, mask, 1);
4001     if (CKR_OK != crv) {
4002         PKM_Error("C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n",
4003                   h, crv, PKM_CK_RVtoStr(crv));
4004         return crv;
4005     }
4006 
4007     (void)memset(&found, 0, sizeof(found));
4008     nFound = 0;
4009     crv = pFunctionList->C_FindObjects(h, found, 10, &nFound);
4010     if (CKR_OK != crv) {
4011         PKM_Error("C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n",
4012                   h, crv, PKM_CK_RVtoStr(crv));
4013         return crv;
4014     }
4015 
4016     if (4 != nFound) {
4017         PKM_Error("Found %lu objects, not 4.\n", nFound);
4018         return crv;
4019     }
4020 
4021     PKM_LogIt("    Found 4 objects: %lu, %lu, %lu, %lu\n",
4022               found[0], found[1], found[2], found[3]);
4023 
4024     crv = pFunctionList->C_FindObjectsFinal(h);
4025     if (CKR_OK != crv) {
4026         PKM_Error("C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n",
4027                   h, crv, PKM_CK_RVtoStr(crv));
4028         return crv;
4029     }
4030 
4031     crv = pFunctionList->C_DestroyObject(h, hThreeIn);
4032     if (CKR_OK != crv) {
4033         PKM_Error("C_DestroyObject(%lu, %lu) returned 0x%08X, %-26s\n", h,
4034                   hThreeIn, crv, PKM_CK_RVtoStr(crv));
4035         return crv;
4036     }
4037 
4038     PKM_LogIt("    Destroyed object three (handle = %lu)\n", hThreeIn);
4039 
4040     delta[0].type = CKA_APPLICATION;
4041     delta[0].pValue = "Changed application";
4042     delta[0].ulValueLen = strlen(delta[0].pValue);
4043 
4044     crv = pFunctionList->C_SetAttributeValue(h, hTwoIn, delta, 1);
4045     if (CKR_OK != crv) {
4046         PKM_Error("C_SetAttributeValue(%lu, %lu, delta, 1) returned "
4047                   "0x%08X, %-26s\n",
4048                   h, hTwoIn, crv, PKM_CK_RVtoStr(crv));
4049         return crv;
4050     }
4051 
4052     PKM_LogIt("    Changed object two (handle = %lu).\n", hTwoIn);
4053 
4054     /* Can another session find these session objects? */
4055 
4056     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
4057                                        NULL, NULL, &h2);
4058     if (CKR_OK != crv) {
4059         PKM_Error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
4060                   " returned 0x%08X, %-26s\n",
4061                   pSlotList[slotID], crv,
4062                   PKM_CK_RVtoStr(crv));
4063         return crv;
4064     }
4065     PKM_LogIt("    Opened a second session: handle = 0x%08x\n", h2);
4066 
4067     /* mask is still the same */
4068 
4069     crv = pFunctionList->C_FindObjectsInit(h2, mask, 1);
4070     if (CKR_OK != crv) {
4071         PKM_Error("C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n",
4072                   h2, crv, PKM_CK_RVtoStr(crv));
4073         return crv;
4074     }
4075 
4076     (void)memset(&found, 0, sizeof(found));
4077     nFound = 0;
4078     crv = pFunctionList->C_FindObjects(h2, found, 10, &nFound);
4079     if (CKR_OK != crv) {
4080         PKM_Error("C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n",
4081                   h2, crv, PKM_CK_RVtoStr(crv));
4082         return crv;
4083     }
4084 
4085     if (2 != nFound) {
4086         PKM_Error("Found %lu objects, not 2.\n", nFound);
4087         return crv;
4088     }
4089 
4090     PKM_LogIt("    Found 2 objects: %lu, %lu\n",
4091               found[0], found[1]);
4092 
4093     crv = pFunctionList->C_FindObjectsFinal(h2);
4094     if (CKR_OK != crv) {
4095         PKM_Error("C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h2, crv,
4096                   PKM_CK_RVtoStr(crv));
4097         return crv;
4098     }
4099     crv = pFunctionList->C_Logout(h);
4100     if (crv == CKR_OK) {
4101         PKM_LogIt("C_Logout succeeded\n");
4102     } else {
4103         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
4104                   PKM_CK_RVtoStr(crv));
4105         return crv;
4106     }
4107     crv = pFunctionList->C_CloseAllSessions(pSlotList[slotID]);
4108     if (CKR_OK != crv) {
4109         PKM_Error("C_CloseAllSessions(%lu) returned 0x%08X, %-26s\n",
4110                   pSlotList[slotID], crv, PKM_CK_RVtoStr(crv));
4111         return crv;
4112     }
4113 
4114     PKM_LogIt("\n");
4115     return crv;
4116 }
4117 
4118 CK_RV
PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen)4119 PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,
4120                      CK_SLOT_ID *pSlotList, CK_ULONG slotID,
4121                      CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
4122 {
4123     CK_SESSION_HANDLE hSession;
4124     CK_RV crv = CKR_OK;
4125     CK_MECHANISM sAESKeyMech = {
4126         CKM_AES_KEY_GEN, NULL, 0
4127     };
4128     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
4129     CK_KEY_TYPE keyAESType = CKK_AES;
4130     CK_UTF8CHAR AESlabel[] = "An AES secret key object";
4131     CK_ULONG AESvalueLen = 16;
4132     CK_ATTRIBUTE sAESKeyTemplate[9];
4133     CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE;
4134     CK_BYTE_PTR pstate = NULL;
4135     CK_ULONG statelen, digestlen, plainlen, plainlen_1, plainlen_2, slen;
4136 
4137     static const CK_UTF8CHAR *plaintext = (CK_UTF8CHAR *)"Firefox rules.";
4138     static const CK_UTF8CHAR *plaintext_1 = (CK_UTF8CHAR *)"Thunderbird rules.";
4139     static const CK_UTF8CHAR *plaintext_2 = (CK_UTF8CHAR *)"Firefox and Thunderbird.";
4140 
4141     char digest[MAX_DIGEST_SZ], digest_1[MAX_DIGEST_SZ];
4142     char sign[MAX_SIG_SZ];
4143     CK_MECHANISM signmech;
4144     CK_MECHANISM digestmech;
4145 
4146     NUMTESTS++; /* increment NUMTESTS */
4147 
4148     /* AES key template */
4149     sAESKeyTemplate[0].type = CKA_CLASS;
4150     sAESKeyTemplate[0].pValue = &class;
4151     sAESKeyTemplate[0].ulValueLen = sizeof(class);
4152     sAESKeyTemplate[1].type = CKA_KEY_TYPE;
4153     sAESKeyTemplate[1].pValue = &keyAESType;
4154     sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
4155     sAESKeyTemplate[2].type = CKA_LABEL;
4156     sAESKeyTemplate[2].pValue = AESlabel;
4157     sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel) - 1;
4158     sAESKeyTemplate[3].type = CKA_ENCRYPT;
4159     sAESKeyTemplate[3].pValue = &true;
4160     sAESKeyTemplate[3].ulValueLen = sizeof(true);
4161     sAESKeyTemplate[4].type = CKA_DECRYPT;
4162     sAESKeyTemplate[4].pValue = &true;
4163     sAESKeyTemplate[4].ulValueLen = sizeof(true);
4164     sAESKeyTemplate[5].type = CKA_SIGN;
4165     sAESKeyTemplate[5].pValue = &true;
4166     sAESKeyTemplate[5].ulValueLen = sizeof(true);
4167     sAESKeyTemplate[6].type = CKA_VERIFY;
4168     sAESKeyTemplate[6].pValue = &true;
4169     sAESKeyTemplate[6].ulValueLen = sizeof(true);
4170     sAESKeyTemplate[7].type = CKA_UNWRAP;
4171     sAESKeyTemplate[7].pValue = &true;
4172     sAESKeyTemplate[7].ulValueLen = sizeof(true);
4173     sAESKeyTemplate[8].type = CKA_VALUE_LEN;
4174     sAESKeyTemplate[8].pValue = &AESvalueLen;
4175     sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
4176 
4177     signmech.mechanism = CKM_SHA_1_HMAC;
4178     signmech.pParameter = NULL;
4179     signmech.ulParameterLen = 0;
4180     digestmech.mechanism = CKM_SHA256;
4181     digestmech.pParameter = NULL;
4182     digestmech.ulParameterLen = 0;
4183 
4184     plainlen = strlen((char *)plaintext);
4185     plainlen_1 = strlen((char *)plaintext_1);
4186     plainlen_2 = strlen((char *)plaintext_2);
4187     digestlen = MAX_DIGEST_SZ;
4188 
4189     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
4190                                        NULL, NULL, &hSession);
4191     if (crv != CKR_OK) {
4192         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
4193                   PKM_CK_RVtoStr(crv));
4194         return crv;
4195     }
4196 
4197     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
4198     if (crv == CKR_OK) {
4199         PKM_LogIt("C_Login with correct password succeeded\n");
4200     } else {
4201         PKM_Error("C_Login with correct password failed "
4202                   "with 0x%08X, %-26s\n",
4203                   crv, PKM_CK_RVtoStr(crv));
4204         return crv;
4205     }
4206 
4207     PKM_LogIt("Generate an AES key ...\n");
4208     /* generate an AES Secret Key */
4209     crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech,
4210                                        sAESKeyTemplate,
4211                                        NUM_ELEM(sAESKeyTemplate),
4212                                        &sKey);
4213     if (crv == CKR_OK) {
4214         PKM_LogIt("C_GenerateKey AES succeeded\n");
4215     } else {
4216         PKM_Error("C_GenerateKey AES failed with 0x%08X, %-26s\n",
4217                   crv, PKM_CK_RVtoStr(crv));
4218         return crv;
4219     }
4220 
4221     crv = pFunctionList->C_SignInit(hSession, &signmech, sKey);
4222     if (crv != CKR_OK) {
4223         PKM_Error("C_SignInit failed returned 0x%08X, %-26s\n", crv,
4224                   PKM_CK_RVtoStr(crv));
4225         return crv;
4226     }
4227 
4228     slen = sizeof(sign);
4229     crv = pFunctionList->C_Sign(hSession, (CK_BYTE_PTR)plaintext, plainlen,
4230                                 (CK_BYTE_PTR)sign, &slen);
4231     if (crv != CKR_OK) {
4232         PKM_Error("C_Sign failed returned 0x%08X, %-26s\n", crv,
4233                   PKM_CK_RVtoStr(crv));
4234         return crv;
4235     }
4236 
4237     crv = pFunctionList->C_DestroyObject(hSession, sKey);
4238     if (crv != CKR_OK) {
4239         PKM_Error("C_DestroyObject failed returned 0x%08X, %-26s\n", crv,
4240                   PKM_CK_RVtoStr(crv));
4241         return crv;
4242     }
4243 
4244     digestlen = MAX_DIGEST_SZ;
4245     crv = pFunctionList->C_DigestInit(hSession, &digestmech);
4246     if (crv != CKR_OK) {
4247         PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv,
4248                   PKM_CK_RVtoStr(crv));
4249         return crv;
4250     }
4251     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext,
4252                                         plainlen);
4253     if (crv != CKR_OK) {
4254         PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv,
4255                   PKM_CK_RVtoStr(crv));
4256         return crv;
4257     }
4258 
4259     crv = pFunctionList->C_GetOperationState(hSession, NULL, &statelen);
4260     if (crv != CKR_OK) {
4261         PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv,
4262                   PKM_CK_RVtoStr(crv));
4263         return crv;
4264     }
4265 
4266     pstate = (CK_BYTE_PTR)malloc(statelen * sizeof(CK_BYTE_PTR));
4267     crv = pFunctionList->C_GetOperationState(hSession, pstate, &statelen);
4268     if (crv != CKR_OK) {
4269         PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv,
4270                   PKM_CK_RVtoStr(crv));
4271         return crv;
4272     }
4273 
4274     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_1,
4275                                         plainlen_1);
4276     if (crv != CKR_OK) {
4277         PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv,
4278                   PKM_CK_RVtoStr(crv));
4279         return crv;
4280     }
4281     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_2,
4282                                         plainlen_2);
4283     if (crv != CKR_OK) {
4284         PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv,
4285                   PKM_CK_RVtoStr(crv));
4286         return crv;
4287     }
4288 
4289     /*
4290      *      This will override/negate the above 2 digest_update
4291      *      operations
4292      */
4293     crv = pFunctionList->C_SetOperationState(hSession, pstate, statelen,
4294                                              0, 0);
4295     if (crv != CKR_OK) {
4296         PKM_Error("C_SetOperationState failed returned 0x%08X, %-26s\n", crv,
4297                   PKM_CK_RVtoStr(crv));
4298         return crv;
4299     }
4300     crv = pFunctionList->C_DigestFinal(hSession, (CK_BYTE_PTR)digest,
4301                                        &digestlen);
4302     if (crv != CKR_OK) {
4303         PKM_Error("C_DigestFinal failed returned 0x%08X, %-26s\n", crv,
4304                   PKM_CK_RVtoStr(crv));
4305         return crv;
4306     }
4307     digestlen = MAX_DIGEST_SZ;
4308     crv = pFunctionList->C_DigestInit(hSession, &digestmech);
4309     if (crv != CKR_OK) {
4310         PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv,
4311                   PKM_CK_RVtoStr(crv));
4312         return crv;
4313     }
4314     crv = pFunctionList->C_Digest(hSession, (CK_BYTE_PTR)plaintext, plainlen,
4315                                   (CK_BYTE_PTR)digest_1, &digestlen);
4316     if (crv != CKR_OK) {
4317         PKM_Error("C_Digest failed returned 0x%08X, %-26s\n", crv,
4318                   PKM_CK_RVtoStr(crv));
4319         return crv;
4320     }
4321     if (memcmp(digest, digest_1, digestlen) == 0) {
4322         PKM_LogIt("Digest and digest_1 are equal!\n");
4323     } else {
4324         PKM_Error("Digest and digest_1 are not equal!\n");
4325     }
4326     crv = pFunctionList->C_Logout(hSession);
4327     if (crv == CKR_OK) {
4328         PKM_LogIt("C_Logout succeeded\n");
4329     } else {
4330         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
4331                   PKM_CK_RVtoStr(crv));
4332         return crv;
4333     }
4334     crv = pFunctionList->C_CloseSession(hSession);
4335     if (CKR_OK != crv) {
4336         PKM_Error("C_CloseSession(%lu) returned 0x%08X, %-26s\n",
4337                   hSession, crv, PKM_CK_RVtoStr(crv));
4338         return crv;
4339     }
4340 
4341     return crv;
4342 }
4343 
4344 /*
4345 * Recover Functions
4346 */
4347 CK_RV
PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hPubKey,CK_OBJECT_HANDLE hPrivKey,CK_MECHANISM * signMech,const CK_BYTE * pData,CK_ULONG pDataLen)4348 PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
4349                      CK_SESSION_HANDLE hSession,
4350                      CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
4351                      CK_MECHANISM *signMech, const CK_BYTE *pData,
4352                      CK_ULONG pDataLen)
4353 {
4354     CK_RV crv = CKR_OK;
4355     CK_BYTE sig[MAX_SIG_SZ];
4356     CK_ULONG sigLen = MAX_SIG_SZ;
4357     CK_BYTE recover[MAX_SIG_SZ];
4358     CK_ULONG recoverLen = MAX_SIG_SZ;
4359 
4360     NUMTESTS++; /* increment NUMTESTS */
4361 
4362     /* initializes a signature operation,
4363      *  where the data can be recovered from the signature
4364      */
4365     crv = pFunctionList->C_SignRecoverInit(hSession, signMech,
4366                                            hPrivKey);
4367     if (crv == CKR_OK) {
4368         PKM_LogIt("C_SignRecoverInit succeeded. \n");
4369     } else {
4370         PKM_Error("C_SignRecoverInit failed.\n"
4371                   "with 0x%08X, %-26s\n",
4372                   crv, PKM_CK_RVtoStr(crv));
4373         return crv;
4374     }
4375 
4376     /* signs single-part data,
4377      * where the data can be recovered from the signature
4378      */
4379     crv = pFunctionList->C_SignRecover(hSession, (CK_BYTE *)pData,
4380                                        pDataLen,
4381                                        (CK_BYTE *)sig, &sigLen);
4382     if (crv == CKR_OK) {
4383         PKM_LogIt("C_SignRecover succeeded. \n");
4384     } else {
4385         PKM_Error("C_SignRecoverInit failed to create an RSA key pair.\n"
4386                   "with 0x%08X, %-26s\n",
4387                   crv, PKM_CK_RVtoStr(crv));
4388         return crv;
4389     }
4390 
4391     /*
4392      * initializes a verification operation
4393      *where the data is recovered from the signature
4394      */
4395     crv = pFunctionList->C_VerifyRecoverInit(hSession, signMech,
4396                                              hPubKey);
4397     if (crv == CKR_OK) {
4398         PKM_LogIt("C_VerifyRecoverInit succeeded. \n");
4399     } else {
4400         PKM_Error("C_VerifyRecoverInit failed.\n"
4401                   "with 0x%08X, %-26s\n",
4402                   crv, PKM_CK_RVtoStr(crv));
4403         return crv;
4404     }
4405 
4406     /*
4407     * verifies a signature on single-part data,
4408     * where the data is recovered from the signature
4409     */
4410     crv = pFunctionList->C_VerifyRecover(hSession, (CK_BYTE *)sig,
4411                                          sigLen,
4412                                          (CK_BYTE *)recover, &recoverLen);
4413     if (crv == CKR_OK) {
4414         PKM_LogIt("C_VerifyRecover succeeded. \n");
4415     } else {
4416         PKM_Error("C_VerifyRecover failed.\n"
4417                   "with 0x%08X, %-26s\n",
4418                   crv, PKM_CK_RVtoStr(crv));
4419         return crv;
4420     }
4421 
4422     if ((recoverLen == pDataLen) &&
4423         (memcmp(recover, pData, pDataLen) == 0)) {
4424         PKM_LogIt("VerifyRecover test case passed\n");
4425     } else {
4426         PKM_Error("VerifyRecover test case failed\n");
4427     }
4428 
4429     return crv;
4430 }
4431 /*
4432 * wrapUnwrap
4433 * wrap the secretkey with the public key.
4434 * unwrap the secretkey with the private key.
4435 */
4436 CK_RV
PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hPublicKey,CK_OBJECT_HANDLE hPrivateKey,CK_MECHANISM * wrapMechanism,CK_OBJECT_HANDLE hSecretKey,CK_ATTRIBUTE * sKeyTemplate,CK_ULONG skeyTempSize)4437 PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,
4438                CK_SESSION_HANDLE hSession,
4439                CK_OBJECT_HANDLE hPublicKey,
4440                CK_OBJECT_HANDLE hPrivateKey,
4441                CK_MECHANISM *wrapMechanism,
4442                CK_OBJECT_HANDLE hSecretKey,
4443                CK_ATTRIBUTE *sKeyTemplate,
4444                CK_ULONG skeyTempSize)
4445 {
4446     CK_RV crv = CKR_OK;
4447     CK_OBJECT_HANDLE hSecretKeyUnwrapped = CK_INVALID_HANDLE;
4448     CK_BYTE wrappedKey[128];
4449     CK_ULONG ulWrappedKeyLen = 0;
4450 
4451     NUMTESTS++; /* increment NUMTESTS */
4452 
4453     ulWrappedKeyLen = sizeof(wrappedKey);
4454     crv = pFunctionList->C_WrapKey(
4455         hSession, wrapMechanism,
4456         hPublicKey, hSecretKey,
4457         wrappedKey, &ulWrappedKeyLen);
4458     if (crv == CKR_OK) {
4459         PKM_LogIt("C_WrapKey succeeded\n");
4460     } else {
4461         PKM_Error("C_WrapKey failed with 0x%08X, %-26s\n", crv,
4462                   PKM_CK_RVtoStr(crv));
4463         return crv;
4464     }
4465     crv = pFunctionList->C_UnwrapKey(
4466         hSession, wrapMechanism, hPrivateKey,
4467         wrappedKey, ulWrappedKeyLen, sKeyTemplate,
4468         skeyTempSize,
4469         &hSecretKeyUnwrapped);
4470     if ((crv == CKR_OK) && (hSecretKeyUnwrapped != CK_INVALID_HANDLE)) {
4471         PKM_LogIt("C_UnwrapKey succeeded\n");
4472     } else {
4473         PKM_Error("C_UnwrapKey failed with 0x%08X, %-26s\n", crv,
4474                   PKM_CK_RVtoStr(crv));
4475         return crv;
4476     }
4477 
4478     return crv;
4479 }
4480 
4481 /*
4482  * Tests if the object's attributes match the expected_attrs
4483  */
4484 CK_RV
PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_PTR expected_attrs,CK_ULONG expected_attrs_count)4485 PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,
4486                    CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj,
4487                    CK_ATTRIBUTE_PTR expected_attrs,
4488                    CK_ULONG expected_attrs_count)
4489 {
4490     CK_RV crv;
4491     CK_ATTRIBUTE_PTR tmp_attrs;
4492     unsigned int i;
4493 
4494     NUMTESTS++; /* increment NUMTESTS */
4495 
4496     /* First duplicate the themplate */
4497     tmp_attrs = malloc(expected_attrs_count * sizeof(CK_ATTRIBUTE));
4498 
4499     if (tmp_attrs == NULL) {
4500         PKM_Error("Internal test memory failure\n");
4501         return (CKR_HOST_MEMORY);
4502     }
4503 
4504     for (i = 0; i < expected_attrs_count; i++) {
4505         tmp_attrs[i].type = expected_attrs[i].type;
4506         tmp_attrs[i].ulValueLen = expected_attrs[i].ulValueLen;
4507 
4508         /* Don't give away the expected one. just zeros */
4509         tmp_attrs[i].pValue = calloc(expected_attrs[i].ulValueLen, 1);
4510 
4511         if (tmp_attrs[i].pValue == NULL) {
4512             unsigned int j;
4513             for (j = 0; j < i; j++)
4514                 free(tmp_attrs[j].pValue);
4515 
4516             free(tmp_attrs);
4517             printf("Internal test memory failure\n");
4518             return (CKR_HOST_MEMORY);
4519         }
4520     }
4521 
4522     /* then get the attributes from the object */
4523     crv = pFunctionList->C_GetAttributeValue(hSession, obj, tmp_attrs,
4524                                              expected_attrs_count);
4525     if (crv != CKR_OK) {
4526         PKM_Error("C_GetAttributeValue failed with 0x%08X, %-26s\n", crv,
4527                   PKM_CK_RVtoStr(crv));
4528         crv = CKR_FUNCTION_FAILED;
4529         goto out;
4530     }
4531 
4532     /* Finally compare with the expected ones */
4533     for (i = 0; i < expected_attrs_count; i++) {
4534 
4535         if (memcmp(tmp_attrs[i].pValue, expected_attrs[i].pValue,
4536                    expected_attrs[i].ulValueLen) != 0) {
4537             PKM_LogIt("comparing attribute type 0x%x with expected  0x%x\n",
4538                       tmp_attrs[i].type, expected_attrs[i].type);
4539             PKM_LogIt("comparing attribute type value 0x%x with expected 0x%x\n",
4540                       tmp_attrs[i].pValue, expected_attrs[i].pValue);
4541             /* don't report error at this time */
4542         }
4543     }
4544 
4545 out:
4546     for (i = 0; i < expected_attrs_count; i++)
4547         free(tmp_attrs[i].pValue);
4548     free(tmp_attrs);
4549     return (crv);
4550 }
4551 
4552 /*
4553  * Check the validity of a mech
4554  */
4555 CK_RV
PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_MECHANISM_TYPE mechType,CK_FLAGS flags,CK_BBOOL check_sizes,CK_ULONG minkeysize,CK_ULONG maxkeysize)4556 PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
4557               CK_MECHANISM_TYPE mechType, CK_FLAGS flags,
4558               CK_BBOOL check_sizes, CK_ULONG minkeysize, CK_ULONG maxkeysize)
4559 {
4560     CK_SESSION_INFO sess_info;
4561     CK_MECHANISM_INFO mech_info;
4562     CK_RV crv;
4563 
4564     NUMTESTS++; /* increment NUMTESTS */
4565 
4566     if ((crv = pFunctionList->C_GetSessionInfo(hSession, &sess_info)) !=
4567         CKR_OK) {
4568         PKM_Error("C_GetSessionInfo failed with 0x%08X, %-26s\n", crv,
4569                   PKM_CK_RVtoStr(crv));
4570         return (CKR_FUNCTION_FAILED);
4571     }
4572 
4573     crv = pFunctionList->C_GetMechanismInfo(0, mechType,
4574                                             &mech_info);
4575 
4576     crv = pFunctionList->C_GetMechanismInfo(sess_info.slotID, mechType,
4577                                             &mech_info);
4578 
4579     if (crv != CKR_OK) {
4580         PKM_Error("C_GetMechanismInfo failed with 0x%08X, %-26s\n", crv,
4581                   PKM_CK_RVtoStr(crv));
4582         return (CKR_FUNCTION_FAILED);
4583     }
4584 
4585     if ((mech_info.flags & flags) == 0) {
4586         PKM_Error("0x%x flag missing from mech\n", flags);
4587         return (CKR_MECHANISM_INVALID);
4588     }
4589     if (!check_sizes)
4590         return (CKR_OK);
4591 
4592     if (mech_info.ulMinKeySize != minkeysize) {
4593         PKM_Error("Bad MinKeySize %d expected %d\n", mech_info.ulMinKeySize,
4594                   minkeysize);
4595         return (CKR_MECHANISM_INVALID);
4596     }
4597     if (mech_info.ulMaxKeySize != maxkeysize) {
4598         PKM_Error("Bad MaxKeySize %d expected %d\n", mech_info.ulMaxKeySize,
4599                   maxkeysize);
4600         return (CKR_MECHANISM_INVALID);
4601     }
4602     return (CKR_OK);
4603 }
4604 
4605 /*
4606  * Can be called with a non-null premaster_key_len for the
4607  * *_DH mechanisms. In that case, no checking for the matching of
4608  * the expected results is done.
4609  * The rnd argument tells which correct/bogus randomInfo to use.
4610  */
4611 CK_RV
PKM_TLSMasterKeyDerive(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen,CK_MECHANISM_TYPE mechType,enum_random_t rnd)4612 PKM_TLSMasterKeyDerive(CK_FUNCTION_LIST_PTR pFunctionList,
4613                        CK_SLOT_ID *pSlotList, CK_ULONG slotID,
4614                        CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
4615                        CK_MECHANISM_TYPE mechType,
4616                        enum_random_t rnd)
4617 {
4618     CK_SESSION_HANDLE hSession;
4619     CK_RV crv;
4620     CK_MECHANISM mk_mech;
4621     CK_VERSION version;
4622     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
4623     CK_KEY_TYPE type = CKK_GENERIC_SECRET;
4624     CK_BBOOL derive_bool = true;
4625     CK_ATTRIBUTE attrs[4];
4626     CK_ULONG attrs_count = 4;
4627     CK_OBJECT_HANDLE pmk_obj = CK_INVALID_HANDLE;
4628     CK_OBJECT_HANDLE mk_obj = CK_INVALID_HANDLE;
4629     CK_SSL3_MASTER_KEY_DERIVE_PARAMS mkd_params;
4630     CK_MECHANISM skmd_mech;
4631 
4632     CK_BBOOL isDH = false;
4633 
4634     NUMTESTS++; /* increment NUMTESTS */
4635 
4636     attrs[0].type = CKA_CLASS;
4637     attrs[0].pValue = &class;
4638     attrs[0].ulValueLen = sizeof(class);
4639     attrs[1].type = CKA_KEY_TYPE;
4640     attrs[1].pValue = &type;
4641     attrs[1].ulValueLen = sizeof(type);
4642     attrs[2].type = CKA_DERIVE;
4643     attrs[2].pValue = &derive_bool;
4644     attrs[2].ulValueLen = sizeof(derive_bool);
4645     attrs[3].type = CKA_VALUE;
4646     attrs[3].pValue = NULL;
4647     attrs[3].ulValueLen = 0;
4648 
4649     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
4650                                        NULL, NULL, &hSession);
4651     if (crv != CKR_OK) {
4652         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
4653                   PKM_CK_RVtoStr(crv));
4654         return crv;
4655     }
4656     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
4657     if (crv == CKR_OK) {
4658         PKM_LogIt("C_Login with correct password succeeded\n");
4659     } else {
4660         PKM_Error("C_Login with correct password failed "
4661                   "with 0x%08X, %-26s\n",
4662                   crv, PKM_CK_RVtoStr(crv));
4663         return crv;
4664     }
4665 
4666     /* Before all, check if the mechanism is supported correctly */
4667     if (MODE == FIPSMODE) {
4668         crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE, false,
4669                             0, 0);
4670         if (crv != CKR_OK) {
4671             PKM_Error("PKM_MechCheck failed with 0x%08X, %-26s\n", crv,
4672                       PKM_CK_RVtoStr(crv));
4673             return (crv);
4674         }
4675     }
4676 
4677     mk_mech.mechanism = mechType;
4678     mk_mech.pParameter = &mkd_params;
4679     mk_mech.ulParameterLen = sizeof(mkd_params);
4680 
4681     switch (mechType) {
4682         case CKM_TLS_MASTER_KEY_DERIVE_DH:
4683             isDH = true;
4684         /* FALLTHRU */
4685         case CKM_TLS_MASTER_KEY_DERIVE:
4686             attrs[3].pValue = NULL;
4687             attrs[3].ulValueLen = 0;
4688 
4689             mkd_params.RandomInfo.pClientRandom = (unsigned char *)TLSClientRandom;
4690             mkd_params.RandomInfo.ulClientRandomLen =
4691                 sizeof(TLSClientRandom);
4692             mkd_params.RandomInfo.pServerRandom = (unsigned char *)TLSServerRandom;
4693             mkd_params.RandomInfo.ulServerRandomLen =
4694                 sizeof(TLSServerRandom);
4695             break;
4696     }
4697     mkd_params.pVersion = (!isDH) ? &version : NULL;
4698 
4699     /* First create the pre-master secret key */
4700 
4701     skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
4702     skmd_mech.pParameter = &mkd_params;
4703     skmd_mech.ulParameterLen = sizeof(mkd_params);
4704 
4705     crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech,
4706                                        attrs,
4707                                        attrs_count,
4708                                        &pmk_obj);
4709     if (crv == CKR_OK) {
4710         PKM_LogIt("C_GenerateKey succeeded\n");
4711     } else {
4712         PKM_Error("C_GenerateKey failed with 0x%08X, %-26s\n", crv,
4713                   PKM_CK_RVtoStr(crv));
4714         return crv;
4715     }
4716     /* Test the bad cases */
4717     switch (rnd) {
4718         case CORRECT:
4719             goto correct;
4720 
4721         case BOGUS_CLIENT_RANDOM:
4722             mkd_params.RandomInfo.pClientRandom = NULL;
4723             break;
4724 
4725         case BOGUS_CLIENT_RANDOM_LEN:
4726             mkd_params.RandomInfo.ulClientRandomLen = 0;
4727             break;
4728 
4729         case BOGUS_SERVER_RANDOM:
4730             mkd_params.RandomInfo.pServerRandom = NULL;
4731             break;
4732 
4733         case BOGUS_SERVER_RANDOM_LEN:
4734             mkd_params.RandomInfo.ulServerRandomLen = 0;
4735             break;
4736     }
4737     crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0,
4738                                      &mk_obj);
4739     if (crv != CKR_MECHANISM_PARAM_INVALID) {
4740         PKM_LogIt("C_DeriveKey returned as EXPECTED with 0x%08X, %-26s\n", crv,
4741                   PKM_CK_RVtoStr(crv));
4742     } else {
4743         PKM_Error("C_DeriveKey did not fail  with  bad data \n");
4744     }
4745     goto out;
4746 
4747 correct:
4748     /* Now derive the master secret key */
4749     crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0,
4750                                      &mk_obj);
4751     if (crv == CKR_OK) {
4752         PKM_LogIt("C_DeriveKey succeeded\n");
4753     } else {
4754         PKM_Error("C_DeriveKey failed with 0x%08X, %-26s\n", crv,
4755                   PKM_CK_RVtoStr(crv));
4756         return crv;
4757     }
4758 
4759 out:
4760     if (pmk_obj != CK_INVALID_HANDLE)
4761         (void)pFunctionList->C_DestroyObject(hSession, pmk_obj);
4762     if (mk_obj != CK_INVALID_HANDLE)
4763         (void)pFunctionList->C_DestroyObject(hSession, mk_obj);
4764     crv = pFunctionList->C_Logout(hSession);
4765 
4766     if (crv == CKR_OK) {
4767         PKM_LogIt("C_Logout succeeded\n");
4768     } else {
4769         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
4770                   PKM_CK_RVtoStr(crv));
4771         return crv;
4772     }
4773 
4774     crv = pFunctionList->C_CloseSession(hSession);
4775     if (crv != CKR_OK) {
4776         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
4777                   PKM_CK_RVtoStr(crv));
4778         return crv;
4779     }
4780     return (crv);
4781 }
4782 
4783 CK_RV
PKM_TLSKeyAndMacDerive(CK_FUNCTION_LIST_PTR pFunctionList,CK_SLOT_ID * pSlotList,CK_ULONG slotID,CK_UTF8CHAR_PTR pwd,CK_ULONG pwdLen,CK_MECHANISM_TYPE mechType,enum_random_t rnd)4784 PKM_TLSKeyAndMacDerive(CK_FUNCTION_LIST_PTR pFunctionList,
4785                        CK_SLOT_ID *pSlotList, CK_ULONG slotID,
4786                        CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
4787                        CK_MECHANISM_TYPE mechType, enum_random_t rnd)
4788 {
4789     CK_SESSION_HANDLE hSession;
4790     CK_RV crv;
4791     CK_MECHANISM kmd_mech;
4792     CK_MECHANISM skmd_mech;
4793     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
4794     CK_KEY_TYPE type = CKK_GENERIC_SECRET;
4795     CK_BBOOL derive_bool = true;
4796     CK_BBOOL sign_bool = true, verify_bool = true;
4797     CK_BBOOL encrypt_bool = true, decrypt_bool = true;
4798     CK_ULONG value_len;
4799 
4800     /*
4801      * We arrange this template so that:
4802      * . Attributes 0-6 are good for a MAC key comparison template.
4803      * . Attributes 2-5 are good for the master key creation template.
4804      * . Attributes 3-8 are good for a cipher key comparison template.
4805      */
4806     CK_ATTRIBUTE attrs[9];
4807 
4808     CK_OBJECT_HANDLE mk_obj = CK_INVALID_HANDLE;
4809     CK_SSL3_KEY_MAT_PARAMS km_params;
4810     CK_SSL3_KEY_MAT_OUT kmo;
4811     CK_BYTE IVClient[8];
4812     CK_BYTE IVServer[8];
4813 
4814     NUMTESTS++; /* increment NUMTESTS */
4815 
4816     attrs[0].type = CKA_SIGN;
4817     attrs[0].pValue = &sign_bool;
4818     attrs[0].ulValueLen = sizeof(sign_bool);
4819     attrs[1].type = CKA_VERIFY;
4820     attrs[1].pValue = &verify_bool;
4821     attrs[1].ulValueLen = sizeof(verify_bool);
4822     attrs[2].type = CKA_KEY_TYPE;
4823     attrs[2].pValue = &type;
4824     attrs[2].ulValueLen = sizeof(type);
4825     attrs[3].type = CKA_CLASS;
4826     attrs[3].pValue = &class;
4827     attrs[3].ulValueLen = sizeof(class);
4828     attrs[4].type = CKA_DERIVE;
4829     attrs[4].pValue = &derive_bool;
4830     attrs[4].ulValueLen = sizeof(derive_bool);
4831     attrs[5].type = CKA_VALUE;
4832     attrs[5].pValue = NULL;
4833     attrs[5].ulValueLen = 0;
4834     attrs[6].type = CKA_VALUE_LEN;
4835     attrs[6].pValue = &value_len;
4836     attrs[6].ulValueLen = sizeof(value_len);
4837     attrs[7].type = CKA_ENCRYPT;
4838     attrs[7].pValue = &encrypt_bool;
4839     attrs[7].ulValueLen = sizeof(encrypt_bool);
4840     attrs[8].type = CKA_DECRYPT;
4841     attrs[8].pValue = &decrypt_bool;
4842     attrs[8].ulValueLen = sizeof(decrypt_bool);
4843 
4844     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
4845                                        NULL, NULL, &hSession);
4846     if (crv != CKR_OK) {
4847         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
4848                   PKM_CK_RVtoStr(crv));
4849         return crv;
4850     }
4851     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
4852     if (crv == CKR_OK) {
4853         PKM_LogIt("C_Login with correct password succeeded\n");
4854     } else {
4855         PKM_Error("C_Login with correct password failed "
4856                   "with 0x%08X, %-26s\n",
4857                   crv, PKM_CK_RVtoStr(crv));
4858         return crv;
4859     }
4860 
4861     /* Before all, check if the mechanism is supported correctly */
4862     if (MODE == FIPSMODE) {
4863         crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE,
4864                             CK_TRUE, 48, 48);
4865 
4866         if (crv != CKR_OK) {
4867             PKM_Error("PKM_MechCheck failed with 0x%08X, %-26s\n", crv,
4868                       PKM_CK_RVtoStr(crv));
4869             return (crv);
4870         }
4871     }
4872     kmd_mech.mechanism = mechType;
4873     kmd_mech.pParameter = &km_params;
4874     kmd_mech.ulParameterLen = sizeof(km_params);
4875 
4876     km_params.ulMacSizeInBits = 128; /* an MD5 based MAC */
4877     km_params.ulKeySizeInBits = 192; /* 3DES key size */
4878     km_params.ulIVSizeInBits = 64;   /* 3DES block size */
4879     km_params.pReturnedKeyMaterial = &kmo;
4880     km_params.bIsExport = false;
4881     kmo.hClientMacSecret = CK_INVALID_HANDLE;
4882     kmo.hServerMacSecret = CK_INVALID_HANDLE;
4883     kmo.hClientKey = CK_INVALID_HANDLE;
4884     kmo.hServerKey = CK_INVALID_HANDLE;
4885     kmo.pIVClient = IVClient;
4886     kmo.pIVServer = IVServer;
4887 
4888     skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
4889     skmd_mech.pParameter = &km_params;
4890     skmd_mech.ulParameterLen = sizeof(km_params);
4891 
4892     crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech,
4893                                        &attrs[2],
4894                                        4,
4895                                        &mk_obj);
4896     if (crv == CKR_OK) {
4897         PKM_LogIt("C_GenerateKey succeeded\n");
4898     } else {
4899         PKM_Error("C_GenerateKey failed with 0x%08X, %-26s\n", crv,
4900                   PKM_CK_RVtoStr(crv));
4901         return crv;
4902     }
4903 
4904     attrs[5].pValue = NULL;
4905     attrs[5].ulValueLen = 0;
4906 
4907     km_params.RandomInfo.pClientRandom = (unsigned char *)TLSClientRandom;
4908     km_params.RandomInfo.ulClientRandomLen =
4909         sizeof(TLSClientRandom);
4910     km_params.RandomInfo.pServerRandom = (unsigned char *)TLSServerRandom;
4911     km_params.RandomInfo.ulServerRandomLen =
4912         sizeof(TLSServerRandom);
4913 
4914     /* Test the bad cases */
4915     switch (rnd) {
4916         case CORRECT:
4917             goto correct;
4918 
4919         case BOGUS_CLIENT_RANDOM:
4920             km_params.RandomInfo.pClientRandom = NULL;
4921             break;
4922 
4923         case BOGUS_CLIENT_RANDOM_LEN:
4924             km_params.RandomInfo.ulClientRandomLen = 0;
4925             break;
4926 
4927         case BOGUS_SERVER_RANDOM:
4928             km_params.RandomInfo.pServerRandom = NULL;
4929             break;
4930 
4931         case BOGUS_SERVER_RANDOM_LEN:
4932             km_params.RandomInfo.ulServerRandomLen = 0;
4933             break;
4934     }
4935     crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0,
4936                                      NULL);
4937     if (crv != CKR_MECHANISM_PARAM_INVALID) {
4938         PKM_Error("key materials derivation returned unexpected "
4939                   "error 0x%08X, %-26s\n",
4940                   crv, PKM_CK_RVtoStr(crv));
4941         (void)pFunctionList->C_DestroyObject(hSession, mk_obj);
4942         return (CKR_FUNCTION_FAILED);
4943     }
4944     return (CKR_OK);
4945 
4946 correct:
4947     /*
4948      * Then use the master key and the client 'n server random data to
4949      * derive the key materials
4950      */
4951     crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0,
4952                                      NULL);
4953     if (crv != CKR_OK) {
4954         PKM_Error("Cannot derive the key materials, crv 0x%08X, %-26s\n",
4955                   crv, PKM_CK_RVtoStr(crv));
4956         (void)pFunctionList->C_DestroyObject(hSession, mk_obj);
4957         return (crv);
4958     }
4959 
4960     if (mk_obj != CK_INVALID_HANDLE)
4961         (void)pFunctionList->C_DestroyObject(hSession, mk_obj);
4962     if (kmo.hClientMacSecret != CK_INVALID_HANDLE)
4963         (void)pFunctionList->C_DestroyObject(hSession, kmo.hClientMacSecret);
4964     if (kmo.hServerMacSecret != CK_INVALID_HANDLE)
4965         (void)pFunctionList->C_DestroyObject(hSession, kmo.hServerMacSecret);
4966     if (kmo.hClientKey != CK_INVALID_HANDLE)
4967         (void)pFunctionList->C_DestroyObject(hSession, kmo.hClientKey);
4968     if (kmo.hServerKey != CK_INVALID_HANDLE)
4969         (void)pFunctionList->C_DestroyObject(hSession, kmo.hServerKey);
4970 
4971     crv = pFunctionList->C_Logout(hSession);
4972     if (crv == CKR_OK) {
4973         PKM_LogIt("C_Logout succeeded\n");
4974     } else {
4975         PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
4976                   PKM_CK_RVtoStr(crv));
4977         return crv;
4978     }
4979     crv = pFunctionList->C_CloseSession(hSession);
4980     if (crv != CKR_OK) {
4981         PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
4982                   PKM_CK_RVtoStr(crv));
4983         return crv;
4984     }
4985 
4986     return (crv);
4987 }
4988 
4989 CK_RV
PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hRwSession,CK_OBJECT_HANDLE publicKey,CK_OBJECT_HANDLE privateKey,CK_MECHANISM * sigMech,CK_OBJECT_HANDLE secretKey,CK_MECHANISM * cryptMech,const CK_BYTE * pData,CK_ULONG pDataLen)4990 PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,
4991                  CK_SESSION_HANDLE hRwSession,
4992                  CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey,
4993                  CK_MECHANISM *sigMech,
4994                  CK_OBJECT_HANDLE secretKey, CK_MECHANISM *cryptMech,
4995                  const CK_BYTE *pData, CK_ULONG pDataLen)
4996 {
4997 
4998     CK_RV crv = CKR_OK;
4999     CK_BYTE encryptedData[MAX_CIPHER_SZ];
5000     CK_ULONG ulEncryptedDataLen = 0;
5001     CK_ULONG ulLastUpdateSize = 0;
5002     CK_BYTE sig[MAX_SIG_SZ];
5003     CK_ULONG ulSigLen = 0;
5004     CK_BYTE data[MAX_DATA_SZ];
5005     CK_ULONG ulDataLen = 0;
5006 
5007     memset(encryptedData, 0, sizeof(encryptedData));
5008     memset(sig, 0, sizeof(sig));
5009     memset(data, 0, sizeof(data));
5010 
5011     NUMTESTS++; /* increment NUMTESTS */
5012 
5013     /* Check that the mechanism is Multi-part */
5014     if (sigMech->mechanism == CKM_DSA || sigMech->mechanism == CKM_RSA_PKCS) {
5015         PKM_Error("PKM_DualFuncSign must be called with a Multi-part "
5016                   "operation mechanism\n");
5017         return CKR_DEVICE_ERROR;
5018     }
5019 
5020     /* Sign and Encrypt */
5021     if (privateKey == 0 && publicKey == 0) {
5022         crv = pFunctionList->C_SignInit(hRwSession, sigMech, secretKey);
5023         if (crv != CKR_OK) {
5024             PKM_Error("C_SignInit failed with 0x%08X, %-26s\n", crv,
5025                       PKM_CK_RVtoStr(crv));
5026             return crv;
5027         }
5028     } else {
5029         crv = pFunctionList->C_SignInit(hRwSession, sigMech, privateKey);
5030         if (crv != CKR_OK) {
5031             PKM_Error("C_SignInit failed with 0x%08X, %-26s\n", crv,
5032                       PKM_CK_RVtoStr(crv));
5033             return crv;
5034         }
5035     }
5036     crv = pFunctionList->C_EncryptInit(hRwSession, cryptMech, secretKey);
5037     if (crv != CKR_OK) {
5038         PKM_Error("C_EncryptInit failed with 0x%08X, %-26s\n", crv,
5039                   PKM_CK_RVtoStr(crv));
5040         return crv;
5041     }
5042 
5043     ulEncryptedDataLen = sizeof(encryptedData);
5044     crv = pFunctionList->C_SignEncryptUpdate(hRwSession, (CK_BYTE *)pData,
5045                                              pDataLen,
5046                                              encryptedData,
5047                                              &ulEncryptedDataLen);
5048     if (crv != CKR_OK) {
5049         PKM_Error("C_Sign failed with 0x%08X, %-26s\n", crv,
5050                   PKM_CK_RVtoStr(crv));
5051         return crv;
5052     }
5053 
5054     ulLastUpdateSize = sizeof(encryptedData) - ulEncryptedDataLen;
5055     crv = pFunctionList->C_EncryptFinal(hRwSession,
5056                                         (CK_BYTE *)&encryptedData[ulEncryptedDataLen], &ulLastUpdateSize);
5057     if (crv != CKR_OK) {
5058         PKM_Error("C_EncryptFinal failed with 0x%08X, %-26s\n", crv,
5059                   PKM_CK_RVtoStr(crv));
5060         return crv;
5061     }
5062     ulEncryptedDataLen = ulEncryptedDataLen + ulLastUpdateSize;
5063     ulSigLen = sizeof(sig);
5064     crv = pFunctionList->C_SignFinal(hRwSession, sig, &ulSigLen);
5065     if (crv != CKR_OK) {
5066         PKM_Error("C_SignFinal failed with 0x%08X, %-26s\n", crv,
5067                   PKM_CK_RVtoStr(crv));
5068         return crv;
5069     }
5070 
5071     /* Decrypt and Verify */
5072 
5073     crv = pFunctionList->C_DecryptInit(hRwSession, cryptMech, secretKey);
5074     if (crv != CKR_OK) {
5075         PKM_Error("C_DecryptInit failed with 0x%08X, %-26s\n", crv,
5076                   PKM_CK_RVtoStr(crv));
5077         return crv;
5078     }
5079     crv = pFunctionList->C_VerifyInit(hRwSession, sigMech,
5080                                       publicKey);
5081     if (crv != CKR_OK) {
5082         PKM_Error("C_VerifyInit failed with 0x%08X, %-26s\n", crv,
5083                   PKM_CK_RVtoStr(crv));
5084         return crv;
5085     }
5086 
5087     ulDataLen = sizeof(data);
5088     crv = pFunctionList->C_DecryptVerifyUpdate(hRwSession,
5089                                                encryptedData,
5090                                                ulEncryptedDataLen,
5091                                                data, &ulDataLen);
5092     if (crv != CKR_OK) {
5093         PKM_Error("C_DecryptVerifyUpdate failed with 0x%08X, %-26s\n", crv,
5094                   PKM_CK_RVtoStr(crv));
5095         return crv;
5096     }
5097     ulLastUpdateSize = sizeof(data) - ulDataLen;
5098     /* Get last little piece of plaintext.  Should have length 0 */
5099     crv = pFunctionList->C_DecryptFinal(hRwSession, &data[ulDataLen],
5100                                         &ulLastUpdateSize);
5101     if (crv != CKR_OK) {
5102         PKM_Error("C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
5103                   PKM_CK_RVtoStr(crv));
5104         return crv;
5105     }
5106 
5107     if (ulLastUpdateSize != 0) {
5108         crv = pFunctionList->C_VerifyUpdate(hRwSession, &data[ulDataLen],
5109                                             ulLastUpdateSize);
5110         if (crv != CKR_OK) {
5111             PKM_Error("C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
5112                       PKM_CK_RVtoStr(crv));
5113             return crv;
5114         }
5115     }
5116     ulDataLen = ulDataLen + ulLastUpdateSize;
5117 
5118     /* input for the verify operation is the decrypted data */
5119     crv = pFunctionList->C_VerifyFinal(hRwSession, sig, ulSigLen);
5120     if (crv == CKR_OK) {
5121         PKM_LogIt("C_VerifyFinal succeeded\n");
5122     } else {
5123         PKM_Error("C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
5124                   PKM_CK_RVtoStr(crv));
5125         return crv;
5126     }
5127 
5128     /* Comparison of Decrypted data with inputed data */
5129     if ((ulDataLen == pDataLen) &&
5130         (memcmp(data, pData, pDataLen) == 0)) {
5131         PKM_LogIt("PKM_DualFuncSign decrypt test case passed\n");
5132     } else {
5133         PKM_Error("PKM_DualFuncSign derypt test case failed\n");
5134     }
5135 
5136     return crv;
5137 }
5138 
5139 CK_RV
PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList,CK_SESSION_HANDLE hSession,CK_MECHANISM * digestMech,CK_OBJECT_HANDLE hSecretKey,const CK_BYTE * pData,CK_ULONG pDataLen)5140 PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList,
5141            CK_SESSION_HANDLE hSession,
5142            CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey,
5143            const CK_BYTE *pData, CK_ULONG pDataLen)
5144 {
5145     CK_RV crv = CKR_OK;
5146     CK_BYTE digest1[MAX_DIGEST_SZ];
5147     CK_ULONG digest1Len = 0;
5148     CK_BYTE digest2[MAX_DIGEST_SZ];
5149     CK_ULONG digest2Len = 0;
5150 
5151     /* Tested with CKM_SHA_1, CKM_SHA224, CKM_SHA256, CKM_SHA384, CKM_SHA512 */
5152 
5153     memset(digest1, 0, sizeof(digest1));
5154     memset(digest2, 0, sizeof(digest2));
5155 
5156     NUMTESTS++; /* increment NUMTESTS */
5157 
5158     crv = pFunctionList->C_DigestInit(hSession, digestMech);
5159     if (crv != CKR_OK) {
5160         PKM_Error("C_SignInit failed with 0x%08X, %-26s\n", crv,
5161                   PKM_CK_RVtoStr(crv));
5162         return crv;
5163     }
5164     digest1Len = sizeof(digest1);
5165     crv = pFunctionList->C_Digest(hSession, (CK_BYTE *)pData, pDataLen,
5166                                   digest1, &digest1Len);
5167     if (crv != CKR_OK) {
5168         PKM_Error("C_Sign failed with 0x%08X, %-26s\n", crv,
5169                   PKM_CK_RVtoStr(crv));
5170         return crv;
5171     }
5172 
5173     crv = pFunctionList->C_DigestInit(hSession, digestMech);
5174     if (crv != CKR_OK) {
5175         PKM_Error("C_DigestInit failed with 0x%08X, %-26s\n", crv,
5176                   PKM_CK_RVtoStr(crv));
5177         return crv;
5178     }
5179 
5180     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE *)pData, pDataLen);
5181     if (crv != CKR_OK) {
5182         PKM_Error("C_DigestUpdate failed with 0x%08X, %-26s\n", crv,
5183                   PKM_CK_RVtoStr(crv));
5184         return crv;
5185     }
5186 
5187     /* C_DigestKey continues a multiple-part message-digesting operation by*/
5188     /* digesting the value of a secret key. (only used with C_DigestUpdate)*/
5189     if (hSecretKey != 0) {
5190         crv = pFunctionList->C_DigestKey(hSession, hSecretKey);
5191         if (crv != CKR_OK) {
5192             PKM_Error("C_DigestKey failed with 0x%08X, %-26s\n", crv,
5193                       PKM_CK_RVtoStr(crv));
5194             return crv;
5195         }
5196     }
5197 
5198     digest2Len = sizeof(digest2);
5199     crv = pFunctionList->C_DigestFinal(hSession, digest2, &digest2Len);
5200     if (crv != CKR_OK) {
5201         PKM_Error("C_DigestFinal failed with 0x%08X, %-26s\n", crv,
5202                   PKM_CK_RVtoStr(crv));
5203         return crv;
5204     }
5205 
5206     if (hSecretKey == 0) {
5207         /* did not digest a secret key so digests should equal */
5208         if ((digest1Len == digest2Len) &&
5209             (memcmp(digest1, digest2, digest1Len) == 0)) {
5210             PKM_LogIt("Single and Multiple-part message digest "
5211                       "operations successful\n");
5212         } else {
5213             PKM_Error("Single and Multiple-part message digest "
5214                       "operations failed\n");
5215         }
5216     } else {
5217         if (digest1Len == digest2Len) {
5218             PKM_LogIt("PKM_Digest Single and Multiple-part message digest "
5219                       "operations successful\n");
5220         } else {
5221             PKM_Error("PKM_Digest Single and Multiple-part message digest "
5222                       "operations failed\n");
5223         }
5224     }
5225 
5226     return crv;
5227 }
5228 
5229 char *
PKM_FilePasswd(char * pwFile)5230 PKM_FilePasswd(char *pwFile)
5231 {
5232     unsigned char phrase[200];
5233     PRFileDesc *fd;
5234     PRInt32 nb;
5235     int i;
5236 
5237     if (!pwFile)
5238         return 0;
5239 
5240     fd = PR_Open(pwFile, PR_RDONLY, 0);
5241     if (!fd) {
5242         fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
5243         return NULL;
5244     }
5245 
5246     nb = PR_Read(fd, phrase, sizeof(phrase));
5247 
5248     PR_Close(fd);
5249     /* handle the Windows EOL case */
5250     i = 0;
5251     while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb)
5252         i++;
5253     phrase[i] = '\0';
5254     if (nb == 0) {
5255         fprintf(stderr, "password file contains no data\n");
5256         return NULL;
5257     }
5258     return (char *)strdup((char *)phrase);
5259 }
5260 
5261 void
PKM_Help()5262 PKM_Help()
5263 {
5264     PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError);
5265     PR_fprintf(debug_out, "pk11mode test program usage:\n");
5266     PR_fprintf(debug_out, "\t-f <file>   Password File : echo pw > file \n");
5267     PR_fprintf(debug_out, "\t-F          Disable Unix fork tests\n");
5268     PR_fprintf(debug_out, "\t-n          Non Fips Mode \n");
5269     PR_fprintf(debug_out, "\t-d <path>   Database path location\n");
5270     PR_fprintf(debug_out, "\t-p <prefix> DataBase prefix\n");
5271     PR_fprintf(debug_out, "\t-v          verbose\n");
5272     PR_fprintf(debug_out, "\t-h          this help message\n");
5273     exit(1);
5274 }
5275 
5276 void
PKM_CheckPath(char * string)5277 PKM_CheckPath(char *string)
5278 {
5279     char *src;
5280     char *dest;
5281 
5282     /*
5283    * windows support convert any back slashes to
5284    * forward slashes.
5285    */
5286     for (src = string, dest = string; *src; src++, dest++) {
5287         if (*src == '\\') {
5288             *dest = '/';
5289         }
5290     }
5291     dest--;
5292     /* if the last char is a / set it to 0 */
5293     if (*dest == '/')
5294         *dest = 0;
5295 }
5296 
5297 CK_RV
PKM_ForkCheck(int expected,CK_FUNCTION_LIST_PTR fList,PRBool forkAssert,CK_C_INITIALIZE_ARGS_NSS * initArgs)5298 PKM_ForkCheck(int expected, CK_FUNCTION_LIST_PTR fList,
5299               PRBool forkAssert, CK_C_INITIALIZE_ARGS_NSS *initArgs)
5300 {
5301     CK_RV crv = CKR_OK;
5302 #ifndef NO_FORK_CHECK
5303     int rc = -1;
5304     pid_t child, ret;
5305     NUMTESTS++; /* increment NUMTESTS */
5306     if (forkAssert) {
5307         putenv("NSS_STRICT_NOFORK=1");
5308     } else {
5309         putenv("NSS_STRICT_NOFORK=0");
5310     }
5311     child = fork();
5312     switch (child) {
5313         case -1:
5314             PKM_Error("Fork failed.\n");
5315             crv = CKR_DEVICE_ERROR;
5316             break;
5317         case 0:
5318             if (fList) {
5319                 if (!initArgs) {
5320                     /* If softoken is loaded, make a PKCS#11 call to C_GetTokenInfo
5321                  * in the child. This call should always fail.
5322                  * If softoken is uninitialized,
5323                  * it fails with CKR_CRYPTOKI_NOT_INITIALIZED.
5324                  * If it was initialized in the parent, the fork check should
5325                  * kick in, and make it return CKR_DEVICE_ERROR.
5326                  */
5327                     CK_RV child_crv = fList->C_GetTokenInfo(0, NULL);
5328                     exit(child_crv & 255);
5329                 } else {
5330                     /* If softoken is loaded, make a PKCS#11 call to C_Initialize
5331                  * in the child. This call should always fail.
5332                  * If softoken is uninitialized, this should succeed.
5333                  * If it was initialized in the parent, the fork check should
5334                  * kick in, and make it return CKR_DEVICE_ERROR.
5335                  */
5336                     CK_RV child_crv = fList->C_Initialize(initArgs);
5337                     if (CKR_OK == child_crv) {
5338                         child_crv = fList->C_Finalize(NULL);
5339                     }
5340                     exit(child_crv & 255);
5341                 }
5342             }
5343             exit(expected & 255);
5344         default:
5345             PKM_LogIt("Fork succeeded.\n");
5346             ret = wait(&rc);
5347             if (ret != child || (!WIFEXITED(rc)) ||
5348                 ((expected & 255) != (WEXITSTATUS(rc) & 255))) {
5349                 int retStatus = -1;
5350                 if (WIFEXITED(rc)) {
5351                     retStatus = WEXITSTATUS(rc);
5352                 }
5353                 PKM_Error("Child misbehaved.\n");
5354                 printf("Child return status : %d.\n", retStatus & 255);
5355                 crv = CKR_DEVICE_ERROR;
5356             }
5357             break;
5358     }
5359 #endif
5360     return crv;
5361 }
5362