security/nss/cmd/pk11mode/pk11mode.c

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial