michael@0: /* michael@0: * pk11mode.c - Test FIPS or NONFIPS Modes for the NSS PKCS11 api. michael@0: * The goal of this program is to test every function michael@0: * entry point of the PKCS11 api at least once. michael@0: * To test in FIPS mode: pk11mode michael@0: * To test in NONFIPS mode: pk11mode -n michael@0: * usage: pk11mode -h michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #if defined(XP_UNIX) && !defined(NO_FORK_CHECK) michael@0: #include michael@0: #include michael@0: #else michael@0: #ifndef NO_FORK_CHECK michael@0: #define NO_FORK_CHECK michael@0: #endif michael@0: #endif michael@0: michael@0: #ifdef _WIN32 michael@0: #include michael@0: #define LIB_NAME "softokn3.dll" michael@0: #endif michael@0: #include "prlink.h" michael@0: #include "prprf.h" michael@0: #include "plgetopt.h" michael@0: #include "prenv.h" michael@0: michael@0: #include "pk11table.h" michael@0: michael@0: #define NUM_ELEM(array) (sizeof(array)/sizeof(array[0])) michael@0: michael@0: #ifndef NULL_PTR michael@0: #define NULL_PTR 0 michael@0: #endif michael@0: michael@0: /* Returns constant error string for "CRV". michael@0: * Returns "unknown error" if errNum is unknown. michael@0: */ michael@0: const char * michael@0: PKM_CK_RVtoStr(CK_RV errNum) { michael@0: const char * err; michael@0: michael@0: err = getName(errNum, ConstResult); michael@0: michael@0: if (err) return err; michael@0: michael@0: return "unknown error"; michael@0: } michael@0: michael@0: #include "pkcs11p.h" michael@0: michael@0: typedef struct CK_C_INITIALIZE_ARGS_NSS { michael@0: CK_CREATEMUTEX CreateMutex; michael@0: CK_DESTROYMUTEX DestroyMutex; michael@0: CK_LOCKMUTEX LockMutex; michael@0: CK_UNLOCKMUTEX UnlockMutex; michael@0: CK_FLAGS flags; michael@0: /* The official PKCS #11 spec does not have a 'LibraryParameters' field, but michael@0: * a reserved field. NSS needs a way to pass instance-specific information michael@0: * to the library (like where to find its config files, etc). This michael@0: * information is usually provided by the installer and passed uninterpreted michael@0: * by NSS to the library, though NSS does know the specifics of the softoken michael@0: * version of this parameter. Most compliant PKCS#11 modules expect this michael@0: * parameter to be NULL, and will return CKR_ARGUMENTS_BAD from michael@0: * C_Initialize if Library parameters is supplied. */ michael@0: CK_CHAR_PTR *LibraryParameters; michael@0: /* This field is only present if the LibraryParameters is not NULL. It must michael@0: * be NULL in all cases */ michael@0: CK_VOID_PTR pReserved; michael@0: } CK_C_INITIALIZE_ARGS_NSS; michael@0: michael@0: #include "pkcs11u.h" michael@0: michael@0: #define MAX_SIG_SZ 128 michael@0: #define MAX_CIPHER_SZ 128 michael@0: #define MAX_DATA_SZ 64 michael@0: #define MAX_DIGEST_SZ 64 michael@0: #define HMAC_MAX_LENGTH 64 michael@0: #define FIPSMODE 0 michael@0: #define NONFIPSMODE 1 michael@0: #define HYBRIDMODE 2 michael@0: #define NOMODE 3 michael@0: int MODE = FIPSMODE; michael@0: michael@0: CK_BBOOL true = CK_TRUE; michael@0: CK_BBOOL false = CK_FALSE; michael@0: static const CK_BYTE PLAINTEXT[] = {"Firefox Rules!"}; michael@0: static const CK_BYTE PLAINTEXT_PAD[] = michael@0: {"Firefox and thunderbird rule the world!"}; michael@0: CK_ULONG NUMTESTS = 0; michael@0: michael@0: static const char * slotFlagName[] = { michael@0: "CKF_TOKEN_PRESENT", michael@0: "CKF_REMOVABLE_DEVICE", michael@0: "CKF_HW_SLOT", michael@0: "unknown token flag 0x00000008", michael@0: "unknown token flag 0x00000010", michael@0: "unknown token flag 0x00000020", michael@0: "unknown token flag 0x00000040", michael@0: "unknown token flag 0x00000080", michael@0: "unknown token flag 0x00000100", michael@0: "unknown token flag 0x00000200", michael@0: "unknown token flag 0x00000400", michael@0: "unknown token flag 0x00000800", michael@0: "unknown token flag 0x00001000", michael@0: "unknown token flag 0x00002000", michael@0: "unknown token flag 0x00004000", michael@0: "unknown token flag 0x00008000" michael@0: "unknown token flag 0x00010000", michael@0: "unknown token flag 0x00020000", michael@0: "unknown token flag 0x00040000", michael@0: "unknown token flag 0x00080000", michael@0: "unknown token flag 0x00100000", michael@0: "unknown token flag 0x00200000", michael@0: "unknown token flag 0x00400000", michael@0: "unknown token flag 0x00800000" michael@0: "unknown token flag 0x01000000", michael@0: "unknown token flag 0x02000000", michael@0: "unknown token flag 0x04000000", michael@0: "unknown token flag 0x08000000", michael@0: "unknown token flag 0x10000000", michael@0: "unknown token flag 0x20000000", michael@0: "unknown token flag 0x40000000", michael@0: "unknown token flag 0x80000000" michael@0: }; michael@0: michael@0: static const char * tokenFlagName[] = { michael@0: "CKF_PKM_RNG", michael@0: "CKF_WRITE_PROTECTED", michael@0: "CKF_LOGIN_REQUIRED", michael@0: "CKF_USER_PIN_INITIALIZED", michael@0: "unknown token flag 0x00000010", michael@0: "CKF_RESTORE_KEY_NOT_NEEDED", michael@0: "CKF_CLOCK_ON_TOKEN", michael@0: "unknown token flag 0x00000080", michael@0: "CKF_PROTECTED_AUTHENTICATION_PATH", michael@0: "CKF_DUAL_CRYPTO_OPERATIONS", michael@0: "CKF_TOKEN_INITIALIZED", michael@0: "CKF_SECONDARY_AUTHENTICATION", michael@0: "unknown token flag 0x00001000", michael@0: "unknown token flag 0x00002000", michael@0: "unknown token flag 0x00004000", michael@0: "unknown token flag 0x00008000", michael@0: "CKF_USER_PIN_COUNT_LOW", michael@0: "CKF_USER_PIN_FINAL_TRY", michael@0: "CKF_USER_PIN_LOCKED", michael@0: "CKF_USER_PIN_TO_BE_CHANGED", michael@0: "CKF_SO_PIN_COUNT_LOW", michael@0: "CKF_SO_PIN_FINAL_TRY", michael@0: "CKF_SO_PIN_LOCKED", michael@0: "CKF_SO_PIN_TO_BE_CHANGED", michael@0: "unknown token flag 0x01000000", michael@0: "unknown token flag 0x02000000", michael@0: "unknown token flag 0x04000000", michael@0: "unknown token flag 0x08000000", michael@0: "unknown token flag 0x10000000", michael@0: "unknown token flag 0x20000000", michael@0: "unknown token flag 0x40000000", michael@0: "unknown token flag 0x80000000" michael@0: }; michael@0: michael@0: static const unsigned char TLSClientRandom[] = { michael@0: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, michael@0: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, michael@0: 0x0d, 0x90, 0xbb, 0x5e, 0xc6, 0xe1, 0x3f, 0x71, michael@0: 0x0a, 0xa2, 0x70, 0x5a, 0x4f, 0xbc, 0x3f, 0x0d michael@0: }; michael@0: static const unsigned char TLSServerRandom[] = { michael@0: 0x00, 0x00, 0x1d, 0x4a, 0x7a, 0x0a, 0xa5, 0x01, michael@0: 0x8e, 0x79, 0x72, 0xde, 0x9e, 0x2f, 0x8a, 0x0d, michael@0: 0xed, 0xb2, 0x5d, 0xf1, 0x14, 0xc2, 0xc6, 0x66, michael@0: 0x95, 0x86, 0xb0, 0x0d, 0x87, 0x2a, 0x2a, 0xc9 michael@0: }; michael@0: michael@0: typedef enum { michael@0: CORRECT, michael@0: BOGUS_CLIENT_RANDOM, michael@0: BOGUS_CLIENT_RANDOM_LEN, michael@0: BOGUS_SERVER_RANDOM, michael@0: BOGUS_SERVER_RANDOM_LEN michael@0: } enum_random_t; michael@0: michael@0: void michael@0: dumpToHash64(const unsigned char *buf, unsigned int bufLen) michael@0: { michael@0: unsigned int i; michael@0: for (i = 0; i < bufLen; i += 8) { michael@0: if (i % 32 == 0) michael@0: printf("\n"); michael@0: printf(" 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,", michael@0: buf[i ], buf[i+1], buf[i+2], buf[i+3], michael@0: buf[i+4], buf[i+5], buf[i+6], buf[i+7]); michael@0: } michael@0: printf("\n"); michael@0: } michael@0: michael@0: michael@0: #ifdef _WIN32 michael@0: HMODULE hModule; michael@0: #else michael@0: PRLibrary *lib; michael@0: #endif michael@0: michael@0: /* michael@0: * All api that belongs to pk11mode.c layer start with the prefix PKM_ michael@0: */ michael@0: void PKM_LogIt(const char *fmt, ...); michael@0: void PKM_Error(const char *fmt, ...); michael@0: CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_ULONG slotID); michael@0: CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID); michael@0: CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID *pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID); michael@0: CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID * pSlotList, michael@0: CK_ULONG slotID); michael@0: CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID *pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList, michael@0: CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList, michael@0: CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, michael@0: CK_C_INITIALIZE_ARGS_NSS *initArgs); michael@0: CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_MultiObjectManagement(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID *pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj, michael@0: CK_ATTRIBUTE_PTR expected_attrs, michael@0: CK_ULONG expected_attrs_count); michael@0: CK_RV PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, CK_MECHANISM_TYPE mechType, michael@0: CK_FLAGS flags, CK_BBOOL check_sizes, michael@0: CK_ULONG minkeysize, CK_ULONG maxkeysize); michael@0: CK_RV PKM_TLSKeyAndMacDerive(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, michael@0: CK_MECHANISM_TYPE mechType, enum_random_t rnd); michael@0: CK_RV PKM_TLSMasterKeyDerive(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, michael@0: CK_MECHANISM_TYPE mechType, michael@0: enum_random_t rnd); michael@0: CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID *pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen); michael@0: CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hRwSession, michael@0: CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey, michael@0: CK_MECHANISM *sigMech, CK_OBJECT_HANDLE secretKey, michael@0: CK_MECHANISM *cryptMech, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen); michael@0: CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech, michael@0: CK_OBJECT_HANDLE hSecKeyDigest, michael@0: CK_MECHANISM *digestMech, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen); michael@0: CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hRwSession, michael@0: CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey, michael@0: CK_MECHANISM *signMech, const CK_BYTE * pData, michael@0: CK_ULONG dataLen); michael@0: CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech, michael@0: const CK_BYTE * pData, CK_ULONG dataLen); michael@0: CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen); michael@0: CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hRwSession, michael@0: CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen); michael@0: CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hPublicKey, michael@0: CK_OBJECT_HANDLE hPrivateKey, michael@0: CK_MECHANISM *wrapMechanism, michael@0: CK_OBJECT_HANDLE hSecretKey, michael@0: CK_ATTRIBUTE *sKeyTemplate, michael@0: CK_ULONG skeyTempSize); michael@0: CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey, michael@0: CK_MECHANISM *signMech, const CK_BYTE * pData, michael@0: CK_ULONG pDataLen); michael@0: CK_RV PKM_ForkCheck(int expected, CK_FUNCTION_LIST_PTR fList, michael@0: PRBool forkAssert, CK_C_INITIALIZE_ARGS_NSS *initArgs); michael@0: michael@0: void PKM_Help(); michael@0: void PKM_CheckPath(char *string); michael@0: char *PKM_FilePasswd(char *pwFile); michael@0: static PRBool verbose = PR_FALSE; michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: CK_C_GetFunctionList pC_GetFunctionList; michael@0: CK_FUNCTION_LIST_PTR pFunctionList; michael@0: CK_RV crv = CKR_OK; michael@0: CK_C_INITIALIZE_ARGS_NSS initArgs; michael@0: CK_SLOT_ID *pSlotList = NULL; michael@0: CK_TOKEN_INFO tokenInfo; michael@0: CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */ michael@0: michael@0: CK_UTF8CHAR *pwd = NULL; michael@0: CK_ULONG pwdLen = 0; michael@0: char *moduleSpec = NULL; michael@0: char *configDir = NULL; michael@0: char *dbPrefix = NULL; michael@0: char *disableUnload = NULL; michael@0: PRBool doForkTests = PR_TRUE; michael@0: michael@0: PLOptStatus os; michael@0: PLOptState *opt = PL_CreateOptState(argc, argv, "nvhf:Fd:p:"); michael@0: while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) michael@0: { michael@0: if (PL_OPT_BAD == os) continue; michael@0: switch (opt->option) michael@0: { michael@0: case 'F': /* disable fork tests */ michael@0: doForkTests = PR_FALSE; michael@0: break; michael@0: case 'n': /* non fips mode */ michael@0: MODE = NONFIPSMODE; michael@0: slotID = 1; michael@0: break; michael@0: case 'f': /* password file */ michael@0: pwd = (CK_UTF8CHAR *) PKM_FilePasswd((char *)opt->value); michael@0: if (!pwd) PKM_Help(); michael@0: break; michael@0: case 'd': /* opt_CertDir */ michael@0: if (!opt->value) PKM_Help(); michael@0: configDir = strdup(opt->value); michael@0: PKM_CheckPath(configDir); michael@0: break; michael@0: case 'p': /* opt_DBPrefix */ michael@0: if (!opt->value) PKM_Help(); michael@0: dbPrefix = strdup(opt->value); michael@0: break; michael@0: case 'v': michael@0: verbose = PR_TRUE; michael@0: break; michael@0: case 'h': /* help message */ michael@0: default: michael@0: PKM_Help(); michael@0: break; michael@0: } michael@0: } michael@0: PL_DestroyOptState(opt); michael@0: michael@0: if (!pwd) { michael@0: pwd = (CK_UTF8CHAR *)strdup("1Mozilla"); michael@0: } michael@0: pwdLen = strlen((const char*)pwd); michael@0: if (!configDir) { michael@0: configDir = strdup("."); michael@0: } michael@0: if (!dbPrefix) { michael@0: dbPrefix = strdup(""); michael@0: } michael@0: michael@0: if (doForkTests) michael@0: { michael@0: /* first, try to fork without softoken loaded to make sure michael@0: * everything is OK */ michael@0: crv = PKM_ForkCheck(123, NULL, PR_FALSE, NULL); michael@0: if (crv != CKR_OK) michael@0: goto cleanup; michael@0: } michael@0: michael@0: michael@0: #ifdef _WIN32 michael@0: hModule = LoadLibrary(LIB_NAME); michael@0: if (hModule == NULL) { michael@0: PKM_Error( "cannot load %s\n", LIB_NAME); michael@0: goto cleanup; michael@0: } michael@0: if (MODE == FIPSMODE) { michael@0: /* FIPS mode == FC_GetFunctionList */ michael@0: pC_GetFunctionList = (CK_C_GetFunctionList) michael@0: GetProcAddress(hModule, "FC_GetFunctionList"); michael@0: } else { michael@0: /* NON FIPS mode == C_GetFunctionList */ michael@0: pC_GetFunctionList = (CK_C_GetFunctionList) michael@0: GetProcAddress(hModule, "C_GetFunctionList"); michael@0: } michael@0: if (pC_GetFunctionList == NULL) { michael@0: PKM_Error( "cannot load %s\n", LIB_NAME); michael@0: goto cleanup; michael@0: } michael@0: #else michael@0: { michael@0: char *libname = NULL; michael@0: /* Get the platform-dependent library name of the NSS cryptographic module */ michael@0: libname = PR_GetLibraryName(NULL, "softokn3"); michael@0: assert(libname != NULL); michael@0: lib = PR_LoadLibrary(libname); michael@0: assert(lib != NULL); michael@0: PR_FreeLibraryName(libname); michael@0: } michael@0: if (MODE == FIPSMODE) { michael@0: pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib, michael@0: "FC_GetFunctionList"); michael@0: assert(pC_GetFunctionList != NULL); michael@0: slotID = 0; michael@0: } else { michael@0: pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib, michael@0: "C_GetFunctionList"); michael@0: assert(pC_GetFunctionList != NULL); michael@0: slotID = 1; michael@0: } michael@0: #endif michael@0: michael@0: if (MODE == FIPSMODE) { michael@0: printf("Loaded FC_GetFunctionList for FIPS MODE; slotID %d \n", michael@0: (int) slotID); michael@0: } else { michael@0: printf("loaded C_GetFunctionList for NON FIPS MODE; slotID %d \n", michael@0: (int) slotID); michael@0: } michael@0: michael@0: crv = (*pC_GetFunctionList)(&pFunctionList); michael@0: assert(crv == CKR_OK); michael@0: michael@0: michael@0: if (doForkTests) michael@0: { michael@0: /* now, try to fork with softoken loaded, but not initialized */ michael@0: crv = PKM_ForkCheck(CKR_CRYPTOKI_NOT_INITIALIZED, pFunctionList, michael@0: PR_TRUE, NULL); michael@0: if (crv != CKR_OK) michael@0: goto cleanup; michael@0: } michael@0: michael@0: initArgs.CreateMutex = NULL; michael@0: initArgs.DestroyMutex = NULL; michael@0: initArgs.LockMutex = NULL; michael@0: initArgs.UnlockMutex = NULL; michael@0: initArgs.flags = CKF_OS_LOCKING_OK; michael@0: moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' " michael@0: "keyPrefix='%s' secmod='secmod.db' flags= ", michael@0: configDir, dbPrefix, dbPrefix); michael@0: initArgs.LibraryParameters = (CK_CHAR_PTR *) moduleSpec; michael@0: initArgs.pReserved = NULL; michael@0: michael@0: /*DebugBreak();*/ michael@0: /* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */ michael@0: /* NSS cryptographic module library initialization for the FIPS */ michael@0: /* Approved mode when FC_Initialize is envoked will perfom */ michael@0: /* software integrity test, and power-up self-tests before */ michael@0: /* FC_Initialize returns */ michael@0: crv = pFunctionList->C_Initialize(&initArgs); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Initialize succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Initialize failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: if (doForkTests) michael@0: { michael@0: /* Disable core on fork for this test, since we are testing the michael@0: * pathological case, and if enabled, the child process would dump michael@0: * core in C_GetTokenInfo . michael@0: * We can still differentiate the correct from incorrect behavior michael@0: * by the PKCS#11 return code. michael@0: */ michael@0: /* try to fork with softoken both loaded and initialized */ michael@0: crv = PKM_ForkCheck(CKR_DEVICE_ERROR, pFunctionList, PR_FALSE, NULL); michael@0: if (crv != CKR_OK) michael@0: goto cleanup; michael@0: } michael@0: michael@0: if (doForkTests) michael@0: { michael@0: /* In this next test, we fork and try to re-initialize softoken in michael@0: * the child. This should now work because softoken has the ability michael@0: * to hard reset. michael@0: */ michael@0: /* try to fork with softoken both loaded and initialized */ michael@0: crv = PKM_ForkCheck(CKR_OK, pFunctionList, PR_TRUE, &initArgs); michael@0: if (crv != CKR_OK) michael@0: goto cleanup; michael@0: } michael@0: michael@0: crv = PKM_ShowInfo(pFunctionList, slotID); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_ShowInfo succeeded\n"); michael@0: } else { michael@0: PKM_Error( "PKM_ShowInfo failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: pSlotList = PKM_GetSlotList(pFunctionList, slotID); michael@0: if (pSlotList == NULL) { michael@0: PKM_Error( "PKM_GetSlotList failed with \n"); michael@0: goto cleanup; michael@0: } michael@0: crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GetTokenInfo succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "C_GetTokenInfo failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: if (!(tokenInfo.flags & CKF_USER_PIN_INITIALIZED)) { michael@0: PKM_LogIt("Initing PW for DB\n"); michael@0: crv = PKM_InitPWforDB(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_InitPWforDB succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_InitPWforDB failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: } else { michael@0: PKM_LogIt("using existing DB\n"); michael@0: } michael@0: michael@0: /* general mechanism by token */ michael@0: crv = PKM_Mechanism(pFunctionList, pSlotList, slotID); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_Mechanism succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_Mechanism failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: /* RNG example without Login */ michael@0: crv = PKM_RNG(pFunctionList, pSlotList, slotID); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_RNG succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_RNG failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: crv = PKM_SessionLogin(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_SessionLogin succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_SessionLogin failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: /* michael@0: * PKM_KeyTest creates RSA,DSA public keys michael@0: * and AES, DES3 secret keys. michael@0: * then does digest, hmac, encrypt/decrypt, signing operations. michael@0: */ michael@0: crv = PKM_KeyTests(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_KeyTests succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_KeyTest failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: crv = PKM_SecretKey(pFunctionList, pSlotList, slotID, pwd, michael@0: pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_SecretKey succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_SecretKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: crv = PKM_PublicKey(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_PublicKey succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_PublicKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = PKM_OperationalState(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_OperationalState succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_OperationalState failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = PKM_MultiObjectManagement(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_MultiObjectManagement succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_MultiObjectManagement failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = PKM_LegacyFunctions(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_LegacyFunctions succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_LegacyFunctions failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = PKM_TLSKeyAndMacDerive(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen, michael@0: CKM_TLS_KEY_AND_MAC_DERIVE, CORRECT); michael@0: michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_TLSKeyAndMacDerive succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_TLSKeyAndMacDerive failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen, michael@0: CKM_TLS_MASTER_KEY_DERIVE, michael@0: CORRECT); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen, michael@0: CKM_TLS_MASTER_KEY_DERIVE_DH, michael@0: CORRECT); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = PKM_FindAllObjects(pFunctionList, pSlotList, slotID, michael@0: pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_FindAllObjects succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_FindAllObjects failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = pFunctionList->C_Finalize(NULL); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Finalize succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Finalize failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: if (doForkTests) michael@0: { michael@0: /* try to fork with softoken still loaded, but de-initialized */ michael@0: crv = PKM_ForkCheck(CKR_CRYPTOKI_NOT_INITIALIZED, pFunctionList, michael@0: PR_TRUE, NULL); michael@0: if (crv != CKR_OK) michael@0: goto cleanup; michael@0: } michael@0: michael@0: if (pSlotList) free(pSlotList); michael@0: michael@0: /* demonstrate how an application can be in Hybrid mode */ michael@0: /* PKM_HybridMode shows how to switch between NONFIPS */ michael@0: /* mode to FIPS mode */ michael@0: michael@0: PKM_LogIt("Testing Hybrid mode \n"); michael@0: crv = PKM_HybridMode(pwd, pwdLen, &initArgs); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_HybridMode succeeded\n"); michael@0: } else { michael@0: PKM_Error( "PKM_HybridMode failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: michael@0: if (doForkTests) { michael@0: /* testing one more C_Initialize / C_Finalize to exercise getpid() michael@0: * fork check code */ michael@0: crv = pFunctionList->C_Initialize(&initArgs); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Initialize succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Initialize failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: crv = pFunctionList->C_Finalize(NULL); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Finalize succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Finalize failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: goto cleanup; michael@0: } michael@0: /* try to C_Initialize / C_Finalize in child. This should succeed */ michael@0: crv = PKM_ForkCheck(CKR_OK, pFunctionList, PR_TRUE, &initArgs); michael@0: } michael@0: michael@0: PKM_LogIt("unloading NSS PKCS # 11 softoken and exiting\n"); michael@0: michael@0: cleanup: michael@0: michael@0: if (pwd) { michael@0: free(pwd); michael@0: } michael@0: if (configDir) { michael@0: free(configDir); michael@0: } michael@0: if (dbPrefix) { michael@0: free(dbPrefix); michael@0: } michael@0: if (moduleSpec) { michael@0: PR_smprintf_free(moduleSpec); michael@0: } michael@0: michael@0: #ifdef _WIN32 michael@0: FreeLibrary(hModule); michael@0: #else michael@0: disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD"); michael@0: if (!disableUnload) { michael@0: PR_UnloadLibrary(lib); michael@0: } michael@0: #endif michael@0: if (CKR_OK == crv && doForkTests && !disableUnload) { michael@0: /* try to fork with softoken both de-initialized and unloaded */ michael@0: crv = PKM_ForkCheck(123, NULL, PR_TRUE, NULL); michael@0: } michael@0: michael@0: printf("**** Total number of TESTS ran in %s is %d. ****\n", michael@0: ((MODE == FIPSMODE) ? "FIPS MODE" : "NON FIPS MODE"), (int) NUMTESTS); michael@0: if (CKR_OK == crv) { michael@0: printf("**** ALL TESTS PASSED ****\n"); michael@0: } michael@0: michael@0: return crv; michael@0: } michael@0: michael@0: /* michael@0: * PKM_KeyTests michael@0: * michael@0: * michael@0: */ michael@0: michael@0: CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: CK_SESSION_HANDLE hRwSession; michael@0: michael@0: CK_RV crv = CKR_OK; michael@0: michael@0: /*** DSA Key ***/ michael@0: CK_MECHANISM dsaParamGenMech; michael@0: CK_ULONG primeBits = 1024; michael@0: CK_ATTRIBUTE dsaParamGenTemplate[1]; michael@0: CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE; michael@0: CK_BYTE DSA_P[128]; michael@0: CK_BYTE DSA_Q[20]; michael@0: CK_BYTE DSA_G[128]; michael@0: CK_MECHANISM dsaKeyPairGenMech; michael@0: CK_ATTRIBUTE dsaPubKeyTemplate[5]; michael@0: CK_ATTRIBUTE dsaPrivKeyTemplate[5]; michael@0: CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE; michael@0: CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE; michael@0: michael@0: /**** RSA Key ***/ michael@0: CK_KEY_TYPE rsatype = CKK_RSA; michael@0: CK_MECHANISM rsaKeyPairGenMech; michael@0: CK_BYTE subject[] = {"RSA Private Key"}; michael@0: CK_ULONG modulusBits = 1024; michael@0: CK_BYTE publicExponent[] = {0x01, 0x00, 0x01}; michael@0: CK_BYTE id[] = {"RSA123"}; michael@0: CK_ATTRIBUTE rsaPubKeyTemplate[9]; michael@0: CK_ATTRIBUTE rsaPrivKeyTemplate[11]; michael@0: CK_OBJECT_HANDLE hRSApubKey = CK_INVALID_HANDLE; michael@0: CK_OBJECT_HANDLE hRSAprivKey = CK_INVALID_HANDLE; michael@0: michael@0: /*** AES Key ***/ michael@0: CK_MECHANISM sAESKeyMech = { michael@0: CKM_AES_KEY_GEN, NULL, 0 michael@0: }; michael@0: CK_OBJECT_CLASS class = CKO_SECRET_KEY; michael@0: CK_KEY_TYPE keyAESType = CKK_AES; michael@0: CK_UTF8CHAR AESlabel[] = "An AES secret key object"; michael@0: CK_ULONG AESvalueLen = 32; michael@0: CK_ATTRIBUTE sAESKeyTemplate[9]; michael@0: CK_OBJECT_HANDLE hAESSecKey; michael@0: michael@0: /*** DES3 Key ***/ michael@0: CK_KEY_TYPE keyDES3Type = CKK_DES3; michael@0: CK_UTF8CHAR DES3label[] = "An Triple DES secret key object"; michael@0: CK_ULONG DES3valueLen = 56; michael@0: CK_MECHANISM sDES3KeyGenMechanism = { michael@0: CKM_DES3_KEY_GEN, NULL, 0 michael@0: }; michael@0: CK_ATTRIBUTE sDES3KeyTemplate[9]; michael@0: CK_OBJECT_HANDLE hDES3SecKey; michael@0: michael@0: CK_MECHANISM dsaWithSha1Mech = { michael@0: CKM_DSA_SHA1, NULL, 0 michael@0: }; michael@0: michael@0: CK_BYTE IV[16]; michael@0: CK_MECHANISM mech_DES3_CBC; michael@0: CK_MECHANISM mech_DES3_CBC_PAD; michael@0: CK_MECHANISM mech_AES_CBC_PAD; michael@0: CK_MECHANISM mech_AES_CBC; michael@0: struct mech_str { michael@0: CK_ULONG mechanism; michael@0: const char *mechanismStr; michael@0: }; michael@0: michael@0: typedef struct mech_str mech_str; michael@0: michael@0: mech_str digestMechs[] = { michael@0: {CKM_SHA_1, "CKM_SHA_1 "}, michael@0: {CKM_SHA224, "CKM_SHA224"}, michael@0: {CKM_SHA256, "CKM_SHA256"}, michael@0: {CKM_SHA384, "CKM_SHA384"}, michael@0: {CKM_SHA512, "CKM_SHA512"} michael@0: }; michael@0: mech_str hmacMechs[] = { michael@0: {CKM_SHA_1_HMAC, "CKM_SHA_1_HMAC"}, michael@0: {CKM_SHA224_HMAC, "CKM_SHA224_HMAC"}, michael@0: {CKM_SHA256_HMAC, "CKM_SHA256_HMAC"}, michael@0: {CKM_SHA384_HMAC, "CKM_SHA384_HMAC"}, michael@0: {CKM_SHA512_HMAC, "CKM_SHA512_HMAC"} michael@0: }; michael@0: mech_str sigRSAMechs[] = { michael@0: {CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS"}, michael@0: {CKM_SHA224_RSA_PKCS, "CKM_SHA224_RSA_PKCS"}, michael@0: {CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS"}, michael@0: {CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS"}, michael@0: {CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS"} michael@0: }; michael@0: michael@0: CK_ULONG digestMechsSZ = NUM_ELEM(digestMechs); michael@0: CK_ULONG sigRSAMechsSZ = NUM_ELEM(sigRSAMechs); michael@0: CK_ULONG hmacMechsSZ = NUM_ELEM(hmacMechs); michael@0: CK_MECHANISM mech; michael@0: michael@0: unsigned int i; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* DSA key init */ michael@0: dsaParamGenMech.mechanism = CKM_DSA_PARAMETER_GEN; michael@0: dsaParamGenMech.pParameter = NULL_PTR; michael@0: dsaParamGenMech.ulParameterLen = 0; michael@0: dsaParamGenTemplate[0].type = CKA_PRIME_BITS; michael@0: dsaParamGenTemplate[0].pValue = &primeBits; michael@0: dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits); michael@0: dsaPubKeyTemplate[0].type = CKA_PRIME; michael@0: dsaPubKeyTemplate[0].pValue = DSA_P; michael@0: dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P); michael@0: dsaPubKeyTemplate[1].type = CKA_SUBPRIME; michael@0: dsaPubKeyTemplate[1].pValue = DSA_Q; michael@0: dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q); michael@0: dsaPubKeyTemplate[2].type = CKA_BASE; michael@0: dsaPubKeyTemplate[2].pValue = DSA_G; michael@0: dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G); michael@0: dsaPubKeyTemplate[3].type = CKA_TOKEN; michael@0: dsaPubKeyTemplate[3].pValue = &true; michael@0: dsaPubKeyTemplate[3].ulValueLen = sizeof(true); michael@0: dsaPubKeyTemplate[4].type = CKA_VERIFY; michael@0: dsaPubKeyTemplate[4].pValue = &true; michael@0: dsaPubKeyTemplate[4].ulValueLen = sizeof(true); michael@0: dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN; michael@0: dsaKeyPairGenMech.pParameter = NULL_PTR; michael@0: dsaKeyPairGenMech.ulParameterLen = 0; michael@0: dsaPrivKeyTemplate[0].type = CKA_TOKEN; michael@0: dsaPrivKeyTemplate[0].pValue = &true; michael@0: dsaPrivKeyTemplate[0].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[1].type = CKA_PRIVATE; michael@0: dsaPrivKeyTemplate[1].pValue = &true; michael@0: dsaPrivKeyTemplate[1].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[2].type = CKA_SENSITIVE; michael@0: dsaPrivKeyTemplate[2].pValue = &true; michael@0: dsaPrivKeyTemplate[2].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[3].type = CKA_SIGN, michael@0: dsaPrivKeyTemplate[3].pValue = &true; michael@0: dsaPrivKeyTemplate[3].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE; michael@0: dsaPrivKeyTemplate[4].pValue = &true; michael@0: dsaPrivKeyTemplate[4].ulValueLen = sizeof(true); michael@0: michael@0: /* RSA key init */ michael@0: rsaKeyPairGenMech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; michael@0: rsaKeyPairGenMech.pParameter = NULL_PTR; michael@0: rsaKeyPairGenMech.ulParameterLen = 0; michael@0: michael@0: rsaPubKeyTemplate[0].type = CKA_KEY_TYPE; michael@0: rsaPubKeyTemplate[0].pValue = &rsatype; michael@0: rsaPubKeyTemplate[0].ulValueLen = sizeof(rsatype); michael@0: rsaPubKeyTemplate[1].type = CKA_PRIVATE; michael@0: rsaPubKeyTemplate[1].pValue = &true; michael@0: rsaPubKeyTemplate[1].ulValueLen = sizeof(true); michael@0: rsaPubKeyTemplate[2].type = CKA_ENCRYPT; michael@0: rsaPubKeyTemplate[2].pValue = &true; michael@0: rsaPubKeyTemplate[2].ulValueLen = sizeof(true); michael@0: rsaPubKeyTemplate[3].type = CKA_DECRYPT; michael@0: rsaPubKeyTemplate[3].pValue = &true; michael@0: rsaPubKeyTemplate[3].ulValueLen = sizeof(true); michael@0: rsaPubKeyTemplate[4].type = CKA_VERIFY; michael@0: rsaPubKeyTemplate[4].pValue = &true; michael@0: rsaPubKeyTemplate[4].ulValueLen = sizeof(true); michael@0: rsaPubKeyTemplate[5].type = CKA_SIGN; michael@0: rsaPubKeyTemplate[5].pValue = &true; michael@0: rsaPubKeyTemplate[5].ulValueLen = sizeof(true); michael@0: rsaPubKeyTemplate[6].type = CKA_WRAP; michael@0: rsaPubKeyTemplate[6].pValue = &true; michael@0: rsaPubKeyTemplate[6].ulValueLen = sizeof(true); michael@0: rsaPubKeyTemplate[7].type = CKA_MODULUS_BITS; michael@0: rsaPubKeyTemplate[7].pValue = &modulusBits; michael@0: rsaPubKeyTemplate[7].ulValueLen = sizeof(modulusBits); michael@0: rsaPubKeyTemplate[8].type = CKA_PUBLIC_EXPONENT; michael@0: rsaPubKeyTemplate[8].pValue = publicExponent; michael@0: rsaPubKeyTemplate[8].ulValueLen = sizeof (publicExponent); michael@0: michael@0: rsaPrivKeyTemplate[0].type = CKA_KEY_TYPE; michael@0: rsaPrivKeyTemplate[0].pValue = &rsatype; michael@0: rsaPrivKeyTemplate[0].ulValueLen = sizeof(rsatype); michael@0: rsaPrivKeyTemplate[1].type = CKA_TOKEN; michael@0: rsaPrivKeyTemplate[1].pValue = &true; michael@0: rsaPrivKeyTemplate[1].ulValueLen = sizeof(true); michael@0: rsaPrivKeyTemplate[2].type = CKA_PRIVATE; michael@0: rsaPrivKeyTemplate[2].pValue = &true; michael@0: rsaPrivKeyTemplate[2].ulValueLen = sizeof(true); michael@0: rsaPrivKeyTemplate[3].type = CKA_SUBJECT; michael@0: rsaPrivKeyTemplate[3].pValue = subject; michael@0: rsaPrivKeyTemplate[3].ulValueLen = sizeof(subject); michael@0: rsaPrivKeyTemplate[4].type = CKA_ID; michael@0: rsaPrivKeyTemplate[4].pValue = id; michael@0: rsaPrivKeyTemplate[4].ulValueLen = sizeof(id); michael@0: rsaPrivKeyTemplate[5].type = CKA_SENSITIVE; michael@0: rsaPrivKeyTemplate[5].pValue = &true; michael@0: rsaPrivKeyTemplate[5].ulValueLen = sizeof(true); michael@0: rsaPrivKeyTemplate[6].type = CKA_ENCRYPT; michael@0: rsaPrivKeyTemplate[6].pValue = &true; michael@0: rsaPrivKeyTemplate[6].ulValueLen = sizeof(true); michael@0: rsaPrivKeyTemplate[7].type = CKA_DECRYPT; michael@0: rsaPrivKeyTemplate[7].pValue = &true; michael@0: rsaPrivKeyTemplate[7].ulValueLen = sizeof(true); michael@0: rsaPrivKeyTemplate[8].type = CKA_VERIFY; michael@0: rsaPrivKeyTemplate[8].pValue = &true; michael@0: rsaPrivKeyTemplate[8].ulValueLen = sizeof(true); michael@0: rsaPrivKeyTemplate[9].type = CKA_SIGN; michael@0: rsaPrivKeyTemplate[9].pValue = &true; michael@0: rsaPrivKeyTemplate[9].ulValueLen = sizeof(true); michael@0: rsaPrivKeyTemplate[10].type = CKA_UNWRAP; michael@0: rsaPrivKeyTemplate[10].pValue = &true; michael@0: rsaPrivKeyTemplate[10].ulValueLen = sizeof(true); michael@0: michael@0: /* AES key template */ michael@0: sAESKeyTemplate[0].type = CKA_CLASS; michael@0: sAESKeyTemplate[0].pValue = &class; michael@0: sAESKeyTemplate[0].ulValueLen = sizeof(class); michael@0: sAESKeyTemplate[1].type = CKA_KEY_TYPE; michael@0: sAESKeyTemplate[1].pValue = &keyAESType; michael@0: sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType); michael@0: sAESKeyTemplate[2].type = CKA_LABEL; michael@0: sAESKeyTemplate[2].pValue = AESlabel; michael@0: sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1; michael@0: sAESKeyTemplate[3].type = CKA_ENCRYPT; michael@0: sAESKeyTemplate[3].pValue = &true; michael@0: sAESKeyTemplate[3].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[4].type = CKA_DECRYPT; michael@0: sAESKeyTemplate[4].pValue = &true; michael@0: sAESKeyTemplate[4].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[5].type = CKA_SIGN; michael@0: sAESKeyTemplate[5].pValue = &true; michael@0: sAESKeyTemplate[5].ulValueLen = sizeof (true); michael@0: sAESKeyTemplate[6].type = CKA_VERIFY; michael@0: sAESKeyTemplate[6].pValue = &true; michael@0: sAESKeyTemplate[6].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[7].type = CKA_UNWRAP; michael@0: sAESKeyTemplate[7].pValue = &true; michael@0: sAESKeyTemplate[7].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[8].type = CKA_VALUE_LEN; michael@0: sAESKeyTemplate[8].pValue = &AESvalueLen; michael@0: sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen); michael@0: michael@0: /* DES3 key template */ michael@0: sDES3KeyTemplate[0].type = CKA_CLASS; michael@0: sDES3KeyTemplate[0].pValue = &class; michael@0: sDES3KeyTemplate[0].ulValueLen = sizeof(class); michael@0: sDES3KeyTemplate[1].type = CKA_KEY_TYPE; michael@0: sDES3KeyTemplate[1].pValue = &keyDES3Type; michael@0: sDES3KeyTemplate[1].ulValueLen = sizeof(keyDES3Type); michael@0: sDES3KeyTemplate[2].type = CKA_LABEL; michael@0: sDES3KeyTemplate[2].pValue = DES3label; michael@0: sDES3KeyTemplate[2].ulValueLen = sizeof(DES3label)-1; michael@0: sDES3KeyTemplate[3].type = CKA_ENCRYPT; michael@0: sDES3KeyTemplate[3].pValue = &true; michael@0: sDES3KeyTemplate[3].ulValueLen = sizeof(true); michael@0: sDES3KeyTemplate[4].type = CKA_DECRYPT; michael@0: sDES3KeyTemplate[4].pValue = &true; michael@0: sDES3KeyTemplate[4].ulValueLen = sizeof(true); michael@0: sDES3KeyTemplate[5].type = CKA_UNWRAP; michael@0: sDES3KeyTemplate[5].pValue = &true; michael@0: sDES3KeyTemplate[5].ulValueLen = sizeof(true); michael@0: sDES3KeyTemplate[6].type = CKA_SIGN, michael@0: sDES3KeyTemplate[6].pValue = &true; michael@0: sDES3KeyTemplate[6].ulValueLen = sizeof (true); michael@0: sDES3KeyTemplate[7].type = CKA_VERIFY; michael@0: sDES3KeyTemplate[7].pValue = &true; michael@0: sDES3KeyTemplate[7].ulValueLen = sizeof(true); michael@0: sDES3KeyTemplate[8].type = CKA_VALUE_LEN; michael@0: sDES3KeyTemplate[8].pValue = &DES3valueLen; michael@0: sDES3KeyTemplate[8].ulValueLen = sizeof(DES3valueLen); michael@0: michael@0: /* mech init */ michael@0: memset(IV, 0x01, sizeof(IV)); michael@0: mech_DES3_CBC.mechanism = CKM_DES3_CBC; michael@0: mech_DES3_CBC.pParameter = IV; michael@0: mech_DES3_CBC.ulParameterLen = sizeof(IV); michael@0: mech_DES3_CBC_PAD.mechanism = CKM_DES3_CBC_PAD; michael@0: mech_DES3_CBC_PAD.pParameter = IV; michael@0: mech_DES3_CBC_PAD.ulParameterLen = sizeof(IV); michael@0: mech_AES_CBC.mechanism = CKM_AES_CBC; michael@0: mech_AES_CBC.pParameter = IV; michael@0: mech_AES_CBC.ulParameterLen = sizeof(IV); michael@0: mech_AES_CBC_PAD.mechanism = CKM_AES_CBC_PAD; michael@0: mech_AES_CBC_PAD.pParameter = IV; michael@0: mech_AES_CBC_PAD.ulParameterLen = sizeof(IV); michael@0: michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], michael@0: CKF_RW_SESSION | CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hRwSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("Opening a read/write session succeeded\n"); michael@0: } else { michael@0: PKM_Error( "Opening a read/write session failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if (MODE == FIPSMODE) { michael@0: crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech, michael@0: sAESKeyTemplate, michael@0: NUM_ELEM(sAESKeyTemplate), michael@0: &hAESSecKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_Error("C_GenerateKey succeeded when not logged in.\n"); michael@0: return CKR_GENERAL_ERROR; michael@0: } else { michael@0: PKM_LogIt("C_GenerateKey returned as EXPECTED with 0x%08X, %-26s\n" michael@0: "since not logged in\n", crv, PKM_CK_RVtoStr(crv)); michael@0: } michael@0: crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech, michael@0: rsaPubKeyTemplate, michael@0: NUM_ELEM(rsaPubKeyTemplate), michael@0: rsaPrivKeyTemplate, michael@0: NUM_ELEM(rsaPrivKeyTemplate), michael@0: &hRSApubKey, &hRSAprivKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_Error("C_GenerateKeyPair succeeded when not logged in.\n"); michael@0: return CKR_GENERAL_ERROR; michael@0: } else { michael@0: PKM_LogIt("C_GenerateKeyPair returned as EXPECTED with 0x%08X, " michael@0: "%-26s\n since not logged in\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: } michael@0: } michael@0: michael@0: crv = pFunctionList->C_Login(hRwSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error("C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate an AES key ... \n"); michael@0: /* generate an AES Secret Key */ michael@0: crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech, michael@0: sAESKeyTemplate, michael@0: NUM_ELEM(sAESKeyTemplate), michael@0: &hAESSecKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateKey AES succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate an 3DES key ...\n"); michael@0: /* generate an 3DES Secret Key */ michael@0: crv = pFunctionList->C_GenerateKey(hRwSession, &sDES3KeyGenMechanism, michael@0: sDES3KeyTemplate, michael@0: NUM_ELEM(sDES3KeyTemplate), michael@0: &hDES3SecKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateKey DES3 succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate DSA PQG domain parameters ... \n"); michael@0: /* Generate DSA domain parameters PQG */ michael@0: crv = pFunctionList->C_GenerateKey(hRwSession, &dsaParamGenMech, michael@0: dsaParamGenTemplate, michael@0: 1, michael@0: &hDsaParams); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("DSA domain parameter generation succeeded\n"); michael@0: } else { michael@0: PKM_Error( "DSA domain parameter generation failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_GetAttributeValue(hRwSession, hDsaParams, michael@0: dsaPubKeyTemplate, 3); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("Getting DSA domain parameters succeeded\n"); michael@0: } else { michael@0: PKM_Error( "Getting DSA domain parameters failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_DestroyObject(hRwSession, hDsaParams); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("Destroying DSA domain parameters succeeded\n"); michael@0: } else { michael@0: PKM_Error( "Destroying DSA domain parameters failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate a DSA key pair ... \n"); michael@0: /* Generate a persistent DSA key pair */ michael@0: crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech, michael@0: dsaPubKeyTemplate, michael@0: NUM_ELEM(dsaPubKeyTemplate), michael@0: dsaPrivKeyTemplate, michael@0: NUM_ELEM(dsaPrivKeyTemplate), michael@0: &hDSApubKey, &hDSAprivKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("DSA key pair generation succeeded\n"); michael@0: } else { michael@0: PKM_Error( "DSA key pair generation failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate a RSA key pair ... \n"); michael@0: /*** GEN RSA Key ***/ michael@0: crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech, michael@0: rsaPubKeyTemplate, michael@0: NUM_ELEM(rsaPubKeyTemplate), michael@0: rsaPrivKeyTemplate, michael@0: NUM_ELEM(rsaPrivKeyTemplate), michael@0: &hRSApubKey, &hRSAprivKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateKeyPair created an RSA key pair. \n"); michael@0: } else { michael@0: PKM_Error("C_GenerateKeyPair failed to create an RSA key pair.\n" michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("**** Generation of keys completed ***** \n"); michael@0: michael@0: mech.mechanism = CKM_RSA_PKCS; michael@0: mech.pParameter = NULL; michael@0: mech.ulParameterLen = 0; michael@0: michael@0: crv = PKM_wrapUnwrap(pFunctionList, michael@0: hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: hAESSecKey, michael@0: sAESKeyTemplate, michael@0: NUM_ELEM(sAESKeyTemplate)); michael@0: michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap AES key " michael@0: "succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_wrapUnwrap using RSA keypair to wrap AES key failed " michael@0: "with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = PKM_wrapUnwrap(pFunctionList, michael@0: hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: hDES3SecKey, michael@0: sDES3KeyTemplate, michael@0: NUM_ELEM(sDES3KeyTemplate)); michael@0: michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap DES3 key " michael@0: "succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_wrapUnwrap using RSA keypair to wrap DES3 key " michael@0: "failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = PKM_SecKeyCrypt(pFunctionList, hRwSession, michael@0: hAESSecKey, &mech_AES_CBC_PAD, michael@0: PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_SecKeyCrypt succeeded \n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_SecKeyCrypt failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = PKM_SecKeyCrypt(pFunctionList, hRwSession, michael@0: hAESSecKey, &mech_AES_CBC, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_SecKeyCrypt AES succeeded \n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_SecKeyCrypt failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = PKM_SecKeyCrypt(pFunctionList, hRwSession, michael@0: hDES3SecKey, &mech_DES3_CBC, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n"); michael@0: } else { michael@0: PKM_Error( "PKM_SecKeyCrypt DES3 failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = PKM_SecKeyCrypt(pFunctionList, hRwSession, michael@0: hDES3SecKey, &mech_DES3_CBC_PAD, michael@0: PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_SecKeyCrypt DES3 failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: mech.mechanism = CKM_RSA_PKCS; michael@0: crv = PKM_RecoverFunctions(pFunctionList, hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_RecoverFunctions for CKM_RSA_PKCS succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_RecoverFunctions failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: mech.pParameter = NULL; michael@0: mech.ulParameterLen = 0; michael@0: michael@0: for (i=0; i < sigRSAMechsSZ; i++) { michael@0: michael@0: mech.mechanism = sigRSAMechs[i].mechanism; michael@0: michael@0: crv = PKM_PubKeySign(pFunctionList, hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_PubKeySign succeeded for %-10s\n\n", michael@0: sigRSAMechs[i].mechanismStr ); michael@0: } else { michael@0: PKM_Error( "PKM_PubKeySign failed for %-10s " michael@0: "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: hAESSecKey, &mech_AES_CBC, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded " michael@0: "for %-10s\n\n", michael@0: sigRSAMechs[i].mechanismStr ); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with AES secret key failed " michael@0: "for %-10s " michael@0: "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: hDES3SecKey, &mech_DES3_CBC, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded " michael@0: "for %-10s\n\n", michael@0: sigRSAMechs[i].mechanismStr ); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with DES3 secret key failed " michael@0: "for %-10s " michael@0: "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: hAESSecKey, &mech_AES_CBC_PAD, michael@0: PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD " michael@0: "succeeded for %-10s\n\n", michael@0: sigRSAMechs[i].mechanismStr ); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with AES secret key CBC_PAD " michael@0: "failed for %-10s " michael@0: "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hRSApubKey, hRSAprivKey, michael@0: &mech, michael@0: hDES3SecKey, &mech_DES3_CBC_PAD, michael@0: PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD " michael@0: "succeeded for %-10s\n\n", michael@0: sigRSAMechs[i].mechanismStr ); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with DES3 secret key CBC_PAD " michael@0: "failed for %-10s " michael@0: "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: } /* end of RSA for loop */ michael@0: michael@0: crv = PKM_PubKeySign(pFunctionList, hRwSession, michael@0: hDSApubKey, hDSAprivKey, michael@0: &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_PubKeySign for DSAwithSHA1 succeeded \n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_PubKeySign failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hDSApubKey, hDSAprivKey, michael@0: &dsaWithSha1Mech, michael@0: hAESSecKey, &mech_AES_CBC, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded " michael@0: "for DSAWithSHA1\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with AES secret key failed " michael@0: "for DSAWithSHA1 with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hDSApubKey, hDSAprivKey, michael@0: &dsaWithSha1Mech, michael@0: hDES3SecKey, &mech_DES3_CBC, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded " michael@0: "for DSAWithSHA1\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with DES3 secret key failed " michael@0: "for DSAWithSHA1 with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hDSApubKey, hDSAprivKey, michael@0: &dsaWithSha1Mech, michael@0: hAESSecKey, &mech_AES_CBC_PAD, michael@0: PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD succeeded " michael@0: "for DSAWithSHA1\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with AES secret key CBC_PAD failed " michael@0: "for DSAWithSHA1 with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncSign(pFunctionList, hRwSession, michael@0: hDSApubKey, hDSAprivKey, michael@0: &dsaWithSha1Mech, michael@0: hDES3SecKey, &mech_DES3_CBC_PAD, michael@0: PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD succeeded " michael@0: "for DSAWithSHA1\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign with DES3 secret key CBC_PAD failed " michael@0: "for DSAWithSHA1 with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: for (i=0; i < digestMechsSZ; i++) { michael@0: mech.mechanism = digestMechs[i].mechanism; michael@0: crv = PKM_Digest(pFunctionList, hRwSession, michael@0: &mech, hAESSecKey, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_Digest with AES secret key succeeded for %-10s\n\n", michael@0: digestMechs[i].mechanismStr); michael@0: } else { michael@0: PKM_Error( "PKM_Digest with AES secret key failed for " michael@0: "%-10s with 0x%08X, %-26s\n", michael@0: digestMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncDigest(pFunctionList, hRwSession, michael@0: hAESSecKey, &mech_AES_CBC, michael@0: 0,&mech, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncDigest with AES secret key succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncDigest with AES secret key " michael@0: "failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: } michael@0: michael@0: crv = PKM_Digest(pFunctionList, hRwSession, michael@0: &mech, hDES3SecKey, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_Digest with DES3 secret key succeeded for %-10s\n\n", michael@0: digestMechs[i].mechanismStr); michael@0: } else { michael@0: PKM_Error( "PKM_Digest with DES3 secret key failed for " michael@0: "%-10s with 0x%08X, %-26s\n", michael@0: digestMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_DualFuncDigest(pFunctionList, hRwSession, michael@0: hDES3SecKey, &mech_DES3_CBC, michael@0: 0,&mech, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_DualFuncDigest DES3 secret key succeeded\n\n"); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncDigest DES3 secret key " michael@0: "failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: } michael@0: michael@0: crv = PKM_Digest(pFunctionList, hRwSession, michael@0: &mech, 0, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_Digest with no secret key succeeded for %-10s\n\n", michael@0: digestMechs[i].mechanismStr ); michael@0: } else { michael@0: PKM_Error( "PKM_Digest with no secret key failed for %-10s " michael@0: "with 0x%08X, %-26s\n", digestMechs[i].mechanismStr, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: } /* end of digest loop */ michael@0: michael@0: for (i=0; i < hmacMechsSZ; i++) { michael@0: mech.mechanism = hmacMechs[i].mechanism; michael@0: crv = PKM_Hmac(pFunctionList, hRwSession, michael@0: hAESSecKey, &mech, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_Hmac with AES secret key succeeded for %-10s\n\n", michael@0: hmacMechs[i].mechanismStr); michael@0: } else { michael@0: PKM_Error( "PKM_Hmac with AES secret key failed for %-10s " michael@0: "with 0x%08X, %-26s\n", michael@0: hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: if ((MODE == FIPSMODE) && (mech.mechanism == CKM_SHA512_HMAC)) break; michael@0: crv = PKM_Hmac(pFunctionList, hRwSession, michael@0: hDES3SecKey, &mech, michael@0: PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_Hmac with DES3 secret key succeeded for %-10s\n\n", michael@0: hmacMechs[i].mechanismStr); michael@0: } else { michael@0: PKM_Error( "PKM_Hmac with DES3 secret key failed for %-10s " michael@0: "with 0x%08X, %-26s\n", michael@0: hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: } /* end of hmac loop */ michael@0: michael@0: crv = pFunctionList->C_Logout(hRwSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_CloseSession(hRwSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: void PKM_LogIt(const char *fmt, ...) { michael@0: va_list args; michael@0: michael@0: if (verbose) { michael@0: va_start (args, fmt); michael@0: if (MODE == FIPSMODE) { michael@0: printf("FIPS MODE: "); michael@0: } else if (MODE == NONFIPSMODE) { michael@0: printf("NON FIPS MODE: "); michael@0: } else if (MODE == HYBRIDMODE) { michael@0: printf("Hybrid MODE: "); michael@0: } michael@0: vprintf(fmt, args); michael@0: va_end(args); michael@0: } michael@0: } michael@0: michael@0: void PKM_Error(const char *fmt, ...) { michael@0: va_list args; michael@0: va_start (args, fmt); michael@0: michael@0: if (MODE == FIPSMODE) { michael@0: fprintf(stderr, "\nFIPS MODE PKM_Error: "); michael@0: } else if (MODE == NONFIPSMODE) { michael@0: fprintf(stderr, "NON FIPS MODE PKM_Error: "); michael@0: } else if (MODE == HYBRIDMODE) { michael@0: fprintf(stderr, "Hybrid MODE PKM_Error: "); michael@0: } else fprintf(stderr, "NOMODE PKM_Error: "); michael@0: vfprintf(stderr, fmt, args); michael@0: va_end(args); michael@0: } michael@0: CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_ULONG slotID) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_SLOT_ID *pSlotList = NULL; michael@0: CK_ULONG slotCount; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* Get slot list */ michael@0: crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */, michael@0: NULL, &slotCount); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_GetSlotList failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return NULL; michael@0: } michael@0: PKM_LogIt("C_GetSlotList reported there are %lu slots\n", slotCount); michael@0: pSlotList = (CK_SLOT_ID *)malloc(slotCount * sizeof(CK_SLOT_ID)); michael@0: if (!pSlotList) { michael@0: PKM_Error( "failed to allocate slot list\n"); michael@0: return NULL; michael@0: } michael@0: crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */, michael@0: pSlotList, &slotCount); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_GetSlotList failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: if (pSlotList) free(pSlotList); michael@0: return NULL; michael@0: } michael@0: return pSlotList; michael@0: } michael@0: michael@0: CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_SESSION_HANDLE hSession; michael@0: static const CK_UTF8CHAR testPin[] = {"0Mozilla"}; michael@0: static const CK_UTF8CHAR weakPin[] = {"mozilla"}; michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], michael@0: CKF_RW_SESSION | CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER); michael@0: michael@0: crv = pFunctionList->C_Login(hSession, CKU_SO, NULL, 0); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Login failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: if (MODE == FIPSMODE) { michael@0: crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *) weakPin, michael@0: strlen((char *)weakPin)); michael@0: if (crv == CKR_OK) { michael@0: PKM_Error( "C_InitPIN with a weak password succeeded\n"); michael@0: return crv; michael@0: } else { michael@0: PKM_LogIt("C_InitPIN with a weak password failed with " michael@0: "0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: } michael@0: } michael@0: crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *) testPin, michael@0: strlen((char *)testPin)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_InitPIN succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_InitPIN failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], michael@0: CKF_RW_SESSION | CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER); michael@0: michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, (CK_UTF8CHAR *) testPin, michael@0: strlen((const char *)testPin)); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Login failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: if (MODE == FIPSMODE) { michael@0: crv = pFunctionList->C_SetPIN( michael@0: hSession, (CK_UTF8CHAR *) testPin, michael@0: strlen((const char *)testPin), michael@0: (CK_UTF8CHAR *) weakPin, michael@0: strlen((const char *)weakPin)); michael@0: if (crv == CKR_OK) { michael@0: PKM_Error( "C_SetPIN with a weak password succeeded\n"); michael@0: return crv; michael@0: } else { michael@0: PKM_LogIt("C_SetPIN with a weak password returned with " michael@0: "0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: } michael@0: } michael@0: crv = pFunctionList->C_SetPIN( michael@0: hSession, (CK_UTF8CHAR *) testPin, michael@0: strlen((const char *)testPin), michael@0: pwd, pwdLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CSetPin failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: return crv; michael@0: } michael@0: michael@0: CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_INFO info; michael@0: CK_SLOT_ID *pSlotList = NULL; michael@0: unsigned i; michael@0: michael@0: CK_SLOT_INFO slotInfo; michael@0: CK_TOKEN_INFO tokenInfo; michael@0: CK_FLAGS bitflag; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: michael@0: crv = pFunctionList->C_GetInfo(&info); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GetInfo succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GetInfo failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_LogIt("General information about the PKCS #11 library:\n"); michael@0: PKM_LogIt(" PKCS #11 version: %d.%d\n", michael@0: (int)info.cryptokiVersion.major, michael@0: (int)info.cryptokiVersion.minor); michael@0: PKM_LogIt(" manufacturer ID: %.32s\n", info.manufacturerID); michael@0: PKM_LogIt(" flags: 0x%08lX\n", info.flags); michael@0: PKM_LogIt(" library description: %.32s\n", info.libraryDescription); michael@0: PKM_LogIt(" library version: %d.%d\n", michael@0: (int)info.libraryVersion.major, (int)info.libraryVersion.minor); michael@0: PKM_LogIt("\n"); michael@0: michael@0: /* Get slot list */ michael@0: pSlotList = PKM_GetSlotList(pFunctionList, slotID); michael@0: if (pSlotList == NULL) { michael@0: PKM_Error( "PKM_GetSlotList failed with \n"); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_GetSlotInfo(pSlotList[slotID], &slotInfo); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GetSlotInfo succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GetSlotInfo failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_LogIt("Information about slot %lu:\n", pSlotList[slotID]); michael@0: PKM_LogIt(" slot description: %.64s\n", slotInfo.slotDescription); michael@0: PKM_LogIt(" slot manufacturer ID: %.32s\n", slotInfo.manufacturerID); michael@0: PKM_LogIt(" flags: 0x%08lX\n", slotInfo.flags); michael@0: bitflag = 1; michael@0: for (i = 0; i < sizeof(slotFlagName)/sizeof(slotFlagName[0]); i++) { michael@0: if (slotInfo.flags & bitflag) { michael@0: PKM_LogIt(" %s\n", slotFlagName[i]); michael@0: } michael@0: bitflag <<= 1; michael@0: } michael@0: PKM_LogIt(" slot's hardware version number: %d.%d\n", michael@0: (int)slotInfo.hardwareVersion.major, michael@0: (int)slotInfo.hardwareVersion.minor); michael@0: PKM_LogIt(" slot's firmware version number: %d.%d\n", michael@0: (int)slotInfo.firmwareVersion.major, michael@0: (int)slotInfo.firmwareVersion.minor); michael@0: PKM_LogIt("\n"); michael@0: michael@0: crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GetTokenInfo succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GetTokenInfo failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_LogIt("Information about the token in slot %lu:\n", michael@0: pSlotList[slotID]); michael@0: PKM_LogIt(" label: %.32s\n", tokenInfo.label); michael@0: PKM_LogIt(" device manufacturer ID: %.32s\n", michael@0: tokenInfo.manufacturerID); michael@0: PKM_LogIt(" device model: %.16s\n", tokenInfo.model); michael@0: PKM_LogIt(" device serial number: %.16s\n", tokenInfo.serialNumber); michael@0: PKM_LogIt(" flags: 0x%08lX\n", tokenInfo.flags); michael@0: bitflag = 1; michael@0: for (i = 0; i < sizeof(tokenFlagName)/sizeof(tokenFlagName[0]); i++) { michael@0: if (tokenInfo.flags & bitflag) { michael@0: PKM_LogIt(" %s\n", tokenFlagName[i]); michael@0: } michael@0: bitflag <<= 1; michael@0: } michael@0: PKM_LogIt(" maximum session count: %lu\n", michael@0: tokenInfo.ulMaxSessionCount); michael@0: PKM_LogIt(" session count: %lu\n", tokenInfo.ulSessionCount); michael@0: PKM_LogIt(" maximum read/write session count: %lu\n", michael@0: tokenInfo.ulMaxRwSessionCount); michael@0: PKM_LogIt(" read/write session count: %lu\n", michael@0: tokenInfo.ulRwSessionCount); michael@0: PKM_LogIt(" maximum PIN length: %lu\n", tokenInfo.ulMaxPinLen); michael@0: PKM_LogIt(" minimum PIN length: %lu\n", tokenInfo.ulMinPinLen); michael@0: PKM_LogIt(" total public memory: %lu\n", michael@0: tokenInfo.ulTotalPublicMemory); michael@0: PKM_LogIt(" free public memory: %lu\n", michael@0: tokenInfo.ulFreePublicMemory); michael@0: PKM_LogIt(" total private memory: %lu\n", michael@0: tokenInfo.ulTotalPrivateMemory); michael@0: PKM_LogIt(" free private memory: %lu\n", michael@0: tokenInfo.ulFreePrivateMemory); michael@0: PKM_LogIt(" hardware version number: %d.%d\n", michael@0: (int)tokenInfo.hardwareVersion.major, michael@0: (int)tokenInfo.hardwareVersion.minor); michael@0: PKM_LogIt(" firmware version number: %d.%d\n", michael@0: (int)tokenInfo.firmwareVersion.major, michael@0: (int)tokenInfo.firmwareVersion.minor); michael@0: if (tokenInfo.flags & CKF_CLOCK_ON_TOKEN) { michael@0: PKM_LogIt(" current time: %.16s\n", tokenInfo.utcTime); michael@0: } michael@0: PKM_LogIt("PKM_ShowInfo done \n\n"); michael@0: if (pSlotList) free(pSlotList); michael@0: return crv; michael@0: } michael@0: michael@0: /* PKM_HybridMode */ michael@0: /* The NSS cryptographic module has two modes of operation: FIPS Approved */ michael@0: /* mode and NONFIPS Approved mode. The two modes of operation are */ michael@0: /* independent of each other -- they have their own copies of data */ michael@0: /* structures and they are even allowed to be active at the same time. */ michael@0: /* The module is FIPS 140-2 compliant only when the NONFIPS mode */ michael@0: /* is inactive. */ michael@0: /* PKM_HybridMode demostrates how an application can switch between the */ michael@0: /* two modes: FIPS Approved mode and NONFIPS mode. */ michael@0: CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, michael@0: CK_C_INITIALIZE_ARGS_NSS *initArgs) { michael@0: michael@0: CK_C_GetFunctionList pC_GetFunctionList; /* NONFIPSMode */ michael@0: CK_FUNCTION_LIST_PTR pC_FunctionList; michael@0: CK_SLOT_ID *pC_SlotList = NULL; michael@0: CK_ULONG slotID_C = 1; michael@0: CK_C_GetFunctionList pFC_GetFunctionList; /* FIPSMode */ michael@0: CK_FUNCTION_LIST_PTR pFC_FunctionList; michael@0: CK_SLOT_ID *pFC_SlotList = NULL; michael@0: CK_ULONG slotID_FC = 0; michael@0: CK_RV crv = CKR_OK; michael@0: CK_SESSION_HANDLE hSession; michael@0: int origMode = MODE; /* remember the orginal MODE value */ michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: MODE = NONFIPSMODE; michael@0: #ifdef _WIN32 michael@0: /* NON FIPS mode == C_GetFunctionList */ michael@0: pC_GetFunctionList = (CK_C_GetFunctionList) michael@0: GetProcAddress(hModule, "C_GetFunctionList"); michael@0: if (pC_GetFunctionList == NULL) { michael@0: PKM_Error( "cannot load %s\n", LIB_NAME); michael@0: return crv; michael@0: } michael@0: #else michael@0: pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib, michael@0: "C_GetFunctionList"); michael@0: assert(pC_GetFunctionList != NULL); michael@0: #endif michael@0: PKM_LogIt("loading C_GetFunctionList for Non FIPS Mode; slotID %d \n", michael@0: slotID_C); michael@0: crv = (*pC_GetFunctionList)(&pC_FunctionList); michael@0: assert(crv == CKR_OK); michael@0: michael@0: /* invoke C_Initialize as pC_FunctionList->C_Initialize */ michael@0: crv = pC_FunctionList->C_Initialize(initArgs); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Initialize succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Initialize failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: pC_SlotList = PKM_GetSlotList(pC_FunctionList, slotID_C); michael@0: if (pC_SlotList == NULL) { michael@0: PKM_Error( "PKM_GetSlotList failed with \n"); michael@0: return crv; michael@0: } michael@0: crv = pC_FunctionList->C_OpenSession(pC_SlotList[slotID_C], michael@0: CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("NONFIPS C_OpenSession succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_OpenSession failed for NONFIPS token " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("able to login in NONFIPS token\n"); michael@0: } else { michael@0: PKM_Error( "Unable to login in to NONFIPS token " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pC_FunctionList->C_Logout(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_ShowInfo(pC_FunctionList, slotID_C); michael@0: MODE = HYBRIDMODE; michael@0: michael@0: /* Now load the FIPS token */ michael@0: /* FIPS mode == FC_GetFunctionList */ michael@0: pFC_GetFunctionList = NULL; michael@0: #ifdef _WIN32 michael@0: pFC_GetFunctionList = (CK_C_GetFunctionList) michael@0: GetProcAddress(hModule, "FC_GetFunctionList"); michael@0: #else michael@0: pFC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib, michael@0: "FC_GetFunctionList"); michael@0: assert(pFC_GetFunctionList != NULL); michael@0: #endif michael@0: michael@0: PKM_LogIt("loading FC_GetFunctionList for FIPS Mode; slotID %d \n", michael@0: slotID_FC); michael@0: PKM_LogIt("pFC_FunctionList->C_Foo == pFC_FunctionList->FC_Foo\n"); michael@0: if (pFC_GetFunctionList == NULL) { michael@0: PKM_Error( "unable to load pFC_GetFunctionList\n"); michael@0: return crv; michael@0: } michael@0: michael@0: crv = (*pFC_GetFunctionList)(&pFC_FunctionList); michael@0: assert(crv == CKR_OK); michael@0: michael@0: /* invoke FC_Initialize as pFunctionList->C_Initialize */ michael@0: crv = pFC_FunctionList->C_Initialize(initArgs); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("FC_Initialize succeeded\n"); michael@0: } else { michael@0: PKM_Error( "FC_Initialize failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_ShowInfo(pFC_FunctionList, slotID_FC); michael@0: michael@0: pFC_SlotList = PKM_GetSlotList(pFC_FunctionList, slotID_FC); michael@0: if (pFC_SlotList == NULL) { michael@0: PKM_Error( "PKM_GetSlotList failed with \n"); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_LogIt("NONFIPS token cannot log in when FIPS token is loaded\n"); michael@0: } else { michael@0: PKM_Error("Able to login in to NONFIPS token\n"); michael@0: return crv; michael@0: } michael@0: crv = pC_FunctionList->C_CloseSession(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("NONFIPS pC_CloseSession succeeded\n"); michael@0: } else { michael@0: PKM_Error( "pC_CloseSession failed for NONFIPS token " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("The module is FIPS 140-2 compliant\n" michael@0: "only when the NONFIPS Approved mode is inactive by \n" michael@0: "calling C_Finalize on the NONFIPS token.\n"); michael@0: michael@0: michael@0: /* to go in FIPSMODE you must Finalize the NONFIPS mode pointer */ michael@0: crv = pC_FunctionList->C_Finalize(NULL); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Finalize of NONFIPS Token succeeded\n"); michael@0: MODE = FIPSMODE; michael@0: } else { michael@0: PKM_Error( "C_Finalize of NONFIPS Token failed with " michael@0: "0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("*** In FIPS mode! ***\n"); michael@0: michael@0: /* could do some operations in FIPS MODE */ michael@0: michael@0: crv = pFC_FunctionList->C_Finalize(NULL); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("Exiting FIPSMODE by caling FC_Finalize.\n"); michael@0: MODE = NOMODE; michael@0: } else { michael@0: PKM_Error( "FC_Finalize failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if (pC_SlotList) free(pC_SlotList); michael@0: if (pFC_SlotList) free(pFC_SlotList); michael@0: michael@0: MODE = origMode; /* set the mode back to the orginal Mode value */ michael@0: PKM_LogIt("PKM_HybridMode test Completed\n\n"); michael@0: return crv; michael@0: } michael@0: michael@0: CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID) { michael@0: michael@0: CK_RV crv = CKR_OK; michael@0: CK_MECHANISM_TYPE *pMechanismList; michael@0: CK_ULONG mechanismCount; michael@0: CK_ULONG i; michael@0: const char * mechName = NULL; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* Get the mechanism list */ michael@0: crv = pFunctionList->C_GetMechanismList(pSlotList[slotID], michael@0: NULL, &mechanismCount); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_GetMechanismList failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_LogIt("C_GetMechanismList reported there are %lu mechanisms\n", michael@0: mechanismCount); michael@0: pMechanismList = (CK_MECHANISM_TYPE *) michael@0: malloc(mechanismCount * sizeof(CK_MECHANISM_TYPE)); michael@0: if (!pMechanismList) { michael@0: PKM_Error( "failed to allocate mechanism list\n"); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_GetMechanismList(pSlotList[slotID], michael@0: pMechanismList, &mechanismCount); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_GetMechanismList failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_LogIt("C_GetMechanismList returned the mechanism types:\n"); michael@0: if (verbose) { michael@0: for (i = 1; i <= mechanismCount; i++) { michael@0: mechName = getName(pMechanismList[(i-1)], ConstMechanism); michael@0: michael@0: /* output two mechanism name on each line */ michael@0: /* currently the longest known mechansim name length is 37 */ michael@0: if (mechName) { michael@0: printf("%-40s",mechName); michael@0: } else { michael@0: printf("Unknown mechanism: 0x%08lX ", pMechanismList[i]); michael@0: } michael@0: if ((i != 0) && ((i % 2) == 0 )) printf("\n"); michael@0: } michael@0: printf("\n\n"); michael@0: } michael@0: michael@0: for ( i = 0; i < mechanismCount; i++ ) { michael@0: CK_MECHANISM_INFO minfo; michael@0: michael@0: memset(&minfo, 0, sizeof(CK_MECHANISM_INFO)); michael@0: crv = pFunctionList->C_GetMechanismInfo(pSlotList[slotID], michael@0: pMechanismList[i], &minfo); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_GetMechanismInfo(%lu, %lu) returned 0x%08X, %-26s\n", michael@0: pSlotList[slotID], pMechanismList[i], crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: mechName = getName(pMechanismList[i], ConstMechanism); michael@0: if (!mechName) mechName = "Unknown mechanism"; michael@0: PKM_LogIt( " [%lu]: CK_MECHANISM_TYPE = %s 0x%08lX\n", (i+1), michael@0: mechName, michael@0: pMechanismList[i]); michael@0: PKM_LogIt( " ulMinKeySize = %lu\n", minfo.ulMinKeySize); michael@0: PKM_LogIt( " ulMaxKeySize = %lu\n", minfo.ulMaxKeySize); michael@0: PKM_LogIt( " flags = 0x%08x\n", minfo.flags); michael@0: PKM_LogIt( " -> HW = %s\n", minfo.flags & CKF_HW ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> SIGN = %s\n", minfo.flags & CKF_SIGN ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> SIGN_RECOVER = %s\n", minfo.flags & michael@0: CKF_SIGN_RECOVER ? "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> VERIFY_RECOVER = %s\n", michael@0: minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> GENERATE_KEY_PAIR = %s\n", michael@0: minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> WRAP = %s\n", minfo.flags & CKF_WRAP ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? michael@0: "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? michael@0: "TRUE" : "FALSE"); michael@0: michael@0: PKM_LogIt( "\n"); michael@0: } michael@0: michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID * pSlotList, michael@0: CK_ULONG slotID) { michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv = CKR_OK; michael@0: CK_BYTE randomData[16]; michael@0: CK_BYTE seed[] = {0x01, 0x03, 0x35, 0x55, 0xFF}; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_GenerateRandom(hSession, michael@0: randomData, sizeof randomData); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateRandom without login succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateRandom without login failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_SeedRandom(hSession, seed, sizeof(seed)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_SeedRandom without login succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_SeedRandom without login failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_GenerateRandom(hSession, michael@0: randomData, sizeof randomData); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateRandom without login succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateRandom without login failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID *pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv = CKR_OK; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *) michael@0: "netscape", 8); michael@0: if (crv == CKR_OK) { michael@0: PKM_Error("C_Login with wrong password succeeded\n"); michael@0: return CKR_FUNCTION_FAILED; michael@0: } else { michael@0: PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, " michael@0: "%-26s.\n ", crv, PKM_CK_RVtoStr(crv)); michael@0: } michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *) michael@0: "red hat", 7); michael@0: if (crv == CKR_OK) { michael@0: PKM_Error("C_Login with wrong password succeeded\n"); michael@0: return CKR_FUNCTION_FAILED; michael@0: } else { michael@0: PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, " michael@0: "%-26s.\n ", crv, PKM_CK_RVtoStr(crv)); michael@0: } michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, michael@0: (unsigned char *) "sun", 3); michael@0: if (crv == CKR_OK) { michael@0: PKM_Error("C_Login with wrong password succeeded\n"); michael@0: return CKR_FUNCTION_FAILED; michael@0: } else { michael@0: PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, " michael@0: "%-26s.\n ", crv, PKM_CK_RVtoStr(crv)); michael@0: } michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error("C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: /* michael@0: * PKM_LegacyFunctions michael@0: * michael@0: * Legacyfunctions exist only for backwards compatibility. michael@0: * C_GetFunctionStatus and C_CancelFunction functions were michael@0: * meant for managing parallel execution of cryptographic functions. michael@0: * michael@0: * C_GetFunctionStatus is a legacy function which should simply return michael@0: * the value CKR_FUNCTION_NOT_PARALLEL. michael@0: * michael@0: * C_CancelFunction is a legacy function which should simply return the michael@0: * value CKR_FUNCTION_NOT_PARALLEL. michael@0: * michael@0: */ michael@0: CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv = CKR_OK; michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_GetFunctionStatus(hSession); michael@0: if (crv == CKR_FUNCTION_NOT_PARALLEL) { michael@0: PKM_LogIt("C_GetFunctionStatus correctly" michael@0: "returned CKR_FUNCTION_NOT_PARALLEL \n"); michael@0: } else { michael@0: PKM_Error( "C_GetFunctionStatus failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_CancelFunction(hSession); michael@0: if (crv == CKR_FUNCTION_NOT_PARALLEL) { michael@0: PKM_LogIt("C_CancelFunction correctly " michael@0: "returned CKR_FUNCTION_NOT_PARALLEL \n"); michael@0: } else { michael@0: PKM_Error( "C_CancelFunction failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: /* michael@0: * PKM_DualFuncDigest - demostrates the Dual-function michael@0: * cryptograpic functions: michael@0: * michael@0: * C_DigestEncryptUpdate - multi-part Digest and Encrypt michael@0: * C_DecryptDigestUpdate - multi-part Decrypt and Digest michael@0: * michael@0: * michael@0: */ michael@0: michael@0: CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech, michael@0: CK_OBJECT_HANDLE hSecKeyDigest, michael@0: CK_MECHANISM *digestMech, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_BYTE eDigest[MAX_DIGEST_SZ]; michael@0: CK_BYTE dDigest[MAX_DIGEST_SZ]; michael@0: CK_ULONG ulDigestLen; michael@0: CK_BYTE ciphertext[MAX_CIPHER_SZ]; michael@0: CK_ULONG ciphertextLen, lastLen; michael@0: CK_BYTE plaintext[MAX_DATA_SZ]; michael@0: CK_ULONG plaintextLen; michael@0: unsigned int i; michael@0: michael@0: memset(eDigest, 0, sizeof(eDigest)); michael@0: memset(dDigest, 0, sizeof(dDigest)); michael@0: memset(ciphertext, 0, sizeof(ciphertext)); michael@0: memset(plaintext, 0, sizeof(plaintext)); michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* michael@0: * First init the Digest and Ecrypt operations michael@0: */ michael@0: crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSecKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_DigestInit(hSession, digestMech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: ciphertextLen = sizeof(ciphertext); michael@0: crv = pFunctionList->C_DigestEncryptUpdate(hSession, (CK_BYTE * ) pData, michael@0: pDataLen, michael@0: ciphertext, &ciphertextLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestEncryptUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: ulDigestLen = sizeof(eDigest); michael@0: crv = pFunctionList->C_DigestFinal(hSession, eDigest, &ulDigestLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: /* get the last piece of ciphertext (length should be 0 */ michael@0: lastLen = sizeof(ciphertext) - ciphertextLen; michael@0: crv = pFunctionList->C_EncryptFinal(hSession, michael@0: (CK_BYTE * )&ciphertext[ciphertextLen], michael@0: &lastLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: ciphertextLen = ciphertextLen + lastLen; michael@0: if (verbose) { michael@0: printf("ciphertext = "); michael@0: for (i = 0; i < ciphertextLen; i++) { michael@0: printf("%02x", (unsigned)ciphertext[i]); michael@0: } michael@0: printf("\n"); michael@0: printf("eDigest = "); michael@0: for (i = 0; i < ulDigestLen; i++) { michael@0: printf("%02x", (unsigned)eDigest[i]); michael@0: } michael@0: printf("\n"); michael@0: } michael@0: michael@0: /* Decrypt the text */ michael@0: crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSecKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_DigestInit(hSession, digestMech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: plaintextLen = sizeof(plaintext); michael@0: crv = pFunctionList->C_DecryptDigestUpdate(hSession, ciphertext, michael@0: ciphertextLen, michael@0: plaintext, michael@0: &plaintextLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptDigestUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: lastLen = sizeof(plaintext) - plaintextLen; michael@0: michael@0: crv = pFunctionList->C_DecryptFinal(hSession, michael@0: (CK_BYTE * )&plaintext[plaintextLen], michael@0: &lastLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: plaintextLen = plaintextLen + lastLen; michael@0: michael@0: ulDigestLen = sizeof(dDigest); michael@0: crv = pFunctionList->C_DigestFinal(hSession, dDigest, &ulDigestLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if (plaintextLen != pDataLen) { michael@0: PKM_Error( "plaintextLen is %lu\n", plaintextLen); michael@0: return crv; michael@0: } michael@0: michael@0: if (verbose) { michael@0: printf("plaintext = "); michael@0: for (i = 0; i < plaintextLen; i++) { michael@0: printf("%02x", (unsigned)plaintext[i]); michael@0: } michael@0: printf("\n"); michael@0: printf("dDigest = "); michael@0: for (i = 0; i < ulDigestLen; i++) { michael@0: printf("%02x", (unsigned)dDigest[i]); michael@0: } michael@0: printf("\n"); michael@0: } michael@0: michael@0: if (memcmp(eDigest, dDigest, ulDigestLen) == 0) { michael@0: PKM_LogIt("Encrypted Digest equals Decrypted Digest\n"); michael@0: } else { michael@0: PKM_Error( "Digests don't match\n"); michael@0: } michael@0: michael@0: if ((plaintextLen == pDataLen) && michael@0: (memcmp(plaintext, pData, pDataLen)) == 0) { michael@0: PKM_LogIt("DualFuncDigest decrypt test case passed\n"); michael@0: } else { michael@0: PKM_Error( "DualFuncDigest derypt test case failed\n"); michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: /* michael@0: * PKM_SecKeyCrypt - Symmetric key encrypt/decyprt michael@0: * michael@0: */ michael@0: michael@0: CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech, michael@0: const CK_BYTE * pData, CK_ULONG dataLen) { michael@0: CK_RV crv = CKR_OK; michael@0: michael@0: CK_BYTE cipher1[MAX_CIPHER_SZ]; michael@0: CK_BYTE cipher2[MAX_CIPHER_SZ]; michael@0: CK_BYTE data1[MAX_DATA_SZ]; michael@0: CK_BYTE data2[MAX_DATA_SZ]; michael@0: CK_ULONG cipher1Len =0, cipher2Len =0, lastLen =0; michael@0: CK_ULONG data1Len =0, data2Len =0; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: memset(cipher1, 0, sizeof(cipher1)); michael@0: memset(cipher2, 0, sizeof(cipher2)); michael@0: memset(data1, 0, sizeof(data1)); michael@0: memset(data2, 0, sizeof(data2)); michael@0: michael@0: /* C_Encrypt */ michael@0: crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: cipher1Len = sizeof(cipher1); michael@0: crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE * ) pData, dataLen, michael@0: cipher1, &cipher1Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* C_EncryptUpdate */ michael@0: crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: cipher2Len = sizeof(cipher2); michael@0: crv = pFunctionList->C_EncryptUpdate (hSession, (CK_BYTE * ) pData, michael@0: dataLen, michael@0: cipher2, &cipher2Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: lastLen = sizeof(cipher2) - cipher2Len; michael@0: michael@0: crv = pFunctionList->C_EncryptFinal(hSession, michael@0: (CK_BYTE * )&cipher2[cipher2Len], michael@0: &lastLen); michael@0: cipher2Len = cipher2Len + lastLen; michael@0: michael@0: if ( (cipher1Len == cipher2Len) && michael@0: (memcmp(cipher1, cipher2, sizeof(cipher1Len)) == 0) ) { michael@0: PKM_LogIt("encrypt test case passed\n"); michael@0: } else { michael@0: PKM_Error( "encrypt test case failed\n"); michael@0: return CKR_GENERAL_ERROR; michael@0: } michael@0: michael@0: /* C_Decrypt */ michael@0: crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: data1Len = sizeof(data1); michael@0: crv = pFunctionList->C_Decrypt(hSession, cipher1, cipher1Len, michael@0: data1, &data1Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: /* now use C_DecryptUpdate the text */ michael@0: crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: data2Len = sizeof(data2); michael@0: crv = pFunctionList->C_DecryptUpdate(hSession, cipher2, michael@0: cipher2Len, michael@0: data2, &data2Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: lastLen = sizeof(data2) - data2Len; michael@0: crv = pFunctionList->C_DecryptFinal(hSession, michael@0: (CK_BYTE * )&data2[data2Len], michael@0: &lastLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: data2Len = data2Len + lastLen; michael@0: michael@0: michael@0: /* Comparison of Decrypt data */ michael@0: michael@0: if ( (data1Len == data2Len) && (dataLen == data1Len) && michael@0: (memcmp(data1, pData, dataLen) == 0) && michael@0: (memcmp(data2, pData, dataLen) == 0) ) { michael@0: PKM_LogIt("decrypt test case passed\n"); michael@0: } else { michael@0: PKM_Error( "derypt test case failed\n"); michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: michael@0: CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv = CKR_OK; michael@0: CK_MECHANISM sAESKeyMech = { michael@0: CKM_AES_KEY_GEN, NULL, 0 michael@0: }; michael@0: CK_OBJECT_CLASS class = CKO_SECRET_KEY; michael@0: CK_KEY_TYPE keyAESType = CKK_AES; michael@0: CK_UTF8CHAR AESlabel[] = "An AES secret key object"; michael@0: CK_ULONG AESvalueLen = 16; michael@0: CK_ATTRIBUTE sAESKeyTemplate[9]; michael@0: CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; michael@0: michael@0: CK_BYTE KEY[16]; michael@0: CK_BYTE IV[16]; michael@0: static const CK_BYTE CIPHERTEXT[] = { michael@0: 0x7e,0x6a,0x3f,0x3b,0x39,0x3c,0xf2,0x4b, michael@0: 0xce,0xcc,0x23,0x6d,0x80,0xfd,0xe0,0xff michael@0: }; michael@0: CK_BYTE ciphertext[64]; michael@0: CK_BYTE ciphertext2[64]; michael@0: CK_ULONG ciphertextLen, ciphertext2Len, lastLen; michael@0: CK_BYTE plaintext[32]; michael@0: CK_BYTE plaintext2[32]; michael@0: CK_ULONG plaintextLen, plaintext2Len; michael@0: CK_BYTE wrappedKey[16]; michael@0: CK_ULONG wrappedKeyLen; michael@0: CK_MECHANISM aesEcbMech = { michael@0: CKM_AES_ECB, NULL, 0 michael@0: }; michael@0: CK_OBJECT_HANDLE hTestKey; michael@0: CK_MECHANISM mech_AES_CBC; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: memset(ciphertext, 0, sizeof(ciphertext)); michael@0: memset(ciphertext2, 0, sizeof(ciphertext2)); michael@0: memset(IV, 0x00, sizeof(IV)); michael@0: memset(KEY, 0x00, sizeof(KEY)); michael@0: michael@0: mech_AES_CBC.mechanism = CKM_AES_CBC; michael@0: mech_AES_CBC.pParameter = IV; michael@0: mech_AES_CBC.ulParameterLen = sizeof(IV); michael@0: michael@0: /* AES key template */ michael@0: sAESKeyTemplate[0].type = CKA_CLASS; michael@0: sAESKeyTemplate[0].pValue = &class; michael@0: sAESKeyTemplate[0].ulValueLen = sizeof(class); michael@0: sAESKeyTemplate[1].type = CKA_KEY_TYPE; michael@0: sAESKeyTemplate[1].pValue = &keyAESType; michael@0: sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType); michael@0: sAESKeyTemplate[2].type = CKA_LABEL; michael@0: sAESKeyTemplate[2].pValue = AESlabel; michael@0: sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1; michael@0: sAESKeyTemplate[3].type = CKA_ENCRYPT; michael@0: sAESKeyTemplate[3].pValue = &true; michael@0: sAESKeyTemplate[3].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[4].type = CKA_DECRYPT; michael@0: sAESKeyTemplate[4].pValue = &true; michael@0: sAESKeyTemplate[4].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[5].type = CKA_SIGN; michael@0: sAESKeyTemplate[5].pValue = &true; michael@0: sAESKeyTemplate[5].ulValueLen = sizeof (true); michael@0: sAESKeyTemplate[6].type = CKA_VERIFY; michael@0: sAESKeyTemplate[6].pValue = &true; michael@0: sAESKeyTemplate[6].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[7].type = CKA_UNWRAP; michael@0: sAESKeyTemplate[7].pValue = &true; michael@0: sAESKeyTemplate[7].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[8].type = CKA_VALUE_LEN; michael@0: sAESKeyTemplate[8].pValue = &AESvalueLen; michael@0: sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen); michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate an AES key ... \n"); michael@0: /* generate an AES Secret Key */ michael@0: crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech, michael@0: sAESKeyTemplate, michael@0: NUM_ELEM(sAESKeyTemplate), michael@0: &hKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateKey AES succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_EncryptInit(hSession, &aesEcbMech, hKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: wrappedKeyLen = sizeof(wrappedKey); michael@0: crv = pFunctionList->C_Encrypt(hSession, KEY, sizeof(KEY), michael@0: wrappedKey, &wrappedKeyLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: if (wrappedKeyLen != sizeof(wrappedKey)) { michael@0: PKM_Error( "wrappedKeyLen is %lu\n", wrappedKeyLen); michael@0: return crv; michael@0: } michael@0: /* Import an encrypted key */ michael@0: crv = pFunctionList->C_UnwrapKey(hSession, &aesEcbMech, hKey, michael@0: wrappedKey, wrappedKeyLen, michael@0: sAESKeyTemplate, michael@0: NUM_ELEM(sAESKeyTemplate), michael@0: &hTestKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_UnwraPKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: /* AES Encrypt the text */ michael@0: crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: ciphertextLen = sizeof(ciphertext); michael@0: crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE *) PLAINTEXT, michael@0: sizeof(PLAINTEXT), michael@0: ciphertext, &ciphertextLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if ( (ciphertextLen == sizeof(CIPHERTEXT)) && michael@0: (memcmp(ciphertext, CIPHERTEXT, ciphertextLen) == 0)) { michael@0: PKM_LogIt("AES CBCVarKey128 encrypt test case 1 passed\n"); michael@0: } else { michael@0: PKM_Error( "AES CBCVarKey128 encrypt test case 1 failed\n"); michael@0: return crv; michael@0: } michael@0: michael@0: /* now use EncryptUpdate the text */ michael@0: crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: ciphertext2Len = sizeof(ciphertext2); michael@0: crv = pFunctionList->C_EncryptUpdate (hSession, (CK_BYTE *) PLAINTEXT, michael@0: sizeof(PLAINTEXT), michael@0: ciphertext2, &ciphertext2Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: lastLen = sizeof(ciphertext2) - ciphertext2Len; michael@0: michael@0: crv = pFunctionList->C_EncryptFinal(hSession, michael@0: (CK_BYTE * )&ciphertext2[ciphertext2Len], michael@0: &lastLen); michael@0: ciphertext2Len = ciphertext2Len + lastLen; michael@0: michael@0: if ( (ciphertextLen == ciphertext2Len) && michael@0: (memcmp(ciphertext, ciphertext2, sizeof(CIPHERTEXT)) == 0) && michael@0: (memcmp(ciphertext2, CIPHERTEXT, sizeof(CIPHERTEXT)) == 0)) { michael@0: PKM_LogIt("AES CBCVarKey128 encrypt test case 2 passed\n"); michael@0: } else { michael@0: PKM_Error( "AES CBCVarKey128 encrypt test case 2 failed\n"); michael@0: return CKR_GENERAL_ERROR; michael@0: } michael@0: michael@0: /* AES CBC Decrypt the text */ michael@0: crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: plaintextLen = sizeof(plaintext); michael@0: crv = pFunctionList->C_Decrypt(hSession, ciphertext, ciphertextLen, michael@0: plaintext, &plaintextLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: if ((plaintextLen == sizeof(PLAINTEXT)) michael@0: && (memcmp(plaintext, PLAINTEXT, plaintextLen) == 0)) { michael@0: PKM_LogIt("AES CBCVarKey128 decrypt test case 1 passed\n"); michael@0: } else { michael@0: PKM_Error( "AES CBCVarKey128 derypt test case 1 failed\n"); michael@0: } michael@0: /* now use DecryptUpdate the text */ michael@0: crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: plaintext2Len = sizeof(plaintext2); michael@0: crv = pFunctionList->C_DecryptUpdate(hSession, ciphertext2, michael@0: ciphertext2Len, michael@0: plaintext2, &plaintext2Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: lastLen = sizeof(plaintext2) - plaintext2Len; michael@0: crv = pFunctionList->C_DecryptFinal(hSession, michael@0: (CK_BYTE * )&plaintext2[plaintext2Len], michael@0: &lastLen); michael@0: plaintext2Len = plaintext2Len + lastLen; michael@0: michael@0: if ( (plaintextLen == plaintext2Len) && michael@0: (memcmp(plaintext, plaintext2, plaintext2Len) == 0) && michael@0: (memcmp(plaintext2, PLAINTEXT, sizeof(PLAINTEXT)) == 0)) { michael@0: PKM_LogIt("AES CBCVarKey128 decrypt test case 2 passed\n"); michael@0: } else { michael@0: PKM_Error( "AES CBCVarKey128 decrypt test case 2 failed\n"); michael@0: return CKR_GENERAL_ERROR; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hRwSession, michael@0: CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey, michael@0: CK_MECHANISM *signMech, const CK_BYTE * pData, michael@0: CK_ULONG pDataLen) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_BYTE sig[MAX_SIG_SZ]; michael@0: CK_ULONG sigLen = 0 ; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: memset(sig, 0, sizeof(sig)); michael@0: michael@0: /* C_Sign */ michael@0: crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: sigLen = sizeof(sig); michael@0: crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE * ) pData, pDataLen, michael@0: sig, &sigLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* C_Verify the signature */ michael@0: crv = pFunctionList->C_VerifyInit(hRwSession, signMech, hPubKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Verify(hRwSession, (CK_BYTE * ) pData, pDataLen, michael@0: sig, sigLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Verify succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Check that the mechanism is Multi-part */ michael@0: if (signMech->mechanism == CKM_DSA || michael@0: signMech->mechanism == CKM_RSA_PKCS) { michael@0: return crv; michael@0: } michael@0: michael@0: memset(sig, 0, sizeof(sig)); michael@0: /* SignUpdate */ michael@0: crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_SignInit failed with 0x%08lX %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_SignUpdate(hRwSession, (CK_BYTE * ) pData, pDataLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Sign failed with 0x%08lX %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: sigLen = sizeof(sig); michael@0: crv = pFunctionList->C_SignFinal(hRwSession, sig, &sigLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* C_VerifyUpdate the signature */ michael@0: crv = pFunctionList->C_VerifyInit(hRwSession, signMech, michael@0: hPubKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyUpdate(hRwSession, (CK_BYTE * ) pData, michael@0: pDataLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyFinal(hRwSession, sig, sigLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyFinal succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, michael@0: CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, michael@0: CK_ULONG pwdLen){ michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv = CKR_OK; michael@0: michael@0: /*** DSA Key ***/ michael@0: CK_MECHANISM dsaParamGenMech; michael@0: CK_ULONG primeBits = 1024; michael@0: CK_ATTRIBUTE dsaParamGenTemplate[1]; michael@0: CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE; michael@0: CK_BYTE DSA_P[128]; michael@0: CK_BYTE DSA_Q[20]; michael@0: CK_BYTE DSA_G[128]; michael@0: CK_MECHANISM dsaKeyPairGenMech; michael@0: CK_ATTRIBUTE dsaPubKeyTemplate[5]; michael@0: CK_ATTRIBUTE dsaPrivKeyTemplate[5]; michael@0: CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE; michael@0: CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE; michael@0: michael@0: /* From SHA1ShortMsg.req, Len = 136 */ michael@0: CK_BYTE MSG[] = { michael@0: 0xba, 0x33, 0x95, 0xfb, michael@0: 0x5a, 0xfa, 0x8e, 0x6a, michael@0: 0x43, 0xdf, 0x41, 0x6b, michael@0: 0x32, 0x7b, 0x74, 0xfa, michael@0: 0x44 michael@0: }; michael@0: CK_BYTE MD[] = { michael@0: 0xf7, 0x5d, 0x92, 0xa4, michael@0: 0xbb, 0x4d, 0xec, 0xc3, michael@0: 0x7c, 0x5c, 0x72, 0xfa, michael@0: 0x04, 0x75, 0x71, 0x0a, michael@0: 0x06, 0x75, 0x8c, 0x1d michael@0: }; michael@0: michael@0: CK_BYTE sha1Digest[20]; michael@0: CK_ULONG sha1DigestLen; michael@0: CK_BYTE dsaSig[40]; michael@0: CK_ULONG dsaSigLen; michael@0: CK_MECHANISM sha1Mech = { michael@0: CKM_SHA_1, NULL, 0 michael@0: }; michael@0: CK_MECHANISM dsaMech = { michael@0: CKM_DSA, NULL, 0 michael@0: }; michael@0: CK_MECHANISM dsaWithSha1Mech = { michael@0: CKM_DSA_SHA1, NULL, 0 michael@0: }; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* DSA key init */ michael@0: dsaParamGenMech.mechanism = CKM_DSA_PARAMETER_GEN; michael@0: dsaParamGenMech.pParameter = NULL_PTR; michael@0: dsaParamGenMech.ulParameterLen = 0; michael@0: dsaParamGenTemplate[0].type = CKA_PRIME_BITS; michael@0: dsaParamGenTemplate[0].pValue = &primeBits; michael@0: dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits); michael@0: dsaPubKeyTemplate[0].type = CKA_PRIME; michael@0: dsaPubKeyTemplate[0].pValue = DSA_P; michael@0: dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P); michael@0: dsaPubKeyTemplate[1].type = CKA_SUBPRIME; michael@0: dsaPubKeyTemplate[1].pValue = DSA_Q; michael@0: dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q); michael@0: dsaPubKeyTemplate[2].type = CKA_BASE; michael@0: dsaPubKeyTemplate[2].pValue = DSA_G; michael@0: dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G); michael@0: dsaPubKeyTemplate[3].type = CKA_TOKEN; michael@0: dsaPubKeyTemplate[3].pValue = &true; michael@0: dsaPubKeyTemplate[3].ulValueLen = sizeof(true); michael@0: dsaPubKeyTemplate[4].type = CKA_VERIFY; michael@0: dsaPubKeyTemplate[4].pValue = &true; michael@0: dsaPubKeyTemplate[4].ulValueLen = sizeof(true); michael@0: dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN; michael@0: dsaKeyPairGenMech.pParameter = NULL_PTR; michael@0: dsaKeyPairGenMech.ulParameterLen = 0; michael@0: dsaPrivKeyTemplate[0].type = CKA_TOKEN; michael@0: dsaPrivKeyTemplate[0].pValue = &true; michael@0: dsaPrivKeyTemplate[0].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[1].type = CKA_PRIVATE; michael@0: dsaPrivKeyTemplate[1].pValue = &true; michael@0: dsaPrivKeyTemplate[1].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[2].type = CKA_SENSITIVE; michael@0: dsaPrivKeyTemplate[2].pValue = &true; michael@0: dsaPrivKeyTemplate[2].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[3].type = CKA_SIGN, michael@0: dsaPrivKeyTemplate[3].pValue = &true; michael@0: dsaPrivKeyTemplate[3].ulValueLen = sizeof(true); michael@0: dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE; michael@0: dsaPrivKeyTemplate[4].pValue = &true; michael@0: dsaPrivKeyTemplate[4].ulValueLen = sizeof(true); michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], michael@0: CKF_RW_SESSION | CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate DSA PQG domain parameters ... \n"); michael@0: /* Generate DSA domain parameters PQG */ michael@0: crv = pFunctionList->C_GenerateKey(hSession, &dsaParamGenMech, michael@0: dsaParamGenTemplate, michael@0: 1, michael@0: &hDsaParams); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("DSA domain parameter generation succeeded\n"); michael@0: } else { michael@0: PKM_Error( "DSA domain parameter generation failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_GetAttributeValue(hSession, hDsaParams, michael@0: dsaPubKeyTemplate, 3); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("Getting DSA domain parameters succeeded\n"); michael@0: } else { michael@0: PKM_Error( "Getting DSA domain parameters failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_DestroyObject(hSession, hDsaParams); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("Destroying DSA domain parameters succeeded\n"); michael@0: } else { michael@0: PKM_Error( "Destroying DSA domain parameters failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate a DSA key pair ... \n"); michael@0: /* Generate a persistent DSA key pair */ michael@0: crv = pFunctionList->C_GenerateKeyPair(hSession, &dsaKeyPairGenMech, michael@0: dsaPubKeyTemplate, michael@0: NUM_ELEM(dsaPubKeyTemplate), michael@0: dsaPrivKeyTemplate, michael@0: NUM_ELEM(dsaPrivKeyTemplate), michael@0: &hDSApubKey, &hDSAprivKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("DSA key pair generation succeeded\n"); michael@0: } else { michael@0: PKM_Error( "DSA key pair generation failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Compute SHA-1 digest */ michael@0: crv = pFunctionList->C_DigestInit(hSession, &sha1Mech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: sha1DigestLen = sizeof(sha1Digest); michael@0: crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG), michael@0: sha1Digest, &sha1DigestLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Digest failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: if (sha1DigestLen != sizeof(sha1Digest)) { michael@0: PKM_Error( "sha1DigestLen is %lu\n", sha1DigestLen); michael@0: return crv; michael@0: } michael@0: michael@0: if (memcmp(sha1Digest, MD, sizeof(MD)) == 0) { michael@0: PKM_LogIt("SHA-1 SHA1ShortMsg test case Len = 136 passed\n"); michael@0: } else { michael@0: PKM_Error( "SHA-1 SHA1ShortMsg test case Len = 136 failed\n"); michael@0: } michael@0: michael@0: crv = PKM_PubKeySign(pFunctionList, hSession, michael@0: hDSApubKey, hDSAprivKey, michael@0: &dsaMech, sha1Digest, sizeof(sha1Digest)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_PubKeySign CKM_DSA succeeded \n"); michael@0: } else { michael@0: PKM_Error( "PKM_PubKeySign failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = PKM_PubKeySign(pFunctionList, hSession, michael@0: hDSApubKey, hDSAprivKey, michael@0: &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT)); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("PKM_PubKeySign CKM_DSA_SHA1 succeeded \n"); michael@0: } else { michael@0: PKM_Error( "PKM_PubKeySign failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Sign with DSA */ michael@0: crv = pFunctionList->C_SignInit(hSession, &dsaMech, hDSAprivKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: dsaSigLen = sizeof(dsaSig); michael@0: crv = pFunctionList->C_Sign(hSession, sha1Digest, sha1DigestLen, michael@0: dsaSig, &dsaSigLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Verify the DSA signature */ michael@0: crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen, michael@0: dsaSig, dsaSigLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Verify succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Verify the signature in a different way */ michael@0: crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech, michael@0: hDSApubKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyUpdate(hSession, MSG+1, sizeof(MSG)-1); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyFinal succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Verify the signature in a different way */ michael@0: crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech, michael@0: hDSApubKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyUpdate(hSession, MSG+1, sizeof(MSG)-1); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyFinal of multi update succeeded.\n"); michael@0: } else { michael@0: PKM_Error("C_VerifyFinal of multi update failed with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: /* Now modify the data */ michael@0: MSG[0] += 1; michael@0: /* Compute SHA-1 digest */ michael@0: crv = pFunctionList->C_DigestInit(hSession, &sha1Mech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: sha1DigestLen = sizeof(sha1Digest); michael@0: crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG), michael@0: sha1Digest, &sha1DigestLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Digest failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen, michael@0: dsaSig, dsaSigLen); michael@0: if (crv != CKR_SIGNATURE_INVALID) { michael@0: PKM_Error( "C_Verify of modified data succeeded\n"); michael@0: return crv; michael@0: } else { michael@0: PKM_LogIt("C_Verify of modified data returned as EXPECTED " michael@0: " with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: } michael@0: michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen) { michael@0: michael@0: CK_RV crv = CKR_OK; michael@0: michael@0: CK_BYTE hmac1[HMAC_MAX_LENGTH]; michael@0: CK_ULONG hmac1Len = 0; michael@0: CK_BYTE hmac2[HMAC_MAX_LENGTH]; michael@0: CK_ULONG hmac2Len = 0; michael@0: michael@0: memset(hmac1, 0, sizeof(hmac1)); michael@0: memset(hmac2, 0, sizeof(hmac2)); michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_SignInit succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: hmac1Len = sizeof(hmac1); michael@0: crv = pFunctionList->C_Sign(hSession, (CK_BYTE * )pData, michael@0: pDataLen, michael@0: (CK_BYTE * )hmac1, &hmac1Len); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Sign succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_SignInit succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_SignUpdate(hSession, (CK_BYTE * )pData, michael@0: pDataLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_SignUpdate succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_SignUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: hmac2Len = sizeof(hmac2); michael@0: crv = pFunctionList->C_SignFinal(hSession, (CK_BYTE * )hmac2, &hmac2Len); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_SignFinal succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_SignFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if ((hmac1Len == hmac2Len) && (memcmp(hmac1, hmac2, hmac1Len) == 0) ) { michael@0: PKM_LogIt("hmacs are equal!\n"); michael@0: } else { michael@0: PKM_Error("hmacs are not equal!\n"); michael@0: } michael@0: crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Verify(hSession, (CK_BYTE * )pData, michael@0: pDataLen, michael@0: (CK_BYTE * ) hmac2, hmac2Len); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Verify of hmac succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyUpdate(hSession, (CK_BYTE * )pData, michael@0: pDataLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyUpdate of hmac succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyFinal(hSession, (CK_BYTE * ) hmac1, michael@0: hmac1Len); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyFinal of hmac succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: return crv; michael@0: } michael@0: michael@0: CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: CK_RV crv = CKR_OK; michael@0: michael@0: CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; michael@0: CK_SESSION_INFO sinfo; michael@0: CK_ATTRIBUTE_PTR pTemplate; michael@0: CK_ULONG tnObjects = 0; michael@0: int curMode; michael@0: int i; michael@0: int number_of_all_known_attribute_types = totalKnownType(ConstAttribute); michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &h); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , )" michael@0: "returned 0x%08X, %-26s\n", pSlotList[slotID], crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Opened a session: handle = 0x%08x\n", h); michael@0: michael@0: (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO)); michael@0: crv = pFunctionList->C_GetSessionInfo(h, &sinfo); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_LogIt( "C_GetSessionInfo(%lu, ) returned 0x%08X, %-26s\n", h, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " SESSION INFO:\n"); michael@0: PKM_LogIt( " slotID = %lu\n", sinfo.slotID); michael@0: PKM_LogIt( " state = %lu\n", sinfo.state); michael@0: PKM_LogIt( " flags = 0x%08x\n", sinfo.flags); michael@0: #ifdef CKF_EXCLUSIVE_SESSION michael@0: PKM_LogIt( " -> EXCLUSIVE SESSION = %s\n", sinfo.flags & michael@0: CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE"); michael@0: #endif /* CKF_EXCLUSIVE_SESSION */ michael@0: PKM_LogIt( " -> RW SESSION = %s\n", sinfo.flags & michael@0: CKF_RW_SESSION ? "TRUE" : "FALSE"); michael@0: PKM_LogIt( " -> SERIAL SESSION = %s\n", sinfo.flags & michael@0: CKF_SERIAL_SESSION ? "TRUE" : "FALSE"); michael@0: #ifdef CKF_INSERTION_CALLBACK michael@0: PKM_LogIt( " -> INSERTION CALLBACK = %s\n", sinfo.flags & michael@0: CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE"); michael@0: #endif /* CKF_INSERTION_CALLBACK */ michael@0: PKM_LogIt( " ulDeviceError = %lu\n", sinfo.ulDeviceError); michael@0: PKM_LogIt( "\n"); michael@0: michael@0: crv = pFunctionList->C_FindObjectsInit(h, NULL, 0); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_LogIt( "C_FindObjectsInit(%lu, NULL, 0) returned " michael@0: "0x%08X, %-26s\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: pTemplate = (CK_ATTRIBUTE_PTR)calloc(number_of_all_known_attribute_types, michael@0: sizeof(CK_ATTRIBUTE)); michael@0: if ( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { michael@0: PKM_Error( "[pTemplate memory allocation of %lu bytes failed]\n", michael@0: number_of_all_known_attribute_types * michael@0: sizeof(CK_ATTRIBUTE)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " All objects:\n"); michael@0: /* Printing table set to NOMODE */ michael@0: curMode = MODE; michael@0: MODE = NOMODE; michael@0: michael@0: while (1) { michael@0: CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0; michael@0: CK_ULONG nObjects = 0; michael@0: CK_ULONG k; michael@0: CK_ULONG nAttributes = 0; michael@0: CK_ATTRIBUTE_PTR pT2; michael@0: CK_ULONG l; michael@0: const char * attName = NULL; michael@0: michael@0: crv = pFunctionList->C_FindObjects(h, &o, 1, &nObjects); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjects(%lu, , 1, ) returned 0x%08X, %-26s\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if ( 0 == nObjects ) { michael@0: PKM_LogIt( "\n"); michael@0: break; michael@0: } michael@0: michael@0: tnObjects++; michael@0: michael@0: PKM_LogIt( " OBJECT HANDLE %lu:\n", o); michael@0: michael@0: k = 0; michael@0: for (i=0; i < constCount; i++) { michael@0: if (consts[i].type == ConstAttribute) { michael@0: pTemplate[k].type = consts[i].value; michael@0: pTemplate[k].pValue = (CK_VOID_PTR) NULL; michael@0: pTemplate[k].ulValueLen = 0; michael@0: k++; michael@0: } michael@0: assert(k <= number_of_all_known_attribute_types); michael@0: } michael@0: michael@0: crv = pFunctionList->C_GetAttributeValue(h, o, pTemplate, michael@0: number_of_all_known_attribute_types); michael@0: switch ( crv ) { michael@0: case CKR_OK: michael@0: case CKR_ATTRIBUTE_SENSITIVE: michael@0: case CKR_ATTRIBUTE_TYPE_INVALID: michael@0: case CKR_BUFFER_TOO_SMALL: michael@0: break; michael@0: default: michael@0: PKM_Error( "C_GetAtributeValue(%lu, %lu, {all attribute types}," michael@0: "%lu) returned 0x%08X, %-26s\n", michael@0: h, o, number_of_all_known_attribute_types, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: for ( k = 0; k < (CK_ULONG) number_of_all_known_attribute_types; k++) { michael@0: if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { michael@0: nAttributes++; michael@0: } michael@0: } michael@0: michael@0: PKM_LogIt( " %lu attributes:\n", nAttributes); michael@0: for ( k = 0; k < (CK_ULONG) number_of_all_known_attribute_types; michael@0: k++ ) { michael@0: if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { michael@0: attName = getNameFromAttribute(pTemplate[k].type); michael@0: if (!attName) { michael@0: PKM_Error("Unable to find attribute name update pk11table.c\n"); michael@0: } michael@0: PKM_LogIt( " %s 0x%08x (len = %lu)\n", michael@0: attName, michael@0: pTemplate[k].type, michael@0: pTemplate[k].ulValueLen); michael@0: } michael@0: } michael@0: PKM_LogIt( "\n"); michael@0: michael@0: pT2 = (CK_ATTRIBUTE_PTR)calloc(nAttributes, sizeof(CK_ATTRIBUTE)); michael@0: if ( (CK_ATTRIBUTE_PTR)NULL == pT2 ) { michael@0: PKM_Error( "[pT2 memory allocation of %lu bytes failed]\n", michael@0: nAttributes * sizeof(CK_ATTRIBUTE)); michael@0: return crv; michael@0: } michael@0: michael@0: /* allocate memory for the attribute values */ michael@0: for ( l = 0, k = 0; k < (CK_ULONG) number_of_all_known_attribute_types; michael@0: k++ ) { michael@0: if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { michael@0: pT2[l].type = pTemplate[k].type; michael@0: pT2[l].ulValueLen = pTemplate[k].ulValueLen; michael@0: if (pT2[l].ulValueLen > 0) { michael@0: pT2[l].pValue = (CK_VOID_PTR)malloc(pT2[l].ulValueLen); michael@0: if ( (CK_VOID_PTR)NULL == pT2[l].pValue ) { michael@0: PKM_Error( "pValue memory allocation of %lu bytes failed]\n", michael@0: pT2[l].ulValueLen); michael@0: return crv; michael@0: } michael@0: } else pT2[l].pValue = (CK_VOID_PTR) NULL; michael@0: l++; michael@0: } michael@0: } michael@0: michael@0: assert( l == nAttributes ); michael@0: michael@0: crv = pFunctionList->C_GetAttributeValue(h, o, pT2, nAttributes); michael@0: switch ( crv ) { michael@0: case CKR_OK: michael@0: case CKR_ATTRIBUTE_SENSITIVE: michael@0: case CKR_ATTRIBUTE_TYPE_INVALID: michael@0: case CKR_BUFFER_TOO_SMALL: michael@0: break; michael@0: default: michael@0: PKM_Error( "C_GetAtributeValue(%lu, %lu, {existent attribute" michael@0: " types}, %lu) returned 0x%08X, %-26s\n", michael@0: h, o, nAttributes, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: for ( l = 0; l < nAttributes; l++ ) { michael@0: attName = getNameFromAttribute(pT2[l].type); michael@0: if (!attName) attName = "unknown attribute"; michael@0: PKM_LogIt( " type = %s len = %ld", michael@0: attName, (CK_LONG)pT2[l].ulValueLen); michael@0: michael@0: if ( -1 == (CK_LONG)pT2[l].ulValueLen ) { michael@0: ; michael@0: } else { michael@0: CK_ULONG m; michael@0: michael@0: if ( pT2[l].ulValueLen <= 8 ) { michael@0: PKM_LogIt( ", value = "); michael@0: } else { michael@0: PKM_LogIt( ", value = \n "); michael@0: } michael@0: michael@0: for ( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) { michael@0: PKM_LogIt( "%02x", (CK_ULONG)(0xff & michael@0: ((CK_CHAR_PTR)pT2[l].pValue)[m])); michael@0: } michael@0: michael@0: PKM_LogIt( " "); michael@0: michael@0: for ( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) { michael@0: CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m]; michael@0: if ( (c < 0x20) || (c >= 0x7f) ) { michael@0: c = '.'; michael@0: } michael@0: PKM_LogIt( "%c", c); michael@0: } michael@0: } michael@0: michael@0: PKM_LogIt( "\n"); michael@0: } michael@0: michael@0: PKM_LogIt( "\n"); michael@0: michael@0: for ( l = 0; l < nAttributes; l++ ) { michael@0: if (pT2[l].pValue) { michael@0: free(pT2[l].pValue); michael@0: } michael@0: } michael@0: free(pT2); michael@0: } /* while(1) */ michael@0: michael@0: MODE = curMode; /* reset the logging MODE */ michael@0: michael@0: crv = pFunctionList->C_FindObjectsFinal(h); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " (%lu objects total)\n", tnObjects); michael@0: michael@0: crv = pFunctionList->C_CloseSession(h); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_CloseSession(%lu) returned 0x%08X, %-26s\n", h, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: } michael@0: /* session to create, find, and delete a couple session objects */ michael@0: CK_RV PKM_MultiObjectManagement (CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: michael@0: CK_RV crv = CKR_OK; michael@0: michael@0: CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; michael@0: CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0; michael@0: CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1]; michael@0: CK_OBJECT_CLASS cko_data = CKO_DATA; michael@0: char *key = "TEST PROGRAM"; michael@0: CK_ULONG key_len = 0; michael@0: CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0; michael@0: CK_OBJECT_HANDLE hTwoIn = (CK_OBJECT_HANDLE)0; michael@0: CK_OBJECT_HANDLE hThreeIn = (CK_OBJECT_HANDLE)0; michael@0: CK_OBJECT_HANDLE hDeltaIn = (CK_OBJECT_HANDLE)0; michael@0: CK_OBJECT_HANDLE found[10]; michael@0: CK_ULONG nFound; michael@0: CK_ULONG hDeltaLen, hThreeLen = 0; michael@0: michael@0: CK_TOKEN_INFO tinfo; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: key_len = sizeof(key); michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], michael@0: CKF_SERIAL_SESSION, NULL, NULL, &h); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_OpenSession(%lu, CKF_SERIAL_SESSION, , )" michael@0: "returned 0x%08X, %-26s\n", pSlotList[slotID], crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Login(h, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO)); michael@0: crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tinfo); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error("C_GetTokenInfo(%lu, ) returned 0x%08X, %-26s\n", michael@0: pSlotList[slotID], crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: PKM_LogIt( " Opened a session: handle = 0x%08x\n", h); michael@0: michael@0: one[0].type = CKA_CLASS; michael@0: one[0].pValue = &cko_data; michael@0: one[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: one[1].type = CKA_TOKEN; michael@0: one[1].pValue = &false; michael@0: one[1].ulValueLen = sizeof(CK_BBOOL); michael@0: one[2].type = CKA_PRIVATE; michael@0: one[2].pValue = &false; michael@0: one[2].ulValueLen = sizeof(CK_BBOOL); michael@0: one[3].type = CKA_MODIFIABLE; michael@0: one[3].pValue = &true; michael@0: one[3].ulValueLen = sizeof(CK_BBOOL); michael@0: one[4].type = CKA_LABEL; michael@0: one[4].pValue = "Test data object one"; michael@0: one[4].ulValueLen = strlen(one[4].pValue); michael@0: one[5].type = CKA_APPLICATION; michael@0: one[5].pValue = key; michael@0: one[5].ulValueLen = key_len; michael@0: one[6].type = CKA_VALUE; michael@0: one[6].pValue = "Object one"; michael@0: one[6].ulValueLen = strlen(one[6].pValue); michael@0: michael@0: two[0].type = CKA_CLASS; michael@0: two[0].pValue = &cko_data; michael@0: two[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: two[1].type = CKA_TOKEN; michael@0: two[1].pValue = &false; michael@0: two[1].ulValueLen = sizeof(CK_BBOOL); michael@0: two[2].type = CKA_PRIVATE; michael@0: two[2].pValue = &false; michael@0: two[2].ulValueLen = sizeof(CK_BBOOL); michael@0: two[3].type = CKA_MODIFIABLE; michael@0: two[3].pValue = &true; michael@0: two[3].ulValueLen = sizeof(CK_BBOOL); michael@0: two[4].type = CKA_LABEL; michael@0: two[4].pValue = "Test data object two"; michael@0: two[4].ulValueLen = strlen(two[4].pValue); michael@0: two[5].type = CKA_APPLICATION; michael@0: two[5].pValue = key; michael@0: two[5].ulValueLen = key_len; michael@0: two[6].type = CKA_VALUE; michael@0: two[6].pValue = "Object two"; michael@0: two[6].ulValueLen = strlen(two[6].pValue); michael@0: michael@0: three[0].type = CKA_CLASS; michael@0: three[0].pValue = &cko_data; michael@0: three[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: three[1].type = CKA_TOKEN; michael@0: three[1].pValue = &false; michael@0: three[1].ulValueLen = sizeof(CK_BBOOL); michael@0: three[2].type = CKA_PRIVATE; michael@0: three[2].pValue = &false; michael@0: three[2].ulValueLen = sizeof(CK_BBOOL); michael@0: three[3].type = CKA_MODIFIABLE; michael@0: three[3].pValue = &true; michael@0: three[3].ulValueLen = sizeof(CK_BBOOL); michael@0: three[4].type = CKA_LABEL; michael@0: three[4].pValue = "Test data object three"; michael@0: three[4].ulValueLen = strlen(three[4].pValue); michael@0: three[5].type = CKA_APPLICATION; michael@0: three[5].pValue = key; michael@0: three[5].ulValueLen = key_len; michael@0: three[6].type = CKA_VALUE; michael@0: three[6].pValue = "Object three"; michael@0: three[6].ulValueLen = strlen(three[6].pValue); michael@0: michael@0: crv = pFunctionList->C_CreateObject(h, one, 7, &hOneIn); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_CreateObject(%lu, one, 7, ) returned 0x%08X, %-26s\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Created object one: handle = %lu\n", hOneIn); michael@0: michael@0: crv = pFunctionList->C_CreateObject(h, two, 7, &hTwoIn); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_CreateObject(%lu, two, 7, ) returned 0x%08X, %-26s\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Created object two: handle = %lu\n", hTwoIn); michael@0: michael@0: crv = pFunctionList->C_CreateObject(h, three, 7, &hThreeIn); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_CreateObject(%lu, three, 7, ) returned 0x%08x\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_GetObjectSize(h, hThreeIn, &hThreeLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GetObjectSize succeeded\n"); michael@0: } else { michael@0: PKM_Error("C_GetObjectSize failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Created object three: handle = %lu\n", hThreeIn); michael@0: michael@0: delta[0].type = CKA_VALUE; michael@0: delta[0].pValue = "Copied object"; michael@0: delta[0].ulValueLen = strlen(delta[0].pValue); michael@0: michael@0: crv = pFunctionList->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_CopyObject(%lu, %lu, delta, 1, ) returned " michael@0: "0x%08X, %-26s\n", michael@0: h, hThreeIn, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_GetObjectSize(h, hDeltaIn, &hDeltaLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GetObjectSize succeeded\n"); michael@0: } else { michael@0: PKM_Error("C_GetObjectSize failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if (hThreeLen == hDeltaLen) { michael@0: PKM_LogIt("Copied object size same as orginal\n"); michael@0: } else { michael@0: PKM_Error("Copied object different from original\n"); michael@0: return CKR_DEVICE_ERROR; michael@0: } michael@0: michael@0: PKM_LogIt( " Copied object three: new handle = %lu\n", hDeltaIn); michael@0: michael@0: mask[0].type = CKA_APPLICATION; michael@0: mask[0].pValue = key; michael@0: mask[0].ulValueLen = key_len; michael@0: michael@0: crv = pFunctionList->C_FindObjectsInit(h, mask, 1); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: (void)memset(&found, 0, sizeof(found)); michael@0: nFound = 0; michael@0: crv = pFunctionList->C_FindObjects(h, found, 10, &nFound); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if ( 4 != nFound ) { michael@0: PKM_Error( "Found %lu objects, not 4.\n", nFound); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Found 4 objects: %lu, %lu, %lu, %lu\n", michael@0: found[0], found[1], found[2], found[3]); michael@0: michael@0: crv = pFunctionList->C_FindObjectsFinal(h); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", michael@0: h, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_DestroyObject(h, hThreeIn); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_DestroyObject(%lu, %lu) returned 0x%08X, %-26s\n", h, michael@0: hThreeIn, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Destroyed object three (handle = %lu)\n", hThreeIn); michael@0: michael@0: delta[0].type = CKA_APPLICATION; michael@0: delta[0].pValue = "Changed application"; michael@0: delta[0].ulValueLen = strlen(delta[0].pValue); michael@0: michael@0: crv = pFunctionList->C_SetAttributeValue(h, hTwoIn, delta, 1); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error("C_SetAttributeValue(%lu, %lu, delta, 1) returned " michael@0: "0x%08X, %-26s\n", michael@0: h, hTwoIn, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Changed object two (handle = %lu).\n", hTwoIn); michael@0: michael@0: /* Can another session find these session objects? */ michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &h2); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_OpenSession(%lu, CKF_SERIAL_SESSION, , )" michael@0: " returned 0x%08X, %-26s\n", pSlotList[slotID], crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: PKM_LogIt( " Opened a second session: handle = 0x%08x\n", h2); michael@0: michael@0: /* mask is still the same */ michael@0: michael@0: crv = pFunctionList->C_FindObjectsInit(h2, mask, 1); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n", michael@0: h2, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: (void)memset(&found, 0, sizeof(found)); michael@0: nFound = 0; michael@0: crv = pFunctionList->C_FindObjects(h2, found, 10, &nFound); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n", michael@0: h2, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if ( 2 != nFound ) { michael@0: PKM_Error( "Found %lu objects, not 2.\n", nFound); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( " Found 2 objects: %lu, %lu\n", michael@0: found[0], found[1]); michael@0: michael@0: crv = pFunctionList->C_FindObjectsFinal(h2); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h2, crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Logout(h); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_CloseAllSessions(pSlotList[slotID]); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_CloseAllSessions(%lu) returned 0x%08X, %-26s\n", michael@0: pSlotList[slotID], crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt( "\n"); michael@0: return crv; michael@0: } michael@0: michael@0: CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) { michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv = CKR_OK; michael@0: CK_MECHANISM sAESKeyMech = { michael@0: CKM_AES_KEY_GEN, NULL, 0 michael@0: }; michael@0: CK_OBJECT_CLASS class = CKO_SECRET_KEY; michael@0: CK_KEY_TYPE keyAESType = CKK_AES; michael@0: CK_UTF8CHAR AESlabel[] = "An AES secret key object"; michael@0: CK_ULONG AESvalueLen = 16; michael@0: CK_ATTRIBUTE sAESKeyTemplate[9]; michael@0: CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE; michael@0: CK_BYTE_PTR pstate = NULL; michael@0: CK_ULONG statelen, digestlen, plainlen, plainlen_1, plainlen_2, slen; michael@0: michael@0: static const CK_UTF8CHAR *plaintext = (CK_UTF8CHAR *)"Firefox rules."; michael@0: static const CK_UTF8CHAR *plaintext_1 = (CK_UTF8CHAR *)"Thunderbird rules."; michael@0: static const CK_UTF8CHAR *plaintext_2 = (CK_UTF8CHAR *) michael@0: "Firefox and Thunderbird."; michael@0: michael@0: char digest[MAX_DIGEST_SZ], digest_1[MAX_DIGEST_SZ]; michael@0: char sign[MAX_SIG_SZ]; michael@0: CK_MECHANISM signmech; michael@0: CK_MECHANISM digestmech; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: michael@0: /* AES key template */ michael@0: sAESKeyTemplate[0].type = CKA_CLASS; michael@0: sAESKeyTemplate[0].pValue = &class; michael@0: sAESKeyTemplate[0].ulValueLen = sizeof(class); michael@0: sAESKeyTemplate[1].type = CKA_KEY_TYPE; michael@0: sAESKeyTemplate[1].pValue = &keyAESType; michael@0: sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType); michael@0: sAESKeyTemplate[2].type = CKA_LABEL; michael@0: sAESKeyTemplate[2].pValue = AESlabel; michael@0: sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1; michael@0: sAESKeyTemplate[3].type = CKA_ENCRYPT; michael@0: sAESKeyTemplate[3].pValue = &true; michael@0: sAESKeyTemplate[3].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[4].type = CKA_DECRYPT; michael@0: sAESKeyTemplate[4].pValue = &true; michael@0: sAESKeyTemplate[4].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[5].type = CKA_SIGN; michael@0: sAESKeyTemplate[5].pValue = &true; michael@0: sAESKeyTemplate[5].ulValueLen = sizeof (true); michael@0: sAESKeyTemplate[6].type = CKA_VERIFY; michael@0: sAESKeyTemplate[6].pValue = &true; michael@0: sAESKeyTemplate[6].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[7].type = CKA_UNWRAP; michael@0: sAESKeyTemplate[7].pValue = &true; michael@0: sAESKeyTemplate[7].ulValueLen = sizeof(true); michael@0: sAESKeyTemplate[8].type = CKA_VALUE_LEN; michael@0: sAESKeyTemplate[8].pValue = &AESvalueLen; michael@0: sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen); michael@0: michael@0: signmech.mechanism = CKM_SHA_1_HMAC; michael@0: signmech.pParameter = NULL; michael@0: signmech.ulParameterLen = 0; michael@0: digestmech.mechanism = CKM_SHA256; michael@0: digestmech.pParameter = NULL; michael@0: digestmech.ulParameterLen = 0; michael@0: michael@0: michael@0: plainlen = strlen((char *)plaintext); michael@0: plainlen_1 = strlen((char *)plaintext_1); michael@0: plainlen_2 = strlen((char *)plaintext_2); michael@0: digestlen = MAX_DIGEST_SZ; michael@0: michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: PKM_LogIt("Generate an AES key ...\n"); michael@0: /* generate an AES Secret Key */ michael@0: crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech, michael@0: sAESKeyTemplate, michael@0: NUM_ELEM(sAESKeyTemplate), michael@0: &sKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateKey AES succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_SignInit(hSession, &signmech, sKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_SignInit failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: slen = sizeof(sign); michael@0: crv = pFunctionList->C_Sign(hSession, (CK_BYTE_PTR)plaintext, plainlen, michael@0: (CK_BYTE_PTR)sign, &slen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_Sign failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_DestroyObject(hSession, sKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_DestroyObject failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: digestlen = MAX_DIGEST_SZ; michael@0: crv = pFunctionList->C_DigestInit(hSession, &digestmech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext, michael@0: plainlen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_GetOperationState(hSession, NULL, &statelen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: pstate = (CK_BYTE_PTR) malloc(statelen * sizeof (CK_BYTE_PTR)); michael@0: crv = pFunctionList->C_GetOperationState(hSession, pstate, &statelen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_1, michael@0: plainlen_1); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_2, michael@0: plainlen_2); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* michael@0: * This will override/negate the above 2 digest_update michael@0: * operations michael@0: */ michael@0: crv = pFunctionList->C_SetOperationState(hSession, pstate, statelen, michael@0: 0, 0); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_SetOperationState failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_DigestFinal(hSession, (CK_BYTE_PTR)digest, michael@0: &digestlen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_DigestFinal failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: digestlen = MAX_DIGEST_SZ; michael@0: crv = pFunctionList->C_DigestInit(hSession, &digestmech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Digest(hSession, (CK_BYTE_PTR)plaintext, plainlen, michael@0: (CK_BYTE_PTR)digest_1, &digestlen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error("C_Digest failed returned 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: if (memcmp(digest, digest_1, digestlen) == 0) { michael@0: PKM_LogIt("Digest and digest_1 are equal!\n"); michael@0: } else { michael@0: PKM_Error("Digest and digest_1 are not equal!\n"); michael@0: } michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if ( CKR_OK != crv ) { michael@0: PKM_Error( "C_CloseSession(%lu) returned 0x%08X, %-26s\n", michael@0: hSession, crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Recover Functions michael@0: */ michael@0: CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey, michael@0: CK_MECHANISM *signMech, const CK_BYTE * pData, michael@0: CK_ULONG pDataLen) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_BYTE sig[MAX_SIG_SZ]; michael@0: CK_ULONG sigLen = MAX_SIG_SZ; michael@0: CK_BYTE recover[MAX_SIG_SZ]; michael@0: CK_ULONG recoverLen = MAX_SIG_SZ; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* initializes a signature operation, michael@0: * where the data can be recovered from the signature michael@0: */ michael@0: crv = pFunctionList->C_SignRecoverInit(hSession, signMech, michael@0: hPrivKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_SignRecoverInit succeeded. \n"); michael@0: } else { michael@0: PKM_Error("C_SignRecoverInit failed.\n" michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* signs single-part data, michael@0: * where the data can be recovered from the signature michael@0: */ michael@0: crv = pFunctionList->C_SignRecover(hSession, (CK_BYTE * )pData, michael@0: pDataLen, michael@0: (CK_BYTE * )sig, &sigLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_SignRecover succeeded. \n"); michael@0: } else { michael@0: PKM_Error("C_SignRecoverInit failed to create an RSA key pair.\n" michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* michael@0: * initializes a verification operation michael@0: *where the data is recovered from the signature michael@0: */ michael@0: crv = pFunctionList->C_VerifyRecoverInit(hSession, signMech, michael@0: hPubKey); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyRecoverInit succeeded. \n"); michael@0: } else { michael@0: PKM_Error("C_VerifyRecoverInit failed.\n" michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* michael@0: * verifies a signature on single-part data, michael@0: * where the data is recovered from the signature michael@0: */ michael@0: crv = pFunctionList->C_VerifyRecover(hSession, (CK_BYTE * )sig, michael@0: sigLen, michael@0: (CK_BYTE * )recover, &recoverLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyRecover succeeded. \n"); michael@0: } else { michael@0: PKM_Error("C_VerifyRecover failed.\n" michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if ((recoverLen == pDataLen) michael@0: && (memcmp(recover, pData, pDataLen) == 0)) { michael@0: PKM_LogIt("VerifyRecover test case passed\n"); michael@0: } else { michael@0: PKM_Error( "VerifyRecover test case failed\n"); michael@0: } michael@0: michael@0: return crv; michael@0: } michael@0: /* michael@0: * wrapUnwrap michael@0: * wrap the secretkey with the public key. michael@0: * unwrap the secretkey with the private key. michael@0: */ michael@0: CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_OBJECT_HANDLE hPublicKey, michael@0: CK_OBJECT_HANDLE hPrivateKey, michael@0: CK_MECHANISM *wrapMechanism, michael@0: CK_OBJECT_HANDLE hSecretKey, michael@0: CK_ATTRIBUTE *sKeyTemplate, michael@0: CK_ULONG skeyTempSize) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_OBJECT_HANDLE hSecretKeyUnwrapped = CK_INVALID_HANDLE; michael@0: CK_BYTE wrappedKey[128]; michael@0: CK_ULONG ulWrappedKeyLen = 0; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: ulWrappedKeyLen = sizeof(wrappedKey); michael@0: crv = pFunctionList->C_WrapKey( michael@0: hSession, wrapMechanism, michael@0: hPublicKey, hSecretKey, michael@0: wrappedKey, &ulWrappedKeyLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_WrapKey succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_WrapKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_UnwrapKey( michael@0: hSession, wrapMechanism, hPrivateKey, michael@0: wrappedKey, ulWrappedKeyLen, sKeyTemplate, michael@0: skeyTempSize, michael@0: &hSecretKeyUnwrapped); michael@0: if ((crv == CKR_OK) && (hSecretKeyUnwrapped != CK_INVALID_HANDLE)) { michael@0: PKM_LogIt("C_UnwrapKey succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_UnwrapKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return crv; michael@0: } michael@0: michael@0: /* michael@0: * Tests if the object's attributes match the expected_attrs michael@0: */ michael@0: CK_RV michael@0: PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj, michael@0: CK_ATTRIBUTE_PTR expected_attrs, michael@0: CK_ULONG expected_attrs_count) michael@0: { michael@0: CK_RV crv; michael@0: CK_ATTRIBUTE_PTR tmp_attrs; michael@0: unsigned int i; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* First duplicate the themplate */ michael@0: tmp_attrs = malloc(expected_attrs_count * sizeof (CK_ATTRIBUTE)); michael@0: michael@0: if (tmp_attrs == NULL) { michael@0: PKM_Error("Internal test memory failure\n"); michael@0: return (CKR_HOST_MEMORY); michael@0: } michael@0: michael@0: for (i = 0; i < expected_attrs_count; i++) { michael@0: tmp_attrs[i].type = expected_attrs[i].type; michael@0: tmp_attrs[i].ulValueLen = expected_attrs[i].ulValueLen; michael@0: michael@0: /* Don't give away the expected one. just zeros */ michael@0: tmp_attrs[i].pValue = calloc(expected_attrs[i].ulValueLen, 1); michael@0: michael@0: if (tmp_attrs[i].pValue == NULL) { michael@0: unsigned int j; michael@0: for (j = 0; j < i; j++) michael@0: free(tmp_attrs[j].pValue); michael@0: michael@0: free(tmp_attrs); michael@0: printf("Internal test memory failure\n"); michael@0: return (CKR_HOST_MEMORY); michael@0: } michael@0: } michael@0: michael@0: /* then get the attributes from the object */ michael@0: crv = pFunctionList->C_GetAttributeValue(hSession, obj, tmp_attrs, michael@0: expected_attrs_count); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_GetAttributeValue failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: crv = CKR_FUNCTION_FAILED; michael@0: goto out; michael@0: } michael@0: michael@0: /* Finally compare with the expected ones */ michael@0: for (i = 0; i < expected_attrs_count; i++) { michael@0: michael@0: if (memcmp(tmp_attrs[i].pValue, expected_attrs[i].pValue, michael@0: expected_attrs[i].ulValueLen) != 0) { michael@0: PKM_LogIt("comparing attribute type 0x%x with expected 0x%x\n", michael@0: tmp_attrs[i].type, expected_attrs[i].type); michael@0: PKM_LogIt("comparing attribute type value 0x%x with expected 0x%x\n", michael@0: tmp_attrs[i].pValue, expected_attrs[i].pValue); michael@0: /* don't report error at this time */ michael@0: } michael@0: } michael@0: michael@0: out: michael@0: for (i = 0; i < expected_attrs_count; i++) michael@0: free(tmp_attrs[i].pValue); michael@0: free(tmp_attrs); michael@0: return (crv); michael@0: } michael@0: michael@0: /* michael@0: * Check the validity of a mech michael@0: */ michael@0: CK_RV michael@0: PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession, michael@0: CK_MECHANISM_TYPE mechType, CK_FLAGS flags, michael@0: CK_BBOOL check_sizes, CK_ULONG minkeysize, CK_ULONG maxkeysize) michael@0: { michael@0: CK_SESSION_INFO sess_info; michael@0: CK_MECHANISM_INFO mech_info; michael@0: CK_RV crv; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: if ((crv = pFunctionList->C_GetSessionInfo(hSession, &sess_info)) michael@0: != CKR_OK) { michael@0: PKM_Error( "C_GetSessionInfo failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return (CKR_FUNCTION_FAILED); michael@0: } michael@0: michael@0: crv = pFunctionList->C_GetMechanismInfo(0, mechType, michael@0: &mech_info); michael@0: michael@0: michael@0: crv = pFunctionList->C_GetMechanismInfo(sess_info.slotID, mechType, michael@0: &mech_info); michael@0: michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_GetMechanismInfo failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return (CKR_FUNCTION_FAILED); michael@0: } michael@0: michael@0: if ((mech_info.flags & flags) == 0) { michael@0: PKM_Error("0x%x flag missing from mech\n", flags); michael@0: return (CKR_MECHANISM_INVALID); michael@0: } michael@0: if (!check_sizes) michael@0: return (CKR_OK); michael@0: michael@0: if (mech_info.ulMinKeySize != minkeysize) { michael@0: PKM_Error("Bad MinKeySize %d expected %d\n", mech_info.ulMinKeySize, michael@0: minkeysize); michael@0: return (CKR_MECHANISM_INVALID); michael@0: } michael@0: if (mech_info.ulMaxKeySize != maxkeysize) { michael@0: PKM_Error("Bad MaxKeySize %d expected %d\n", mech_info.ulMaxKeySize, michael@0: maxkeysize); michael@0: return (CKR_MECHANISM_INVALID); michael@0: } michael@0: return (CKR_OK); michael@0: } michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: /* michael@0: * Can be called with a non-null premaster_key_len for the michael@0: * *_DH mechanisms. In that case, no checking for the matching of michael@0: * the expected results is done. michael@0: * The rnd argument tells which correct/bogus randomInfo to use. michael@0: */ michael@0: CK_RV michael@0: PKM_TLSMasterKeyDerive( CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, michael@0: CK_MECHANISM_TYPE mechType, michael@0: enum_random_t rnd) { michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv; michael@0: CK_MECHANISM mk_mech; michael@0: CK_VERSION expected_version, version; michael@0: CK_OBJECT_CLASS class = CKO_SECRET_KEY; michael@0: CK_KEY_TYPE type = CKK_GENERIC_SECRET; michael@0: CK_BBOOL derive_bool = true; michael@0: CK_ATTRIBUTE attrs[4]; michael@0: CK_ULONG attrs_count = 4; michael@0: CK_OBJECT_HANDLE pmk_obj = CK_INVALID_HANDLE; michael@0: CK_OBJECT_HANDLE mk_obj = CK_INVALID_HANDLE; michael@0: CK_SSL3_MASTER_KEY_DERIVE_PARAMS mkd_params; michael@0: CK_MECHANISM skmd_mech; michael@0: michael@0: CK_BBOOL isDH = false; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: attrs[0].type = CKA_CLASS; michael@0: attrs[0].pValue = &class; michael@0: attrs[0].ulValueLen = sizeof (class); michael@0: attrs[1].type = CKA_KEY_TYPE; michael@0: attrs[1].pValue = &type; michael@0: attrs[1].ulValueLen = sizeof (type); michael@0: attrs[2].type = CKA_DERIVE; michael@0: attrs[2].pValue = &derive_bool; michael@0: attrs[2].ulValueLen = sizeof (derive_bool); michael@0: attrs[3].type = CKA_VALUE; michael@0: attrs[3].pValue = NULL; michael@0: attrs[3].ulValueLen = 0; michael@0: michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Before all, check if the mechanism is supported correctly */ michael@0: if (MODE == FIPSMODE) { michael@0: crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE, false, michael@0: 0, 0); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "PKM_MechCheck failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return (crv); michael@0: } michael@0: } michael@0: michael@0: mk_mech.mechanism = mechType; michael@0: mk_mech.pParameter = &mkd_params; michael@0: mk_mech.ulParameterLen = sizeof (mkd_params); michael@0: michael@0: switch (mechType) { michael@0: case CKM_TLS_MASTER_KEY_DERIVE_DH: michael@0: isDH = true; michael@0: /* FALLTHRU */ michael@0: case CKM_TLS_MASTER_KEY_DERIVE: michael@0: attrs[3].pValue = NULL; michael@0: attrs[3].ulValueLen = 0; michael@0: expected_version.major = 3; michael@0: expected_version.minor = 1; michael@0: michael@0: mkd_params.RandomInfo.pClientRandom = (unsigned char * ) TLSClientRandom; michael@0: mkd_params.RandomInfo.ulClientRandomLen = michael@0: sizeof (TLSClientRandom); michael@0: mkd_params.RandomInfo.pServerRandom = (unsigned char * ) TLSServerRandom; michael@0: mkd_params.RandomInfo.ulServerRandomLen = michael@0: sizeof (TLSServerRandom); michael@0: break; michael@0: } michael@0: mkd_params.pVersion = (!isDH) ? &version : NULL; michael@0: michael@0: /* First create the pre-master secret key */ michael@0: michael@0: skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN; michael@0: skmd_mech.pParameter = &mkd_params; michael@0: skmd_mech.ulParameterLen = sizeof (mkd_params); michael@0: michael@0: michael@0: crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech, michael@0: attrs, michael@0: attrs_count, michael@0: &pmk_obj); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateKey succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: michael@0: } michael@0: /* Test the bad cases */ michael@0: switch (rnd) { michael@0: case CORRECT: michael@0: goto correct; michael@0: michael@0: case BOGUS_CLIENT_RANDOM: michael@0: mkd_params.RandomInfo.pClientRandom = NULL; michael@0: break; michael@0: michael@0: case BOGUS_CLIENT_RANDOM_LEN: michael@0: mkd_params.RandomInfo.ulClientRandomLen = 0; michael@0: break; michael@0: michael@0: case BOGUS_SERVER_RANDOM: michael@0: mkd_params.RandomInfo.pServerRandom = NULL; michael@0: break; michael@0: michael@0: case BOGUS_SERVER_RANDOM_LEN: michael@0: mkd_params.RandomInfo.ulServerRandomLen = 0; michael@0: break; michael@0: } michael@0: crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0, michael@0: &mk_obj); michael@0: if (crv != CKR_MECHANISM_PARAM_INVALID) { michael@0: PKM_LogIt( "C_DeriveKey returned as EXPECTED with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: } else { michael@0: PKM_Error( "C_DeriveKey did not fail with bad data \n" ); michael@0: } michael@0: goto out; michael@0: michael@0: michael@0: correct: michael@0: /* Now derive the master secret key */ michael@0: crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0, michael@0: &mk_obj); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_DeriveKey succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_DeriveKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: out: michael@0: if (pmk_obj != CK_INVALID_HANDLE) michael@0: (void) pFunctionList->C_DestroyObject(hSession, pmk_obj); michael@0: if (mk_obj != CK_INVALID_HANDLE) michael@0: (void) pFunctionList->C_DestroyObject(hSession, mk_obj); michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: return (crv); michael@0: } michael@0: michael@0: michael@0: CK_RV michael@0: PKM_TLSKeyAndMacDerive( CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SLOT_ID * pSlotList, CK_ULONG slotID, michael@0: CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, michael@0: CK_MECHANISM_TYPE mechType, enum_random_t rnd) michael@0: { michael@0: CK_SESSION_HANDLE hSession; michael@0: CK_RV crv; michael@0: CK_MECHANISM kmd_mech; michael@0: CK_MECHANISM skmd_mech; michael@0: CK_OBJECT_CLASS class = CKO_SECRET_KEY; michael@0: CK_KEY_TYPE type = CKK_GENERIC_SECRET; michael@0: CK_BBOOL derive_bool = true; michael@0: CK_BBOOL sign_bool = true, verify_bool = true; michael@0: CK_BBOOL encrypt_bool = true, decrypt_bool = true; michael@0: CK_ULONG value_len; michael@0: michael@0: /* michael@0: * We arrange this template so that: michael@0: * . Attributes 0-6 are good for a MAC key comparison template. michael@0: * . Attributes 2-5 are good for the master key creation template. michael@0: * . Attributes 3-8 are good for a cipher key comparison template. michael@0: */ michael@0: CK_ATTRIBUTE attrs[9]; michael@0: michael@0: CK_OBJECT_HANDLE mk_obj = CK_INVALID_HANDLE; michael@0: CK_SSL3_KEY_MAT_PARAMS km_params; michael@0: CK_SSL3_KEY_MAT_OUT kmo; michael@0: CK_BYTE IVClient[8]; michael@0: CK_BYTE IVServer[8]; michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: attrs[0].type = CKA_SIGN; michael@0: attrs[0].pValue = &sign_bool; michael@0: attrs[0].ulValueLen = sizeof (sign_bool); michael@0: attrs[1].type = CKA_VERIFY; michael@0: attrs[1].pValue = &verify_bool; michael@0: attrs[1].ulValueLen = sizeof (verify_bool); michael@0: attrs[2].type = CKA_KEY_TYPE; michael@0: attrs[2].pValue = &type; michael@0: attrs[2].ulValueLen = sizeof (type); michael@0: attrs[3].type = CKA_CLASS; michael@0: attrs[3].pValue = &class; michael@0: attrs[3].ulValueLen = sizeof (class); michael@0: attrs[4].type = CKA_DERIVE; michael@0: attrs[4].pValue = &derive_bool; michael@0: attrs[4].ulValueLen = sizeof (derive_bool); michael@0: attrs[5].type = CKA_VALUE; michael@0: attrs[5].pValue = NULL; michael@0: attrs[5].ulValueLen = 0; michael@0: attrs[6].type = CKA_VALUE_LEN; michael@0: attrs[6].pValue = &value_len; michael@0: attrs[6].ulValueLen = sizeof (value_len); michael@0: attrs[7].type = CKA_ENCRYPT; michael@0: attrs[7].pValue = &encrypt_bool; michael@0: attrs[7].ulValueLen = sizeof (encrypt_bool); michael@0: attrs[8].type = CKA_DECRYPT; michael@0: attrs[8].pValue = &decrypt_bool; michael@0: attrs[8].ulValueLen = sizeof (decrypt_bool); michael@0: michael@0: crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION, michael@0: NULL, NULL, &hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Login with correct password succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Login with correct password failed " michael@0: "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: /* Before all, check if the mechanism is supported correctly */ michael@0: if (MODE == FIPSMODE) { michael@0: crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE, michael@0: CK_TRUE, 48, 48); michael@0: michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "PKM_MechCheck failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return (crv); michael@0: } michael@0: } michael@0: kmd_mech.mechanism = mechType; michael@0: kmd_mech.pParameter = &km_params; michael@0: kmd_mech.ulParameterLen = sizeof (km_params); michael@0: michael@0: km_params.ulMacSizeInBits = 128; /* an MD5 based MAC */ michael@0: km_params.ulKeySizeInBits = 192; /* 3DES key size */ michael@0: km_params.ulIVSizeInBits = 64; /* 3DES block size */ michael@0: km_params.pReturnedKeyMaterial = &kmo; michael@0: km_params.bIsExport = false; michael@0: kmo.hClientMacSecret = CK_INVALID_HANDLE; michael@0: kmo.hServerMacSecret = CK_INVALID_HANDLE; michael@0: kmo.hClientKey = CK_INVALID_HANDLE; michael@0: kmo.hServerKey = CK_INVALID_HANDLE; michael@0: kmo.pIVClient = IVClient; michael@0: kmo.pIVServer = IVServer; michael@0: michael@0: skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN; michael@0: skmd_mech.pParameter = &km_params; michael@0: skmd_mech.ulParameterLen = sizeof (km_params); michael@0: michael@0: michael@0: crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech, michael@0: &attrs[2], michael@0: 4, michael@0: &mk_obj); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_GenerateKey succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: attrs[5].pValue = NULL; michael@0: attrs[5].ulValueLen = 0; michael@0: michael@0: km_params.RandomInfo.pClientRandom = (unsigned char *) TLSClientRandom; michael@0: km_params.RandomInfo.ulClientRandomLen = michael@0: sizeof (TLSClientRandom); michael@0: km_params.RandomInfo.pServerRandom = (unsigned char *) TLSServerRandom; michael@0: km_params.RandomInfo.ulServerRandomLen = michael@0: sizeof (TLSServerRandom); michael@0: michael@0: /* Test the bad cases */ michael@0: switch (rnd) { michael@0: case CORRECT: michael@0: goto correct; michael@0: michael@0: case BOGUS_CLIENT_RANDOM: michael@0: km_params.RandomInfo.pClientRandom = NULL; michael@0: break; michael@0: michael@0: case BOGUS_CLIENT_RANDOM_LEN: michael@0: km_params.RandomInfo.ulClientRandomLen = 0; michael@0: break; michael@0: michael@0: case BOGUS_SERVER_RANDOM: michael@0: km_params.RandomInfo.pServerRandom = NULL; michael@0: break; michael@0: michael@0: case BOGUS_SERVER_RANDOM_LEN: michael@0: km_params.RandomInfo.ulServerRandomLen = 0; michael@0: break; michael@0: } michael@0: crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0, michael@0: NULL); michael@0: if (crv != CKR_MECHANISM_PARAM_INVALID) { michael@0: PKM_Error( "key materials derivation returned unexpected " michael@0: "error 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); michael@0: (void) pFunctionList->C_DestroyObject(hSession, mk_obj); michael@0: return (CKR_FUNCTION_FAILED); michael@0: michael@0: } michael@0: return (CKR_OK); michael@0: michael@0: correct: michael@0: /* michael@0: * Then use the master key and the client 'n server random data to michael@0: * derive the key materials michael@0: */ michael@0: crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0, michael@0: NULL); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "Cannot derive the key materials, crv 0x%08X, %-26s\n", michael@0: crv, PKM_CK_RVtoStr(crv)); michael@0: (void) pFunctionList->C_DestroyObject(hSession, mk_obj); michael@0: return (crv); michael@0: } michael@0: michael@0: if (mk_obj != CK_INVALID_HANDLE) michael@0: (void) pFunctionList->C_DestroyObject(hSession, mk_obj); michael@0: if (kmo.hClientMacSecret != CK_INVALID_HANDLE) michael@0: (void) pFunctionList->C_DestroyObject(hSession, kmo.hClientMacSecret); michael@0: if (kmo.hServerMacSecret != CK_INVALID_HANDLE) michael@0: (void) pFunctionList->C_DestroyObject(hSession, kmo.hServerMacSecret); michael@0: if (kmo.hClientKey != CK_INVALID_HANDLE) michael@0: (void) pFunctionList->C_DestroyObject(hSession, kmo.hClientKey); michael@0: if (kmo.hServerKey != CK_INVALID_HANDLE) michael@0: (void) pFunctionList->C_DestroyObject(hSession, kmo.hServerKey); michael@0: michael@0: crv = pFunctionList->C_Logout(hSession); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_Logout succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_CloseSession(hSession); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: return (crv); michael@0: } michael@0: michael@0: CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hRwSession, michael@0: CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey, michael@0: CK_MECHANISM *sigMech, michael@0: CK_OBJECT_HANDLE secretKey, CK_MECHANISM *cryptMech, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen) { michael@0: michael@0: CK_RV crv = CKR_OK; michael@0: CK_BYTE encryptedData[MAX_CIPHER_SZ]; michael@0: CK_ULONG ulEncryptedDataLen = 0; michael@0: CK_ULONG ulLastUpdateSize = 0 ; michael@0: CK_BYTE sig[MAX_SIG_SZ]; michael@0: CK_ULONG ulSigLen = 0; michael@0: CK_BYTE data[MAX_DATA_SZ]; michael@0: CK_ULONG ulDataLen = 0; michael@0: michael@0: memset(encryptedData, 0, sizeof(encryptedData)); michael@0: memset(sig, 0, sizeof(sig)); michael@0: memset(data, 0, sizeof(data)); michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: /* Check that the mechanism is Multi-part */ michael@0: if (sigMech->mechanism == CKM_DSA || sigMech->mechanism == CKM_RSA_PKCS) { michael@0: PKM_Error( "PKM_DualFuncSign must be called with a Multi-part " michael@0: "operation mechanism\n"); michael@0: return CKR_DEVICE_ERROR; michael@0: } michael@0: michael@0: /* Sign and Encrypt */ michael@0: if (privateKey == 0 && publicKey == 0) { michael@0: crv = pFunctionList->C_SignInit(hRwSession, sigMech, secretKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: } else { michael@0: crv = pFunctionList->C_SignInit(hRwSession, sigMech, privateKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: } michael@0: crv = pFunctionList->C_EncryptInit(hRwSession, cryptMech, secretKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: ulEncryptedDataLen = sizeof(encryptedData); michael@0: crv = pFunctionList->C_SignEncryptUpdate(hRwSession, (CK_BYTE * ) pData, michael@0: pDataLen, michael@0: encryptedData, michael@0: &ulEncryptedDataLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: ulLastUpdateSize = sizeof(encryptedData) - ulEncryptedDataLen; michael@0: crv = pFunctionList->C_EncryptFinal(hRwSession, michael@0: (CK_BYTE * )&encryptedData[ulEncryptedDataLen], &ulLastUpdateSize); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_EncryptFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: ulEncryptedDataLen = ulEncryptedDataLen + ulLastUpdateSize; michael@0: ulSigLen = sizeof(sig); michael@0: crv = pFunctionList->C_SignFinal(hRwSession, sig, &ulSigLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_SignFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Decrypt and Verify */ michael@0: michael@0: crv = pFunctionList->C_DecryptInit(hRwSession, cryptMech, secretKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: crv = pFunctionList->C_VerifyInit(hRwSession, sigMech, michael@0: publicKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: ulDataLen = sizeof(data); michael@0: crv = pFunctionList->C_DecryptVerifyUpdate(hRwSession, michael@0: encryptedData, michael@0: ulEncryptedDataLen, michael@0: data, &ulDataLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptVerifyUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: ulLastUpdateSize = sizeof(data) - ulDataLen; michael@0: /* Get last little piece of plaintext. Should have length 0 */ michael@0: crv = pFunctionList->C_DecryptFinal(hRwSession, &data[ulDataLen], michael@0: &ulLastUpdateSize); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if (ulLastUpdateSize != 0) { michael@0: crv = pFunctionList->C_VerifyUpdate(hRwSession, &data[ulDataLen], michael@0: ulLastUpdateSize); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: } michael@0: ulDataLen = ulDataLen + ulLastUpdateSize; michael@0: michael@0: /* input for the verify operation is the decrypted data */ michael@0: crv = pFunctionList->C_VerifyFinal(hRwSession, sig, ulSigLen); michael@0: if (crv == CKR_OK) { michael@0: PKM_LogIt("C_VerifyFinal succeeded\n"); michael@0: } else { michael@0: PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* Comparison of Decrypted data with inputed data */ michael@0: if ( (ulDataLen == pDataLen) && michael@0: (memcmp(data, pData, pDataLen) == 0) ) { michael@0: PKM_LogIt("PKM_DualFuncSign decrypt test case passed\n"); michael@0: } else { michael@0: PKM_Error( "PKM_DualFuncSign derypt test case failed\n"); michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList, michael@0: CK_SESSION_HANDLE hSession, michael@0: CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey, michael@0: const CK_BYTE * pData, CK_ULONG pDataLen) { michael@0: CK_RV crv = CKR_OK; michael@0: CK_BYTE digest1[MAX_DIGEST_SZ]; michael@0: CK_ULONG digest1Len = 0 ; michael@0: CK_BYTE digest2[MAX_DIGEST_SZ]; michael@0: CK_ULONG digest2Len = 0; michael@0: michael@0: /* Tested with CKM_SHA_1, CKM_SHA224, CKM_SHA256, CKM_SHA384, CKM_SHA512 */ michael@0: michael@0: memset(digest1, 0, sizeof(digest1)); michael@0: memset(digest2, 0, sizeof(digest2)); michael@0: michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: michael@0: crv = pFunctionList->C_DigestInit(hSession, digestMech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: digest1Len = sizeof(digest1); michael@0: crv = pFunctionList->C_Digest(hSession, (CK_BYTE * ) pData, pDataLen, michael@0: digest1, &digest1Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: michael@0: crv = pFunctionList->C_DigestInit(hSession, digestMech); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE * ) pData, pDataLen); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestUpdate failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: /* C_DigestKey continues a multiple-part message-digesting operation by*/ michael@0: /* digesting the value of a secret key. (only used with C_DigestUpdate)*/ michael@0: if (hSecretKey != 0) { michael@0: crv = pFunctionList->C_DigestKey(hSession, hSecretKey); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestKey failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: } michael@0: michael@0: digest2Len = sizeof(digest2); michael@0: crv = pFunctionList->C_DigestFinal(hSession, digest2, &digest2Len); michael@0: if (crv != CKR_OK) { michael@0: PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv, michael@0: PKM_CK_RVtoStr(crv)); michael@0: return crv; michael@0: } michael@0: michael@0: if (hSecretKey == 0){ michael@0: /* did not digest a secret key so digests should equal */ michael@0: if ( (digest1Len == digest2Len) michael@0: && (memcmp(digest1, digest2, digest1Len) == 0) ) { michael@0: PKM_LogIt("Single and Multiple-part message digest " michael@0: "operations successful\n"); michael@0: } else { michael@0: PKM_Error("Single and Multiple-part message digest " michael@0: "operations failed\n"); michael@0: } michael@0: } else { michael@0: if (digest1Len == digest2Len) { michael@0: PKM_LogIt("PKM_Digest Single and Multiple-part message digest " michael@0: "operations successful\n"); michael@0: } else { michael@0: PKM_Error("PKM_Digest Single and Multiple-part message digest " michael@0: "operations failed\n"); michael@0: } michael@0: michael@0: } michael@0: michael@0: return crv; michael@0: michael@0: } michael@0: michael@0: char * PKM_FilePasswd(char *pwFile) michael@0: { michael@0: unsigned char phrase[200]; michael@0: PRFileDesc *fd; michael@0: PRInt32 nb; michael@0: int i; michael@0: michael@0: if (!pwFile) michael@0: return 0; michael@0: michael@0: fd = PR_Open(pwFile, PR_RDONLY, 0); michael@0: if (!fd) { michael@0: fprintf(stderr, "No password file \"%s\" exists.\n", pwFile); michael@0: return NULL; michael@0: } michael@0: michael@0: nb = PR_Read(fd, phrase, sizeof(phrase)); michael@0: michael@0: PR_Close(fd); michael@0: /* handle the Windows EOL case */ michael@0: i = 0; michael@0: while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++; michael@0: phrase[i] = '\0'; michael@0: if (nb == 0) { michael@0: fprintf(stderr,"password file contains no data\n"); michael@0: return NULL; michael@0: } michael@0: return (char*) strdup((char*)phrase); michael@0: } michael@0: michael@0: void PKM_Help() michael@0: { michael@0: PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError); michael@0: PR_fprintf(debug_out, "pk11mode test program usage:\n"); michael@0: PR_fprintf(debug_out, "\t-f Password File : echo pw > file \n"); michael@0: PR_fprintf(debug_out, "\t-F Disable Unix fork tests\n"); michael@0: PR_fprintf(debug_out, "\t-n Non Fips Mode \n"); michael@0: PR_fprintf(debug_out, "\t-d Database path location\n"); michael@0: PR_fprintf(debug_out, "\t-p DataBase prefix\n"); michael@0: PR_fprintf(debug_out, "\t-v verbose\n"); michael@0: PR_fprintf(debug_out, "\t-h this help message\n"); michael@0: exit(1); michael@0: } michael@0: michael@0: void PKM_CheckPath(char *string) michael@0: { michael@0: char *src; michael@0: char *dest; michael@0: michael@0: /* michael@0: * windows support convert any back slashes to michael@0: * forward slashes. michael@0: */ michael@0: for (src=string, dest=string; *src; src++,dest++) { michael@0: if (*src == '\\') { michael@0: *dest = '/'; michael@0: } michael@0: } michael@0: dest--; michael@0: /* if the last char is a / set it to 0 */ michael@0: if (*dest == '/') michael@0: *dest = 0; michael@0: michael@0: } michael@0: michael@0: CK_RV PKM_ForkCheck(int expected, CK_FUNCTION_LIST_PTR fList, michael@0: PRBool forkAssert, CK_C_INITIALIZE_ARGS_NSS *initArgs) michael@0: { michael@0: CK_RV crv = CKR_OK; michael@0: #ifndef NO_FORK_CHECK michael@0: int rc = -1; michael@0: pid_t child, ret; michael@0: NUMTESTS++; /* increment NUMTESTS */ michael@0: if (forkAssert) { michael@0: putenv("NSS_STRICT_NOFORK=1"); michael@0: } else { michael@0: putenv("NSS_STRICT_NOFORK=0"); michael@0: } michael@0: child = fork(); michael@0: switch (child) { michael@0: case -1: michael@0: PKM_Error("Fork failed.\n"); michael@0: crv = CKR_DEVICE_ERROR; michael@0: break; michael@0: case 0: michael@0: if (fList) { michael@0: if (!initArgs) { michael@0: /* If softoken is loaded, make a PKCS#11 call to C_GetTokenInfo michael@0: * in the child. This call should always fail. michael@0: * If softoken is uninitialized, michael@0: * it fails with CKR_CRYPTOKI_NOT_INITIALIZED. michael@0: * If it was initialized in the parent, the fork check should michael@0: * kick in, and make it return CKR_DEVICE_ERROR. michael@0: */ michael@0: CK_RV child_crv = fList->C_GetTokenInfo(0, NULL); michael@0: exit(child_crv & 255); michael@0: } else { michael@0: /* If softoken is loaded, make a PKCS#11 call to C_Initialize michael@0: * in the child. This call should always fail. michael@0: * If softoken is uninitialized, this should succeed. michael@0: * If it was initialized in the parent, the fork check should michael@0: * kick in, and make it return CKR_DEVICE_ERROR. michael@0: */ michael@0: CK_RV child_crv = fList->C_Initialize(initArgs); michael@0: if (CKR_OK == child_crv) { michael@0: child_crv = fList->C_Finalize(NULL); michael@0: } michael@0: exit(child_crv & 255); michael@0: } michael@0: } michael@0: exit(expected & 255); michael@0: default: michael@0: PKM_LogIt("Fork succeeded.\n"); michael@0: ret = wait(&rc); michael@0: if (ret != child || (!WIFEXITED(rc)) || michael@0: ( (expected & 255) != (WEXITSTATUS(rc) & 255)) ) { michael@0: int retStatus = -1; michael@0: if (WIFEXITED(rc)) { michael@0: retStatus = WEXITSTATUS(rc); michael@0: } michael@0: PKM_Error("Child misbehaved.\n"); michael@0: printf("Child return status : %d.\n", retStatus & 255); michael@0: crv = CKR_DEVICE_ERROR; michael@0: } michael@0: break; michael@0: } michael@0: #endif michael@0: return crv; michael@0: } michael@0: