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