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