security/nss/cmd/pk11mode/pk11mode.c

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

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

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial