Source code

Revision control

Copy as Markdown

Other Tools

/*
* pk11mode.c - Test FIPS or NONFIPS Modes for the NSS PKCS11 api.
* The goal of this program is to test every function
* entry point of the PKCS11 api at least once.
* To test in FIPS mode: pk11mode
* To test in NONFIPS mode: pk11mode -n
* usage: pk11mode -h
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#if defined(XP_UNIX) && defined(DO_FORK_CHECK)
#include <unistd.h>
#include <sys/wait.h>
#else
#ifndef NO_FORK_CHECK
#define NO_FORK_CHECK
#endif
#endif
#ifdef _WIN32
#include <windows.h>
#define LIB_NAME "softokn3.dll"
#endif
#include "prlink.h"
#include "prprf.h"
#include "plgetopt.h"
#include "prenv.h"
#include "pk11table.h"
#define NUM_ELEM(array) (sizeof(array) / sizeof(array[0]))
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
/* Returns constant error string for "CRV".
* Returns "unknown error" if errNum is unknown.
*/
const char *
PKM_CK_RVtoStr(CK_RV errNum)
{
const char *err;
err = getName(errNum, ConstResult);
if (err)
return err;
return "unknown error";
}
#include "pkcs11p.h"
typedef struct CK_C_INITIALIZE_ARGS_NSS {
CK_CREATEMUTEX CreateMutex;
CK_DESTROYMUTEX DestroyMutex;
CK_LOCKMUTEX LockMutex;
CK_UNLOCKMUTEX UnlockMutex;
CK_FLAGS flags;
/* The official PKCS #11 spec does not have a 'LibraryParameters' field, but
* a reserved field. NSS needs a way to pass instance-specific information
* to the library (like where to find its config files, etc). This
* information is usually provided by the installer and passed uninterpreted
* by NSS to the library, though NSS does know the specifics of the softoken
* version of this parameter. Most compliant PKCS#11 modules expect this
* parameter to be NULL, and will return CKR_ARGUMENTS_BAD from
* C_Initialize if Library parameters is supplied. */
CK_CHAR_PTR *LibraryParameters;
/* This field is only present if the LibraryParameters is not NULL. It must
* be NULL in all cases */
CK_VOID_PTR pReserved;
} CK_C_INITIALIZE_ARGS_NSS;
#include "pkcs11u.h"
#define MAX_SIG_SZ 128
#define MAX_CIPHER_SZ 128
#define MAX_DATA_SZ 64
#define MAX_DIGEST_SZ 64
#define HMAC_MAX_LENGTH 64
#define FIPSMODE 0
#define NONFIPSMODE 1
#define HYBRIDMODE 2
#define NOMODE 3
int MODE = FIPSMODE;
CK_BBOOL true = CK_TRUE;
CK_BBOOL false = CK_FALSE;
static const CK_BYTE PLAINTEXT[] = { "Firefox Rules!" };
static const CK_BYTE PLAINTEXT_PAD[] = { "Firefox and thunderbird rule the world!" };
CK_ULONG NUMTESTS = 0;
static const char *slotFlagName[] = {
"CKF_TOKEN_PRESENT",
"CKF_REMOVABLE_DEVICE",
"CKF_HW_SLOT",
"unknown token flag 0x00000008",
"unknown token flag 0x00000010",
"unknown token flag 0x00000020",
"unknown token flag 0x00000040",
"unknown token flag 0x00000080",
"unknown token flag 0x00000100",
"unknown token flag 0x00000200",
"unknown token flag 0x00000400",
"unknown token flag 0x00000800",
"unknown token flag 0x00001000",
"unknown token flag 0x00002000",
"unknown token flag 0x00004000",
"unknown token flag 0x00008000"
"unknown token flag 0x00010000",
"unknown token flag 0x00020000",
"unknown token flag 0x00040000",
"unknown token flag 0x00080000",
"unknown token flag 0x00100000",
"unknown token flag 0x00200000",
"unknown token flag 0x00400000",
"unknown token flag 0x00800000"
"unknown token flag 0x01000000",
"unknown token flag 0x02000000",
"unknown token flag 0x04000000",
"unknown token flag 0x08000000",
"unknown token flag 0x10000000",
"unknown token flag 0x20000000",
"unknown token flag 0x40000000",
"unknown token flag 0x80000000"
};
static const char *tokenFlagName[] = {
"CKF_PKM_RNG",
"CKF_WRITE_PROTECTED",
"CKF_LOGIN_REQUIRED",
"CKF_USER_PIN_INITIALIZED",
"unknown token flag 0x00000010",
"CKF_RESTORE_KEY_NOT_NEEDED",
"CKF_CLOCK_ON_TOKEN",
"unknown token flag 0x00000080",
"CKF_PROTECTED_AUTHENTICATION_PATH",
"CKF_DUAL_CRYPTO_OPERATIONS",
"CKF_TOKEN_INITIALIZED",
"CKF_SECONDARY_AUTHENTICATION",
"unknown token flag 0x00001000",
"unknown token flag 0x00002000",
"unknown token flag 0x00004000",
"unknown token flag 0x00008000",
"CKF_USER_PIN_COUNT_LOW",
"CKF_USER_PIN_FINAL_TRY",
"CKF_USER_PIN_LOCKED",
"CKF_USER_PIN_TO_BE_CHANGED",
"CKF_SO_PIN_COUNT_LOW",
"CKF_SO_PIN_FINAL_TRY",
"CKF_SO_PIN_LOCKED",
"CKF_SO_PIN_TO_BE_CHANGED",
"unknown token flag 0x01000000",
"unknown token flag 0x02000000",
"unknown token flag 0x04000000",
"unknown token flag 0x08000000",
"unknown token flag 0x10000000",
"unknown token flag 0x20000000",
"unknown token flag 0x40000000",
"unknown token flag 0x80000000"
};
static const unsigned char TLSClientRandom[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0d, 0x90, 0xbb, 0x5e, 0xc6, 0xe1, 0x3f, 0x71,
0x0a, 0xa2, 0x70, 0x5a, 0x4f, 0xbc, 0x3f, 0x0d
};
static const unsigned char TLSServerRandom[] = {
0x00, 0x00, 0x1d, 0x4a, 0x7a, 0x0a, 0xa5, 0x01,
0x8e, 0x79, 0x72, 0xde, 0x9e, 0x2f, 0x8a, 0x0d,
0xed, 0xb2, 0x5d, 0xf1, 0x14, 0xc2, 0xc6, 0x66,
0x95, 0x86, 0xb0, 0x0d, 0x87, 0x2a, 0x2a, 0xc9
};
typedef enum {
CORRECT,
BOGUS_CLIENT_RANDOM,
BOGUS_CLIENT_RANDOM_LEN,
BOGUS_SERVER_RANDOM,
BOGUS_SERVER_RANDOM_LEN
} enum_random_t;
void
dumpToHash64(const unsigned char *buf, unsigned int bufLen)
{
unsigned int i;
for (i = 0; i < bufLen; i += 8) {
if (i % 32 == 0)
printf("\n");
printf(" 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,",
buf[i], buf[i + 1], buf[i + 2], buf[i + 3],
buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
}
printf("\n");
}
#ifdef _WIN32
HMODULE hModule;
#else
PRLibrary *lib;
#endif
/*
* All api that belongs to pk11mode.c layer start with the prefix PKM_
*/
void PKM_LogIt(const char *fmt, ...);
void PKM_Error(const char *fmt, ...);
CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
CK_ULONG slotID);
CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID);
CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID);
CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
CK_ULONG slotID);
CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
CK_C_INITIALIZE_ARGS_NSS *initArgs);
CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_MultiObjectManagement(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj,
CK_ATTRIBUTE_PTR expected_attrs,
CK_ULONG expected_attrs_count);
CK_RV PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hSession, CK_MECHANISM_TYPE mechType,
CK_FLAGS flags, CK_BBOOL check_sizes,
CK_ULONG minkeysize, CK_ULONG maxkeysize);
CK_RV PKM_TLSKeyAndMacDerive(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
CK_MECHANISM_TYPE mechType, enum_random_t rnd);
CK_RV PKM_TLSMasterKeyDerive(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
CK_MECHANISM_TYPE mechType,
enum_random_t rnd);
CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hRwSession,
CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey,
CK_MECHANISM *sigMech, CK_OBJECT_HANDLE secretKey,
CK_MECHANISM *cryptMech,
const CK_BYTE *pData, CK_ULONG pDataLen);
CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech,
CK_OBJECT_HANDLE hSecKeyDigest,
CK_MECHANISM *digestMech,
const CK_BYTE *pData, CK_ULONG pDataLen);
CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hRwSession,
CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
CK_MECHANISM *signMech, const CK_BYTE *pData,
CK_ULONG dataLen);
CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech,
const CK_BYTE *pData, CK_ULONG dataLen);
CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech,
const CK_BYTE *pData, CK_ULONG pDataLen);
CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hRwSession,
CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey,
const CK_BYTE *pData, CK_ULONG pDataLen);
CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hPublicKey,
CK_OBJECT_HANDLE hPrivateKey,
CK_MECHANISM *wrapMechanism,
CK_OBJECT_HANDLE hSecretKey,
CK_ATTRIBUTE *sKeyTemplate,
CK_ULONG skeyTempSize);
CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
CK_MECHANISM *signMech, const CK_BYTE *pData,
CK_ULONG pDataLen);
CK_RV PKM_ForkCheck(int expected, CK_FUNCTION_LIST_PTR fList,
PRBool forkAssert, CK_C_INITIALIZE_ARGS_NSS *initArgs);
void PKM_Help();
void PKM_CheckPath(char *string);
char *PKM_FilePasswd(char *pwFile);
static PRBool verbose = PR_FALSE;
int
main(int argc, char **argv)
{
CK_C_GetFunctionList pC_GetFunctionList;
CK_FUNCTION_LIST_PTR pFunctionList;
CK_RV crv = CKR_OK;
CK_C_INITIALIZE_ARGS_NSS initArgs;
CK_C_INITIALIZE_ARGS_NSS initArgsRerun; /* rerun selftests */
CK_SLOT_ID *pSlotList = NULL;
CK_TOKEN_INFO tokenInfo;
CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */
CK_UTF8CHAR *pwd = NULL;
CK_ULONG pwdLen = 0;
char *moduleSpec = NULL;
char *moduleSpecRerun = NULL;
char *configDir = NULL;
char *dbPrefix = NULL;
char *disableUnload = NULL;
PRBool doForkTests = PR_TRUE;
PLOptStatus os;
PLOptState *opt = PL_CreateOptState(argc, argv, "nvhf:Fd:p:");
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
if (PL_OPT_BAD == os)
continue;
switch (opt->option) {
case 'F': /* disable fork tests */
doForkTests = PR_FALSE;
break;
case 'n': /* non fips mode */
MODE = NONFIPSMODE;
slotID = 1;
break;
case 'f': /* password file */
pwd = (CK_UTF8CHAR *)PKM_FilePasswd((char *)opt->value);
if (!pwd)
PKM_Help();
break;
case 'd': /* opt_CertDir */
if (!opt->value)
PKM_Help();
configDir = strdup(opt->value);
PKM_CheckPath(configDir);
break;
case 'p': /* opt_DBPrefix */
if (!opt->value)
PKM_Help();
dbPrefix = strdup(opt->value);
break;
case 'v':
verbose = PR_TRUE;
break;
case 'h': /* help message */
default:
PKM_Help();
break;
}
}
PL_DestroyOptState(opt);
if (!pwd) {
pwd = (CK_UTF8CHAR *)strdup("1Mozilla");
}
pwdLen = strlen((const char *)pwd);
if (!configDir) {
configDir = strdup(".");
}
if (!dbPrefix) {
dbPrefix = strdup("");
}
if (doForkTests) {
/* first, try to fork without softoken loaded to make sure
* everything is OK */
crv = PKM_ForkCheck(123, NULL, PR_FALSE, NULL);
if (crv != CKR_OK)
goto cleanup;
}
#ifdef _WIN32
hModule = LoadLibrary(LIB_NAME);
if (hModule == NULL) {
PKM_Error("cannot load %s\n", LIB_NAME);
goto cleanup;
}
if (MODE == FIPSMODE) {
/* FIPS mode == FC_GetFunctionList */
pC_GetFunctionList = (CK_C_GetFunctionList)
GetProcAddress(hModule, "FC_GetFunctionList");
} else {
/* NON FIPS mode == C_GetFunctionList */
pC_GetFunctionList = (CK_C_GetFunctionList)
GetProcAddress(hModule, "C_GetFunctionList");
}
if (pC_GetFunctionList == NULL) {
PKM_Error("cannot load %s\n", LIB_NAME);
goto cleanup;
}
#else
{
char *libname = NULL;
/* Get the platform-dependent library name of the NSS cryptographic module */
libname = PR_GetLibraryName(NULL, "softokn3");
assert(libname != NULL);
lib = PR_LoadLibrary(libname);
assert(lib != NULL);
PR_FreeLibraryName(libname);
}
if (MODE == FIPSMODE) {
pC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
"FC_GetFunctionList");
assert(pC_GetFunctionList != NULL);
slotID = 0;
} else {
pC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
"C_GetFunctionList");
assert(pC_GetFunctionList != NULL);
slotID = 1;
}
#endif
if (MODE == FIPSMODE) {
printf("Loaded FC_GetFunctionList for FIPS MODE; slotID %d \n",
(int)slotID);
} else {
printf("loaded C_GetFunctionList for NON FIPS MODE; slotID %d \n",
(int)slotID);
}
crv = (*pC_GetFunctionList)(&pFunctionList);
assert(crv == CKR_OK);
if (doForkTests) {
/* now, try to fork with softoken loaded, but not initialized */
crv = PKM_ForkCheck(CKR_CRYPTOKI_NOT_INITIALIZED, pFunctionList,
PR_TRUE, NULL);
if (crv != CKR_OK)
goto cleanup;
}
initArgs.CreateMutex = NULL;
initArgs.DestroyMutex = NULL;
initArgs.LockMutex = NULL;
initArgs.UnlockMutex = NULL;
initArgs.flags = CKF_OS_LOCKING_OK;
moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' "
"keyPrefix='%s' secmod='secmod.db' flags= ",
configDir, dbPrefix, dbPrefix);
moduleSpecRerun = PR_smprintf("configdir='%s' certPrefix='%s' "
"keyPrefix='%s' secmod='secmod.db' flags=forcePOST ",
configDir, dbPrefix, dbPrefix);
initArgs.LibraryParameters = (CK_CHAR_PTR *)moduleSpec;
initArgs.pReserved = NULL;
initArgsRerun = initArgs;
initArgsRerun.LibraryParameters = (CK_CHAR_PTR *)moduleSpecRerun;
/*DebugBreak();*/
/* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */
/* NSS cryptographic module library initialization for the FIPS */
/* Approved mode when FC_Initialize is envoked will perfom */
/* software integrity test, and power-up self-tests before */
/* FC_Initialize returns */
crv = pFunctionList->C_Initialize(&initArgs);
if (crv == CKR_OK) {
PKM_LogIt("C_Initialize succeeded\n");
} else {
PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
if (doForkTests) {
/* Disable core on fork for this test, since we are testing the
* pathological case, and if enabled, the child process would dump
* core in C_GetTokenInfo .
* We can still differentiate the correct from incorrect behavior
* by the PKCS#11 return code.
*/
/* try to fork with softoken both loaded and initialized */
crv = PKM_ForkCheck(CKR_DEVICE_ERROR, pFunctionList, PR_FALSE, NULL);
if (crv != CKR_OK)
goto cleanup;
}
if (doForkTests) {
/* In this next test, we fork and try to re-initialize softoken in
* the child. This should now work because softoken has the ability
* to hard reset.
*/
/* try to fork with softoken both loaded and initialized */
crv = PKM_ForkCheck(CKR_OK, pFunctionList, PR_TRUE, &initArgs);
if (crv != CKR_OK)
goto cleanup;
}
crv = PKM_ShowInfo(pFunctionList, slotID);
if (crv == CKR_OK) {
PKM_LogIt("PKM_ShowInfo succeeded\n");
} else {
PKM_Error("PKM_ShowInfo failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
pSlotList = PKM_GetSlotList(pFunctionList, slotID);
if (pSlotList == NULL) {
PKM_Error("PKM_GetSlotList failed with \n");
goto cleanup;
}
crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
if (crv == CKR_OK) {
PKM_LogIt("C_GetTokenInfo succeeded\n\n");
} else {
PKM_Error("C_GetTokenInfo failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
if (!(tokenInfo.flags & CKF_USER_PIN_INITIALIZED)) {
PKM_LogIt("Initing PW for DB\n");
crv = PKM_InitPWforDB(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_InitPWforDB succeeded\n\n");
} else {
PKM_Error("PKM_InitPWforDB failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
} else {
PKM_LogIt("using existing DB\n");
}
/* general mechanism by token */
crv = PKM_Mechanism(pFunctionList, pSlotList, slotID);
if (crv == CKR_OK) {
PKM_LogIt("PKM_Mechanism succeeded\n\n");
} else {
PKM_Error("PKM_Mechanism failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
/* RNG example without Login */
crv = PKM_RNG(pFunctionList, pSlotList, slotID);
if (crv == CKR_OK) {
PKM_LogIt("PKM_RNG succeeded\n\n");
} else {
PKM_Error("PKM_RNG failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_SessionLogin(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_SessionLogin succeeded\n\n");
} else {
PKM_Error("PKM_SessionLogin failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
/*
* PKM_KeyTest creates RSA,DSA public keys
* and AES, DES3 secret keys.
* then does digest, hmac, encrypt/decrypt, signing operations.
*/
crv = PKM_KeyTests(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_KeyTests succeeded\n\n");
} else {
PKM_Error("PKM_KeyTest failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_SecretKey(pFunctionList, pSlotList, slotID, pwd,
pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_SecretKey succeeded\n\n");
} else {
PKM_Error("PKM_SecretKey failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_PublicKey(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_PublicKey succeeded\n\n");
} else {
PKM_Error("PKM_PublicKey failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_OperationalState(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_OperationalState succeeded\n\n");
} else {
PKM_Error("PKM_OperationalState failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_MultiObjectManagement(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_MultiObjectManagement succeeded\n\n");
} else {
PKM_Error("PKM_MultiObjectManagement failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_LegacyFunctions(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_LegacyFunctions succeeded\n\n");
} else {
PKM_Error("PKM_LegacyFunctions failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_TLSKeyAndMacDerive(pFunctionList, pSlotList, slotID,
pwd, pwdLen,
CKM_TLS_KEY_AND_MAC_DERIVE, CORRECT);
if (crv == CKR_OK) {
PKM_LogIt("PKM_TLSKeyAndMacDerive succeeded\n\n");
} else {
PKM_Error("PKM_TLSKeyAndMacDerive failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
pwd, pwdLen,
CKM_TLS_MASTER_KEY_DERIVE,
CORRECT);
if (crv == CKR_OK) {
PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
} else {
PKM_Error("PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
pwd, pwdLen,
CKM_TLS_MASTER_KEY_DERIVE_DH,
CORRECT);
if (crv == CKR_OK) {
PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
} else {
PKM_Error("PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = PKM_FindAllObjects(pFunctionList, pSlotList, slotID,
pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("PKM_FindAllObjects succeeded\n\n");
} else {
PKM_Error("PKM_FindAllObjects failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = pFunctionList->C_Finalize(NULL);
if (crv == CKR_OK) {
PKM_LogIt("C_Finalize succeeded\n");
} else {
PKM_Error("C_Finalize failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
if (doForkTests) {
/* try to fork with softoken still loaded, but de-initialized */
crv = PKM_ForkCheck(CKR_CRYPTOKI_NOT_INITIALIZED, pFunctionList,
PR_TRUE, NULL);
if (crv != CKR_OK)
goto cleanup;
}
free(pSlotList);
/* demonstrate how an application can be in Hybrid mode */
/* PKM_HybridMode shows how to switch between NONFIPS */
/* mode to FIPS mode */
PKM_LogIt("Testing Hybrid mode \n");
crv = PKM_HybridMode(pwd, pwdLen, &initArgs);
if (crv == CKR_OK) {
PKM_LogIt("PKM_HybridMode succeeded\n");
} else {
PKM_Error("PKM_HybridMode failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
if (doForkTests) {
/* testing one more C_Initialize / C_Finalize to exercise getpid()
* fork check code */
crv = pFunctionList->C_Initialize(&initArgsRerun);
if (crv == CKR_OK) {
PKM_LogIt("C_Initialize succeeded\n");
} else {
PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
crv = pFunctionList->C_Finalize(NULL);
if (crv == CKR_OK) {
PKM_LogIt("C_Finalize succeeded\n");
} else {
PKM_Error("C_Finalize failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
goto cleanup;
}
/* try to C_Initialize / C_Finalize in child. This should succeed */
crv = PKM_ForkCheck(CKR_OK, pFunctionList, PR_TRUE, &initArgs);
}
PKM_LogIt("unloading NSS PKCS # 11 softoken and exiting\n");
cleanup:
if (pwd) {
free(pwd);
}
if (configDir) {
free(configDir);
}
if (dbPrefix) {
free(dbPrefix);
}
if (moduleSpec) {
PR_smprintf_free(moduleSpec);
}
if (moduleSpecRerun) {
PR_smprintf_free(moduleSpecRerun);
}
#ifdef _WIN32
FreeLibrary(hModule);
#else
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
if (!disableUnload) {
PR_UnloadLibrary(lib);
}
#endif
if (CKR_OK == crv && doForkTests && !disableUnload) {
/* try to fork with softoken both de-initialized and unloaded */
crv = PKM_ForkCheck(123, NULL, PR_TRUE, NULL);
}
printf("**** Total number of TESTS ran in %s is %d. ****\n",
((MODE == FIPSMODE) ? "FIPS MODE" : "NON FIPS MODE"), (int)NUMTESTS);
if (CKR_OK == crv) {
printf("**** ALL TESTS PASSED ****\n");
}
return crv;
}
/*
* PKM_KeyTests
*
*
*/
CK_RV
PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
{
CK_SESSION_HANDLE hRwSession;
CK_RV crv = CKR_OK;
/*** DSA Key ***/
CK_MECHANISM dsaParamGenMech;
CK_ULONG primeBits = 1024;
CK_ATTRIBUTE dsaParamGenTemplate[1];
CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE;
CK_BYTE DSA_P[128];
CK_BYTE DSA_Q[20];
CK_BYTE DSA_G[128];
CK_MECHANISM dsaKeyPairGenMech;
CK_ATTRIBUTE dsaPubKeyTemplate[5];
CK_ATTRIBUTE dsaPrivKeyTemplate[5];
CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
/**** RSA Key ***/
CK_KEY_TYPE rsatype = CKK_RSA;
CK_MECHANISM rsaKeyPairGenMech;
CK_BYTE subject[] = { "RSA Private Key" };
CK_ULONG modulusBits = 1024;
CK_BYTE publicExponent[] = { 0x01, 0x00, 0x01 };
CK_BYTE id[] = { "RSA123" };
CK_ATTRIBUTE rsaPubKeyTemplate[9];
CK_ATTRIBUTE rsaPrivKeyTemplate[11];
CK_OBJECT_HANDLE hRSApubKey = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE hRSAprivKey = CK_INVALID_HANDLE;
/*** AES Key ***/
CK_MECHANISM sAESKeyMech = {
CKM_AES_KEY_GEN, NULL, 0
};
CK_OBJECT_CLASS class = CKO_SECRET_KEY;
CK_KEY_TYPE keyAESType = CKK_AES;
CK_UTF8CHAR AESlabel[] = "An AES secret key object";
CK_ULONG AESvalueLen = 32;
CK_ATTRIBUTE sAESKeyTemplate[9];
CK_OBJECT_HANDLE hAESSecKey;
/*** DES3 Key ***/
CK_KEY_TYPE keyDES3Type = CKK_DES3;
CK_UTF8CHAR DES3label[] = "An Triple DES secret key object";
CK_ULONG DES3valueLen = 56;
CK_MECHANISM sDES3KeyGenMechanism = {
CKM_DES3_KEY_GEN, NULL, 0
};
CK_ATTRIBUTE sDES3KeyTemplate[9];
CK_OBJECT_HANDLE hDES3SecKey;
CK_MECHANISM dsaWithSha1Mech = {
CKM_DSA_SHA1, NULL, 0
};
CK_BYTE IV[16];
CK_MECHANISM mech_DES3_CBC;
CK_MECHANISM mech_DES3_CBC_PAD;
CK_MECHANISM mech_AES_CBC_PAD;
CK_MECHANISM mech_AES_CBC;
struct mech_str {
CK_ULONG mechanism;
const char *mechanismStr;
};
typedef struct mech_str mech_str;
mech_str digestMechs[] = {
{ CKM_SHA_1, "CKM_SHA_1 " },
{ CKM_SHA224, "CKM_SHA224" },
{ CKM_SHA256, "CKM_SHA256" },
{ CKM_SHA384, "CKM_SHA384" },
{ CKM_SHA512, "CKM_SHA512" }
};
mech_str hmacMechs[] = {
{ CKM_SHA_1_HMAC, "CKM_SHA_1_HMAC" },
{ CKM_SHA224_HMAC, "CKM_SHA224_HMAC" },
{ CKM_SHA256_HMAC, "CKM_SHA256_HMAC" },
{ CKM_SHA384_HMAC, "CKM_SHA384_HMAC" },
{ CKM_SHA512_HMAC, "CKM_SHA512_HMAC" }
};
mech_str sigRSAMechs[] = {
{ CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS" },
{ CKM_SHA224_RSA_PKCS, "CKM_SHA224_RSA_PKCS" },
{ CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS" },
{ CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS" },
{ CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS" }
};
CK_ULONG digestMechsSZ = NUM_ELEM(digestMechs);
CK_ULONG sigRSAMechsSZ = NUM_ELEM(sigRSAMechs);
CK_ULONG hmacMechsSZ = NUM_ELEM(hmacMechs);
CK_MECHANISM mech;
unsigned int i;
NUMTESTS++; /* increment NUMTESTS */
/* DSA key init */
dsaParamGenMech.mechanism = CKM_DSA_PARAMETER_GEN;
dsaParamGenMech.pParameter = NULL_PTR;
dsaParamGenMech.ulParameterLen = 0;
dsaParamGenTemplate[0].type = CKA_PRIME_BITS;
dsaParamGenTemplate[0].pValue = &primeBits;
dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits);
dsaPubKeyTemplate[0].type = CKA_PRIME;
dsaPubKeyTemplate[0].pValue = DSA_P;
dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P);
dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
dsaPubKeyTemplate[1].pValue = DSA_Q;
dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q);
dsaPubKeyTemplate[2].type = CKA_BASE;
dsaPubKeyTemplate[2].pValue = DSA_G;
dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G);
dsaPubKeyTemplate[3].type = CKA_TOKEN;
dsaPubKeyTemplate[3].pValue = &true;
dsaPubKeyTemplate[3].ulValueLen = sizeof(true);
dsaPubKeyTemplate[4].type = CKA_VERIFY;
dsaPubKeyTemplate[4].pValue = &true;
dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN;
dsaKeyPairGenMech.pParameter = NULL_PTR;
dsaKeyPairGenMech.ulParameterLen = 0;
dsaPrivKeyTemplate[0].type = CKA_TOKEN;
dsaPrivKeyTemplate[0].pValue = &true;
dsaPrivKeyTemplate[0].ulValueLen = sizeof(true);
dsaPrivKeyTemplate[1].type = CKA_PRIVATE;
dsaPrivKeyTemplate[1].pValue = &true;
dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
dsaPrivKeyTemplate[2].type = CKA_SENSITIVE;
dsaPrivKeyTemplate[2].pValue = &true;
dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
dsaPrivKeyTemplate[3].type = CKA_SIGN,
dsaPrivKeyTemplate[3].pValue = &true;
dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE;
dsaPrivKeyTemplate[4].pValue = &true;
dsaPrivKeyTemplate[4].ulValueLen = sizeof(true);
/* RSA key init */
rsaKeyPairGenMech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
rsaKeyPairGenMech.pParameter = NULL_PTR;
rsaKeyPairGenMech.ulParameterLen = 0;
rsaPubKeyTemplate[0].type = CKA_KEY_TYPE;
rsaPubKeyTemplate[0].pValue = &rsatype;
rsaPubKeyTemplate[0].ulValueLen = sizeof(rsatype);
rsaPubKeyTemplate[1].type = CKA_PRIVATE;
rsaPubKeyTemplate[1].pValue = &true;
rsaPubKeyTemplate[1].ulValueLen = sizeof(true);
rsaPubKeyTemplate[2].type = CKA_ENCRYPT;
rsaPubKeyTemplate[2].pValue = &true;
rsaPubKeyTemplate[2].ulValueLen = sizeof(true);
rsaPubKeyTemplate[3].type = CKA_DECRYPT;
rsaPubKeyTemplate[3].pValue = &true;
rsaPubKeyTemplate[3].ulValueLen = sizeof(true);
rsaPubKeyTemplate[4].type = CKA_VERIFY;
rsaPubKeyTemplate[4].pValue = &true;
rsaPubKeyTemplate[4].ulValueLen = sizeof(true);
rsaPubKeyTemplate[5].type = CKA_SIGN;
rsaPubKeyTemplate[5].pValue = &true;
rsaPubKeyTemplate[5].ulValueLen = sizeof(true);
rsaPubKeyTemplate[6].type = CKA_WRAP;
rsaPubKeyTemplate[6].pValue = &true;
rsaPubKeyTemplate[6].ulValueLen = sizeof(true);
rsaPubKeyTemplate[7].type = CKA_MODULUS_BITS;
rsaPubKeyTemplate[7].pValue = &modulusBits;
rsaPubKeyTemplate[7].ulValueLen = sizeof(modulusBits);
rsaPubKeyTemplate[8].type = CKA_PUBLIC_EXPONENT;
rsaPubKeyTemplate[8].pValue = publicExponent;
rsaPubKeyTemplate[8].ulValueLen = sizeof(publicExponent);
rsaPrivKeyTemplate[0].type = CKA_KEY_TYPE;
rsaPrivKeyTemplate[0].pValue = &rsatype;
rsaPrivKeyTemplate[0].ulValueLen = sizeof(rsatype);
rsaPrivKeyTemplate[1].type = CKA_TOKEN;
rsaPrivKeyTemplate[1].pValue = &true;
rsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
rsaPrivKeyTemplate[2].type = CKA_PRIVATE;
rsaPrivKeyTemplate[2].pValue = &true;
rsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
rsaPrivKeyTemplate[3].type = CKA_SUBJECT;
rsaPrivKeyTemplate[3].pValue = subject;
rsaPrivKeyTemplate[3].ulValueLen = sizeof(subject);
rsaPrivKeyTemplate[4].type = CKA_ID;
rsaPrivKeyTemplate[4].pValue = id;
rsaPrivKeyTemplate[4].ulValueLen = sizeof(id);
rsaPrivKeyTemplate[5].type = CKA_SENSITIVE;
rsaPrivKeyTemplate[5].pValue = &true;
rsaPrivKeyTemplate[5].ulValueLen = sizeof(true);
rsaPrivKeyTemplate[6].type = CKA_ENCRYPT;
rsaPrivKeyTemplate[6].pValue = &true;
rsaPrivKeyTemplate[6].ulValueLen = sizeof(true);
rsaPrivKeyTemplate[7].type = CKA_DECRYPT;
rsaPrivKeyTemplate[7].pValue = &true;
rsaPrivKeyTemplate[7].ulValueLen = sizeof(true);
rsaPrivKeyTemplate[8].type = CKA_VERIFY;
rsaPrivKeyTemplate[8].pValue = &true;
rsaPrivKeyTemplate[8].ulValueLen = sizeof(true);
rsaPrivKeyTemplate[9].type = CKA_SIGN;
rsaPrivKeyTemplate[9].pValue = &true;
rsaPrivKeyTemplate[9].ulValueLen = sizeof(true);
rsaPrivKeyTemplate[10].type = CKA_UNWRAP;
rsaPrivKeyTemplate[10].pValue = &true;
rsaPrivKeyTemplate[10].ulValueLen = sizeof(true);
/* AES key template */
sAESKeyTemplate[0].type = CKA_CLASS;
sAESKeyTemplate[0].pValue = &class;
sAESKeyTemplate[0].ulValueLen = sizeof(class);
sAESKeyTemplate[1].type = CKA_KEY_TYPE;
sAESKeyTemplate[1].pValue = &keyAESType;
sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
sAESKeyTemplate[2].type = CKA_LABEL;
sAESKeyTemplate[2].pValue = AESlabel;
sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel) - 1;
sAESKeyTemplate[3].type = CKA_ENCRYPT;
sAESKeyTemplate[3].pValue = &true;
sAESKeyTemplate[3].ulValueLen = sizeof(true);
sAESKeyTemplate[4].type = CKA_DECRYPT;
sAESKeyTemplate[4].pValue = &true;
sAESKeyTemplate[4].ulValueLen = sizeof(true);
sAESKeyTemplate[5].type = CKA_SIGN;
sAESKeyTemplate[5].pValue = &true;
sAESKeyTemplate[5].ulValueLen = sizeof(true);
sAESKeyTemplate[6].type = CKA_VERIFY;
sAESKeyTemplate[6].pValue = &true;
sAESKeyTemplate[6].ulValueLen = sizeof(true);
sAESKeyTemplate[7].type = CKA_UNWRAP;
sAESKeyTemplate[7].pValue = &true;
sAESKeyTemplate[7].ulValueLen = sizeof(true);
sAESKeyTemplate[8].type = CKA_VALUE_LEN;
sAESKeyTemplate[8].pValue = &AESvalueLen;
sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
/* DES3 key template */
sDES3KeyTemplate[0].type = CKA_CLASS;
sDES3KeyTemplate[0].pValue = &class;
sDES3KeyTemplate[0].ulValueLen = sizeof(class);
sDES3KeyTemplate[1].type = CKA_KEY_TYPE;
sDES3KeyTemplate[1].pValue = &keyDES3Type;
sDES3KeyTemplate[1].ulValueLen = sizeof(keyDES3Type);
sDES3KeyTemplate[2].type = CKA_LABEL;
sDES3KeyTemplate[2].pValue = DES3label;
sDES3KeyTemplate[2].ulValueLen = sizeof(DES3label) - 1;
sDES3KeyTemplate[3].type = CKA_ENCRYPT;
sDES3KeyTemplate[3].pValue = &true;
sDES3KeyTemplate[3].ulValueLen = sizeof(true);
sDES3KeyTemplate[4].type = CKA_DECRYPT;
sDES3KeyTemplate[4].pValue = &true;
sDES3KeyTemplate[4].ulValueLen = sizeof(true);
sDES3KeyTemplate[5].type = CKA_UNWRAP;
sDES3KeyTemplate[5].pValue = &true;
sDES3KeyTemplate[5].ulValueLen = sizeof(true);
sDES3KeyTemplate[6].type = CKA_SIGN,
sDES3KeyTemplate[6].pValue = &true;
sDES3KeyTemplate[6].ulValueLen = sizeof(true);
sDES3KeyTemplate[7].type = CKA_VERIFY;
sDES3KeyTemplate[7].pValue = &true;
sDES3KeyTemplate[7].ulValueLen = sizeof(true);
sDES3KeyTemplate[8].type = CKA_VALUE_LEN;
sDES3KeyTemplate[8].pValue = &DES3valueLen;
sDES3KeyTemplate[8].ulValueLen = sizeof(DES3valueLen);
/* mech init */
memset(IV, 0x01, sizeof(IV));
mech_DES3_CBC.mechanism = CKM_DES3_CBC;
mech_DES3_CBC.pParameter = IV;
mech_DES3_CBC.ulParameterLen = sizeof(IV);
mech_DES3_CBC_PAD.mechanism = CKM_DES3_CBC_PAD;
mech_DES3_CBC_PAD.pParameter = IV;
mech_DES3_CBC_PAD.ulParameterLen = sizeof(IV);
mech_AES_CBC.mechanism = CKM_AES_CBC;
mech_AES_CBC.pParameter = IV;
mech_AES_CBC.ulParameterLen = sizeof(IV);
mech_AES_CBC_PAD.mechanism = CKM_AES_CBC_PAD;
mech_AES_CBC_PAD.pParameter = IV;
mech_AES_CBC_PAD.ulParameterLen = sizeof(IV);
crv = pFunctionList->C_OpenSession(pSlotList[slotID],
CKF_RW_SESSION | CKF_SERIAL_SESSION,
NULL, NULL, &hRwSession);
if (crv == CKR_OK) {
PKM_LogIt("Opening a read/write session succeeded\n");
} else {
PKM_Error("Opening a read/write session failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
if (MODE == FIPSMODE) {
crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
sAESKeyTemplate,
NUM_ELEM(sAESKeyTemplate),
&hAESSecKey);
if (crv == CKR_OK) {
PKM_Error("C_GenerateKey succeeded when not logged in.\n");
return CKR_GENERAL_ERROR;
} else {
PKM_LogIt("C_GenerateKey returned as EXPECTED with 0x%08X, %-26s\n"
"since not logged in\n",
crv, PKM_CK_RVtoStr(crv));
}
crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
rsaPubKeyTemplate,
NUM_ELEM(rsaPubKeyTemplate),
rsaPrivKeyTemplate,
NUM_ELEM(rsaPrivKeyTemplate),
&hRSApubKey, &hRSAprivKey);
if (crv == CKR_OK) {
PKM_Error("C_GenerateKeyPair succeeded when not logged in.\n");
return CKR_GENERAL_ERROR;
} else {
PKM_LogIt("C_GenerateKeyPair returned as EXPECTED with 0x%08X, "
"%-26s\n since not logged in\n",
crv,
PKM_CK_RVtoStr(crv));
}
}
crv = pFunctionList->C_Login(hRwSession, CKU_USER, pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("C_Login with correct password succeeded\n");
} else {
PKM_Error("C_Login with correct password failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("Generate an AES key ... \n");
/* generate an AES Secret Key */
crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
sAESKeyTemplate,
NUM_ELEM(sAESKeyTemplate),
&hAESSecKey);
if (crv == CKR_OK) {
PKM_LogIt("C_GenerateKey AES succeeded\n");
} else {
PKM_Error("C_GenerateKey AES failed with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("Generate an 3DES key ...\n");
/* generate an 3DES Secret Key */
crv = pFunctionList->C_GenerateKey(hRwSession, &sDES3KeyGenMechanism,
sDES3KeyTemplate,
NUM_ELEM(sDES3KeyTemplate),
&hDES3SecKey);
if (crv == CKR_OK) {
PKM_LogIt("C_GenerateKey DES3 succeeded\n");
} else {
PKM_Error("C_GenerateKey failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("Generate DSA PQG domain parameters ... \n");
/* Generate DSA domain parameters PQG */
crv = pFunctionList->C_GenerateKey(hRwSession, &dsaParamGenMech,
dsaParamGenTemplate,
1,
&hDsaParams);
if (crv == CKR_OK) {
PKM_LogIt("DSA domain parameter generation succeeded\n");
} else {
PKM_Error("DSA domain parameter generation failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_GetAttributeValue(hRwSession, hDsaParams,
dsaPubKeyTemplate, 3);
if (crv == CKR_OK) {
PKM_LogIt("Getting DSA domain parameters succeeded\n");
} else {
PKM_Error("Getting DSA domain parameters failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_DestroyObject(hRwSession, hDsaParams);
if (crv == CKR_OK) {
PKM_LogIt("Destroying DSA domain parameters succeeded\n");
} else {
PKM_Error("Destroying DSA domain parameters failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("Generate a DSA key pair ... \n");
/* Generate a persistent DSA key pair */
crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech,
dsaPubKeyTemplate,
NUM_ELEM(dsaPubKeyTemplate),
dsaPrivKeyTemplate,
NUM_ELEM(dsaPrivKeyTemplate),
&hDSApubKey, &hDSAprivKey);
if (crv == CKR_OK) {
PKM_LogIt("DSA key pair generation succeeded\n");
} else {
PKM_Error("DSA key pair generation failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("Generate a RSA key pair ... \n");
/*** GEN RSA Key ***/
crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
rsaPubKeyTemplate,
NUM_ELEM(rsaPubKeyTemplate),
rsaPrivKeyTemplate,
NUM_ELEM(rsaPrivKeyTemplate),
&hRSApubKey, &hRSAprivKey);
if (crv == CKR_OK) {
PKM_LogIt("C_GenerateKeyPair created an RSA key pair. \n");
} else {
PKM_Error("C_GenerateKeyPair failed to create an RSA key pair.\n"
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("**** Generation of keys completed ***** \n");
mech.mechanism = CKM_RSA_PKCS;
mech.pParameter = NULL;
mech.ulParameterLen = 0;
crv = PKM_wrapUnwrap(pFunctionList,
hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
hAESSecKey,
sAESKeyTemplate,
NUM_ELEM(sAESKeyTemplate));
if (crv == CKR_OK) {
PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap AES key "
"succeeded\n\n");
} else {
PKM_Error("PKM_wrapUnwrap using RSA keypair to wrap AES key failed "
"with 0x%08X, %-26s\n",
crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_wrapUnwrap(pFunctionList,
hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
hDES3SecKey,
sDES3KeyTemplate,
NUM_ELEM(sDES3KeyTemplate));
if (crv == CKR_OK) {
PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
"succeeded\n\n");
} else {
PKM_Error("PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
"failed with 0x%08X, %-26s\n",
crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
hAESSecKey, &mech_AES_CBC_PAD,
PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
if (crv == CKR_OK) {
PKM_LogIt("PKM_SecKeyCrypt succeeded \n\n");
} else {
PKM_Error("PKM_SecKeyCrypt failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
hAESSecKey, &mech_AES_CBC,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_SecKeyCrypt AES succeeded \n\n");
} else {
PKM_Error("PKM_SecKeyCrypt failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
hDES3SecKey, &mech_DES3_CBC,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n");
} else {
PKM_Error("PKM_SecKeyCrypt DES3 failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
hDES3SecKey, &mech_DES3_CBC_PAD,
PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
if (crv == CKR_OK) {
PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n\n");
} else {
PKM_Error("PKM_SecKeyCrypt DES3 failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
mech.mechanism = CKM_RSA_PKCS;
crv = PKM_RecoverFunctions(pFunctionList, hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_RecoverFunctions for CKM_RSA_PKCS succeeded\n\n");
} else {
PKM_Error("PKM_RecoverFunctions failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
mech.pParameter = NULL;
mech.ulParameterLen = 0;
for (i = 0; i < sigRSAMechsSZ; i++) {
mech.mechanism = sigRSAMechs[i].mechanism;
crv = PKM_PubKeySign(pFunctionList, hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_PubKeySign succeeded for %-10s\n\n",
sigRSAMechs[i].mechanismStr);
} else {
PKM_Error("PKM_PubKeySign failed for %-10s "
"with 0x%08X, %-26s\n",
sigRSAMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
hAESSecKey, &mech_AES_CBC,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
"for %-10s\n\n",
sigRSAMechs[i].mechanismStr);
} else {
PKM_Error("PKM_DualFuncSign with AES secret key failed "
"for %-10s "
"with 0x%08X, %-26s\n",
sigRSAMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
hDES3SecKey, &mech_DES3_CBC,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
"for %-10s\n\n",
sigRSAMechs[i].mechanismStr);
} else {
PKM_Error("PKM_DualFuncSign with DES3 secret key failed "
"for %-10s "
"with 0x%08X, %-26s\n",
sigRSAMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
hAESSecKey, &mech_AES_CBC_PAD,
PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD "
"succeeded for %-10s\n\n",
sigRSAMechs[i].mechanismStr);
} else {
PKM_Error("PKM_DualFuncSign with AES secret key CBC_PAD "
"failed for %-10s "
"with 0x%08X, %-26s\n",
sigRSAMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hRSApubKey, hRSAprivKey,
&mech,
hDES3SecKey, &mech_DES3_CBC_PAD,
PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD "
"succeeded for %-10s\n\n",
sigRSAMechs[i].mechanismStr);
} else {
PKM_Error("PKM_DualFuncSign with DES3 secret key CBC_PAD "
"failed for %-10s "
"with 0x%08X, %-26s\n",
sigRSAMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
} /* end of RSA for loop */
crv = PKM_PubKeySign(pFunctionList, hRwSession,
hDSApubKey, hDSAprivKey,
&dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_PubKeySign for DSAwithSHA1 succeeded \n\n");
} else {
PKM_Error("PKM_PubKeySign failed "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hDSApubKey, hDSAprivKey,
&dsaWithSha1Mech,
hAESSecKey, &mech_AES_CBC,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
"for DSAWithSHA1\n\n");
} else {
PKM_Error("PKM_DualFuncSign with AES secret key failed "
"for DSAWithSHA1 with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hDSApubKey, hDSAprivKey,
&dsaWithSha1Mech,
hDES3SecKey, &mech_DES3_CBC,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
"for DSAWithSHA1\n\n");
} else {
PKM_Error("PKM_DualFuncSign with DES3 secret key failed "
"for DSAWithSHA1 with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hDSApubKey, hDSAprivKey,
&dsaWithSha1Mech,
hAESSecKey, &mech_AES_CBC_PAD,
PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD succeeded "
"for DSAWithSHA1\n\n");
} else {
PKM_Error("PKM_DualFuncSign with AES secret key CBC_PAD failed "
"for DSAWithSHA1 with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncSign(pFunctionList, hRwSession,
hDSApubKey, hDSAprivKey,
&dsaWithSha1Mech,
hDES3SecKey, &mech_DES3_CBC_PAD,
PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD succeeded "
"for DSAWithSHA1\n\n");
} else {
PKM_Error("PKM_DualFuncSign with DES3 secret key CBC_PAD failed "
"for DSAWithSHA1 with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
for (i = 0; i < digestMechsSZ; i++) {
mech.mechanism = digestMechs[i].mechanism;
crv = PKM_Digest(pFunctionList, hRwSession,
&mech, hAESSecKey,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_Digest with AES secret key succeeded for %-10s\n\n",
digestMechs[i].mechanismStr);
} else {
PKM_Error("PKM_Digest with AES secret key failed for "
"%-10s with 0x%08X, %-26s\n",
digestMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
hAESSecKey, &mech_AES_CBC,
0, &mech,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncDigest with AES secret key succeeded\n\n");
} else {
PKM_Error("PKM_DualFuncDigest with AES secret key "
"failed with 0x%08X, %-26s\n",
crv,
PKM_CK_RVtoStr(crv));
}
crv = PKM_Digest(pFunctionList, hRwSession,
&mech, hDES3SecKey,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_Digest with DES3 secret key succeeded for %-10s\n\n",
digestMechs[i].mechanismStr);
} else {
PKM_Error("PKM_Digest with DES3 secret key failed for "
"%-10s with 0x%08X, %-26s\n",
digestMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
hDES3SecKey, &mech_DES3_CBC,
0, &mech,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_DualFuncDigest DES3 secret key succeeded\n\n");
} else {
PKM_Error("PKM_DualFuncDigest DES3 secret key "
"failed with 0x%08X, %-26s\n",
crv,
PKM_CK_RVtoStr(crv));
}
crv = PKM_Digest(pFunctionList, hRwSession,
&mech, 0,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_Digest with no secret key succeeded for %-10s\n\n",
digestMechs[i].mechanismStr);
} else {
PKM_Error("PKM_Digest with no secret key failed for %-10s "
"with 0x%08X, %-26s\n",
digestMechs[i].mechanismStr, crv,
PKM_CK_RVtoStr(crv));
return crv;
}
} /* end of digest loop */
for (i = 0; i < hmacMechsSZ; i++) {
mech.mechanism = hmacMechs[i].mechanism;
crv = PKM_Hmac(pFunctionList, hRwSession,
hAESSecKey, &mech,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_Hmac with AES secret key succeeded for %-10s\n\n",
hmacMechs[i].mechanismStr);
} else {
PKM_Error("PKM_Hmac with AES secret key failed for %-10s "
"with 0x%08X, %-26s\n",
hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
return crv;
}
if ((MODE == FIPSMODE) && (mech.mechanism == CKM_SHA512_HMAC))
break;
crv = PKM_Hmac(pFunctionList, hRwSession,
hDES3SecKey, &mech,
PLAINTEXT, sizeof(PLAINTEXT));
if (crv == CKR_OK) {
PKM_LogIt("PKM_Hmac with DES3 secret key succeeded for %-10s\n\n",
hmacMechs[i].mechanismStr);
} else {
PKM_Error("PKM_Hmac with DES3 secret key failed for %-10s "
"with 0x%08X, %-26s\n",
hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
return crv;
}
} /* end of hmac loop */
crv = pFunctionList->C_Logout(hRwSession);
if (crv == CKR_OK) {
PKM_LogIt("C_Logout succeeded\n");
} else {
PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_CloseSession(hRwSession);
if (crv != CKR_OK) {
PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
return crv;
}
void
PKM_LogIt(const char *fmt, ...)
{
va_list args;
if (verbose) {
va_start(args, fmt);
if (MODE == FIPSMODE) {
printf("FIPS MODE: ");
} else if (MODE == NONFIPSMODE) {
printf("NON FIPS MODE: ");
} else if (MODE == HYBRIDMODE) {
printf("Hybrid MODE: ");
}
vprintf(fmt, args);
va_end(args);
}
}
void
PKM_Error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (MODE == FIPSMODE) {
fprintf(stderr, "\nFIPS MODE PKM_Error: ");
} else if (MODE == NONFIPSMODE) {
fprintf(stderr, "NON FIPS MODE PKM_Error: ");
} else if (MODE == HYBRIDMODE) {
fprintf(stderr, "Hybrid MODE PKM_Error: ");
} else
fprintf(stderr, "NOMODE PKM_Error: ");
vfprintf(stderr, fmt, args);
va_end(args);
}
CK_SLOT_ID *
PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
CK_ULONG slotID)
{
CK_RV crv = CKR_OK;
CK_SLOT_ID *pSlotList = NULL;
CK_ULONG slotCount;
NUMTESTS++; /* increment NUMTESTS */
/* Get slot list */
crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
NULL, &slotCount);
if (crv != CKR_OK) {
PKM_Error("C_GetSlotList failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return NULL;
}
PKM_LogIt("C_GetSlotList reported there are %lu slots\n", slotCount);
pSlotList = (CK_SLOT_ID *)malloc(slotCount * sizeof(CK_SLOT_ID));
if (!pSlotList) {
PKM_Error("failed to allocate slot list\n");
return NULL;
}
crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
pSlotList, &slotCount);
if (crv != CKR_OK) {
PKM_Error("C_GetSlotList failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
if (pSlotList)
free(pSlotList);
return NULL;
}
return pSlotList;
}
CK_RV
PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID,
CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)
{
CK_RV crv = CKR_OK;
CK_SESSION_HANDLE hSession;
static const CK_UTF8CHAR testPin[] = { "0Mozilla" };
static const CK_UTF8CHAR weakPin[] = { "mozilla" };
crv = pFunctionList->C_OpenSession(pSlotList[slotID],
CKF_RW_SESSION | CKF_SERIAL_SESSION,
NULL, NULL, &hSession);
if (crv != CKR_OK) {
PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER);
crv = pFunctionList->C_Login(hSession, CKU_SO, NULL, 0);
if (crv != CKR_OK) {
PKM_Error("C_Login failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
if (MODE == FIPSMODE) {
crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *)weakPin,
strlen((char *)weakPin));
if (crv == CKR_OK) {
PKM_Error("C_InitPIN with a weak password succeeded\n");
return crv;
} else {
PKM_LogIt("C_InitPIN with a weak password failed with "
"0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
}
}
crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *)testPin,
strlen((char *)testPin));
if (crv == CKR_OK) {
PKM_LogIt("C_InitPIN succeeded\n");
} else {
PKM_Error("C_InitPIN failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_Logout(hSession);
if (crv != CKR_OK) {
PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_CloseSession(hSession);
if (crv != CKR_OK) {
PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_OpenSession(pSlotList[slotID],
CKF_RW_SESSION | CKF_SERIAL_SESSION,
NULL, NULL, &hSession);
if (crv != CKR_OK) {
PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER);
crv = pFunctionList->C_Login(hSession, CKU_USER, (CK_UTF8CHAR *)testPin,
strlen((const char *)testPin));
if (crv != CKR_OK) {
PKM_Error("C_Login failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
if (MODE == FIPSMODE) {
crv = pFunctionList->C_SetPIN(
hSession, (CK_UTF8CHAR *)testPin,
strlen((const char *)testPin),
(CK_UTF8CHAR *)weakPin,
strlen((const char *)weakPin));
if (crv == CKR_OK) {
PKM_Error("C_SetPIN with a weak password succeeded\n");
return crv;
} else {
PKM_LogIt("C_SetPIN with a weak password returned with "
"0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
}
}
crv = pFunctionList->C_SetPIN(
hSession, (CK_UTF8CHAR *)testPin,
strlen((const char *)testPin),
pwd, pwdLen);
if (crv != CKR_OK) {
PKM_Error("C_CSetPin failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_Logout(hSession);
if (crv != CKR_OK) {
PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
crv = pFunctionList->C_CloseSession(hSession);
if (crv != CKR_OK) {
PKM_Error("C_CloseSession failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
return crv;
}
CK_RV
PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID)
{
CK_RV crv = CKR_OK;
CK_INFO info;
CK_SLOT_ID *pSlotList = NULL;
unsigned i;
CK_SLOT_INFO slotInfo;
CK_TOKEN_INFO tokenInfo;
CK_FLAGS bitflag;
NUMTESTS++; /* increment NUMTESTS */
crv = pFunctionList->C_GetInfo(&info);
if (crv == CKR_OK) {
PKM_LogIt("C_GetInfo succeeded\n");
} else {
PKM_Error("C_GetInfo failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("General information about the PKCS #11 library:\n");
PKM_LogIt(" PKCS #11 version: %d.%d\n",
(int)info.cryptokiVersion.major,
(int)info.cryptokiVersion.minor);
PKM_LogIt(" manufacturer ID: %.32s\n", info.manufacturerID);
PKM_LogIt(" flags: 0x%08lX\n", info.flags);
PKM_LogIt(" library description: %.32s\n", info.libraryDescription);
PKM_LogIt(" library version: %d.%d\n",
(int)info.libraryVersion.major, (int)info.libraryVersion.minor);
PKM_LogIt("\n");
/* Get slot list */
pSlotList = PKM_GetSlotList(pFunctionList, slotID);
if (pSlotList == NULL) {
PKM_Error("PKM_GetSlotList failed with \n");
return crv;
}
crv = pFunctionList->C_GetSlotInfo(pSlotList[slotID], &slotInfo);
if (crv == CKR_OK) {
PKM_LogIt("C_GetSlotInfo succeeded\n");
} else {
PKM_Error("C_GetSlotInfo failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("Information about slot %lu:\n", pSlotList[slotID]);
PKM_LogIt(" slot description: %.64s\n", slotInfo.slotDescription);
PKM_LogIt(" slot manufacturer ID: %.32s\n", slotInfo.manufacturerID);
PKM_LogIt(" flags: 0x%08lX\n", slotInfo.flags);
bitflag = 1;
for (i = 0; i < sizeof(slotFlagName) / sizeof(slotFlagName[0]); i++) {
if (slotInfo.flags & bitflag) {
PKM_LogIt(" %s\n", slotFlagName[i]);
}
bitflag <<= 1;
}
PKM_LogIt(" slot's hardware version number: %d.%d\n",
(int)slotInfo.hardwareVersion.major,
(int)slotInfo.hardwareVersion.minor);
PKM_LogIt(" slot's firmware version number: %d.%d\n",
(int)slotInfo.firmwareVersion.major,
(int)slotInfo.firmwareVersion.minor);
PKM_LogIt("\n");
crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
if (crv == CKR_OK) {
PKM_LogIt("C_GetTokenInfo succeeded\n");
} else {
PKM_Error("C_GetTokenInfo failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("Information about the token in slot %lu:\n",
pSlotList[slotID]);
PKM_LogIt(" label: %.32s\n", tokenInfo.label);
PKM_LogIt(" device manufacturer ID: %.32s\n",
tokenInfo.manufacturerID);
PKM_LogIt(" device model: %.16s\n", tokenInfo.model);
PKM_LogIt(" device serial number: %.16s\n", tokenInfo.serialNumber);
PKM_LogIt(" flags: 0x%08lX\n", tokenInfo.flags);
bitflag = 1;
for (i = 0; i < sizeof(tokenFlagName) / sizeof(tokenFlagName[0]); i++) {
if (tokenInfo.flags & bitflag) {
PKM_LogIt(" %s\n", tokenFlagName[i]);
}
bitflag <<= 1;
}
PKM_LogIt(" maximum session count: %lu\n",
tokenInfo.ulMaxSessionCount);
PKM_LogIt(" session count: %lu\n", tokenInfo.ulSessionCount);
PKM_LogIt(" maximum read/write session count: %lu\n",
tokenInfo.ulMaxRwSessionCount);
PKM_LogIt(" read/write session count: %lu\n",
tokenInfo.ulRwSessionCount);
PKM_LogIt(" maximum PIN length: %lu\n", tokenInfo.ulMaxPinLen);
PKM_LogIt(" minimum PIN length: %lu\n", tokenInfo.ulMinPinLen);
PKM_LogIt(" total public memory: %lu\n",
tokenInfo.ulTotalPublicMemory);
PKM_LogIt(" free public memory: %lu\n",
tokenInfo.ulFreePublicMemory);
PKM_LogIt(" total private memory: %lu\n",
tokenInfo.ulTotalPrivateMemory);
PKM_LogIt(" free private memory: %lu\n",
tokenInfo.ulFreePrivateMemory);
PKM_LogIt(" hardware version number: %d.%d\n",
(int)tokenInfo.hardwareVersion.major,
(int)tokenInfo.hardwareVersion.minor);
PKM_LogIt(" firmware version number: %d.%d\n",
(int)tokenInfo.firmwareVersion.major,
(int)tokenInfo.firmwareVersion.minor);
if (tokenInfo.flags & CKF_CLOCK_ON_TOKEN) {
PKM_LogIt(" current time: %.16s\n", tokenInfo.utcTime);
}
PKM_LogIt("PKM_ShowInfo done \n\n");
free(pSlotList);
return crv;
}
/* PKM_HybridMode */
/* The NSS cryptographic module has two modes of operation: FIPS Approved */
/* mode and NONFIPS Approved mode. The two modes of operation are */
/* independent of each other -- they have their own copies of data */
/* structures and they are even allowed to be active at the same time. */
/* The module is FIPS 140-2 compliant only when the NONFIPS mode */
/* is inactive. */
/* PKM_HybridMode demostrates how an application can switch between the */
/* two modes: FIPS Approved mode and NONFIPS mode. */
CK_RV
PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
CK_C_INITIALIZE_ARGS_NSS *initArgs)
{
CK_C_GetFunctionList pC_GetFunctionList; /* NONFIPSMode */
CK_FUNCTION_LIST_PTR pC_FunctionList;
CK_SLOT_ID *pC_SlotList = NULL;
CK_ULONG slotID_C = 1;
CK_C_GetFunctionList pFC_GetFunctionList; /* FIPSMode */
CK_FUNCTION_LIST_PTR pFC_FunctionList;
CK_SLOT_ID *pFC_SlotList = NULL;
CK_ULONG slotID_FC = 0;
CK_RV crv = CKR_OK;
CK_SESSION_HANDLE hSession;
int origMode = MODE; /* remember the orginal MODE value */
NUMTESTS++; /* increment NUMTESTS */
MODE = NONFIPSMODE;
#ifdef _WIN32
/* NON FIPS mode == C_GetFunctionList */
pC_GetFunctionList = (CK_C_GetFunctionList)
GetProcAddress(hModule, "C_GetFunctionList");
if (pC_GetFunctionList == NULL) {
PKM_Error("cannot load %s\n", LIB_NAME);
return crv;
}
#else
pC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
"C_GetFunctionList");
assert(pC_GetFunctionList != NULL);
#endif
PKM_LogIt("loading C_GetFunctionList for Non FIPS Mode; slotID %d \n",
slotID_C);
crv = (*pC_GetFunctionList)(&pC_FunctionList);
assert(crv == CKR_OK);
/* invoke C_Initialize as pC_FunctionList->C_Initialize */
crv = pC_FunctionList->C_Initialize(initArgs);
if (crv == CKR_OK) {
PKM_LogIt("C_Initialize succeeded\n");
} else {
PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
pC_SlotList = PKM_GetSlotList(pC_FunctionList, slotID_C);
if (pC_SlotList == NULL) {
PKM_Error("PKM_GetSlotList failed with \n");
return crv;
}
crv = pC_FunctionList->C_OpenSession(pC_SlotList[slotID_C],
CKF_SERIAL_SESSION,
NULL, NULL, &hSession);
if (crv == CKR_OK) {
PKM_LogIt("NONFIPS C_OpenSession succeeded\n");
} else {
PKM_Error("C_OpenSession failed for NONFIPS token "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
if (crv == CKR_OK) {
PKM_LogIt("able to login in NONFIPS token\n");
} else {
PKM_Error("Unable to login in to NONFIPS token "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
crv = pC_FunctionList->C_Logout(hSession);
if (crv == CKR_OK) {
PKM_LogIt("C_Logout succeeded\n");
} else {
PKM_Error("C_Logout failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_ShowInfo(pC_FunctionList, slotID_C);
MODE = HYBRIDMODE;
/* Now load the FIPS token */
/* FIPS mode == FC_GetFunctionList */
pFC_GetFunctionList = NULL;
#ifdef _WIN32
pFC_GetFunctionList = (CK_C_GetFunctionList)
GetProcAddress(hModule, "FC_GetFunctionList");
#else
pFC_GetFunctionList = (CK_C_GetFunctionList)PR_FindFunctionSymbol(lib,
"FC_GetFunctionList");
assert(pFC_GetFunctionList != NULL);
#endif
PKM_LogIt("loading FC_GetFunctionList for FIPS Mode; slotID %d \n",
slotID_FC);
PKM_LogIt("pFC_FunctionList->C_Foo == pFC_FunctionList->FC_Foo\n");
if (pFC_GetFunctionList == NULL) {
PKM_Error("unable to load pFC_GetFunctionList\n");
return crv;
}
crv = (*pFC_GetFunctionList)(&pFC_FunctionList);
assert(crv == CKR_OK);
/* invoke FC_Initialize as pFunctionList->C_Initialize */
crv = pFC_FunctionList->C_Initialize(initArgs);
if (crv == CKR_OK) {
PKM_LogIt("FC_Initialize succeeded\n");
} else {
PKM_Error("FC_Initialize failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_ShowInfo(pFC_FunctionList, slotID_FC);
pFC_SlotList = PKM_GetSlotList(pFC_FunctionList, slotID_FC);
if (pFC_SlotList == NULL) {
PKM_Error("PKM_GetSlotList failed with \n");
return crv;
}
crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
if (crv != CKR_OK) {
PKM_LogIt("NONFIPS token cannot log in when FIPS token is loaded\n");
} else {
PKM_Error("Able to login in to NONFIPS token\n");
return crv;
}
crv = pC_FunctionList->C_CloseSession(hSession);
if (crv == CKR_OK) {
PKM_LogIt("NONFIPS pC_CloseSession succeeded\n");
} else {
PKM_Error("pC_CloseSession failed for NONFIPS token "
"with 0x%08X, %-26s\n",
crv, PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("The module is FIPS 140-2 compliant\n"
"only when the NONFIPS Approved mode is inactive by \n"
"calling C_Finalize on the NONFIPS token.\n");
/* to go in FIPSMODE you must Finalize the NONFIPS mode pointer */
crv = pC_FunctionList->C_Finalize(NULL);
if (crv == CKR_OK) {
PKM_LogIt("C_Finalize of NONFIPS Token succeeded\n");
MODE = FIPSMODE;
} else {
PKM_Error("C_Finalize of NONFIPS Token failed with "
"0x%08X, %-26s\n",
crv,
PKM_CK_RVtoStr(crv));
return crv;
}
PKM_LogIt("*** In FIPS mode! ***\n");
/* could do some operations in FIPS MODE */
crv = pFC_FunctionList->C_Finalize(NULL);
if (crv == CKR_OK) {
PKM_LogIt("Exiting FIPSMODE by caling FC_Finalize.\n");
MODE = NOMODE;
} else {
PKM_Error("FC_Finalize failed with 0x%08X, %-26s\n", crv,
PKM_CK_RVtoStr(crv));
return crv;
}
if (pC_SlotList)
free(pC_SlotList);
if (pFC_SlotList)
free(pFC_SlotList);
MODE = origMode; /* set the mode back to the orginal Mode value */
PKM_LogIt("PKM_HybridMode test Completed\n\n");
return crv;
}
CK_RV
PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
CK_SLOT_ID *pSlotList, CK_ULONG slotID)
{
CK_RV crv = CKR_OK;