Back to index

lightning-sunbird  0.9+nobinonly
pk11mode.c
Go to the documentation of this file.
00001 /*
00002  * pk11mode.c - Test FIPS or NONFIPS Modes for the NSS PKCS11 api.
00003  *              The goal of this program is to test every function
00004  *              entry point of the PKCS11 api at least once.
00005  *              To test in FIPS mode: pk11mode
00006  *              To test in NONFIPS mode: pk11mode nonFIPS
00007  *
00008  * ***** BEGIN LICENSE BLOCK *****
00009  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00010  *
00011  * The contents of this file are subject to the Mozilla Public License Version
00012  * 1.1 (the "License"); you may not use this file except in compliance with
00013  * the License. You may obtain a copy of the License at
00014  * http://www.mozilla.org/MPL/
00015  *
00016  * Software distributed under the License is distributed on an "AS IS" basis,
00017  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00018  * for the specific language governing rights and limitations under the
00019  * License.
00020  *
00021  * The Original Code is the Netscape security libraries.
00022  *
00023  * The Initial Developer of the Original Code is
00024  * Netscape Communications Corporation.
00025  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00026  * the Initial Developer. All Rights Reserved.
00027  *
00028  * Contributor(s):
00029  *
00030  * Alternatively, the contents of this file may be used under the terms of
00031  * either the GNU General Public License Version 2 or later (the "GPL"), or
00032  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00033  * in which case the provisions of the GPL or the LGPL are applicable instead
00034  * of those above. If you wish to allow use of your version of this file only
00035  * under the terms of either the GPL or the LGPL, and not to allow others to
00036  * use your version of this file under the terms of the MPL, indicate your
00037  * decision by deleting the provisions above and replace them with the notice
00038  * and other provisions required by the GPL or the LGPL. If you do not delete
00039  * the provisions above, a recipient may use your version of this file under
00040  * the terms of any one of the MPL, the GPL or the LGPL.
00041  *
00042  * ***** END LICENSE BLOCK ***** */
00043 
00044 
00045 #include <assert.h>
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 #include <string.h>
00049 #include <stdarg.h>
00050 
00051 #ifdef _WIN32
00052 #include <windows.h>
00053 #define LIB_NAME "softokn3.dll"
00054 #endif
00055 #include "prlink.h"
00056 #include "prprf.h"
00057 #include "plgetopt.h"
00058 #include "prenv.h"
00059 
00060 #include "pkcs11.h"
00061 
00062 
00063 #define NUM_ELEM(array) (sizeof(array)/sizeof(array[0]))
00064 
00065 #ifndef NULL_PTR
00066 #define NULL_PTR 0
00067 #endif
00068 
00069 struct tuple_str {
00070     CK_RV         errNum;
00071     const char * errString;
00072 };
00073 
00074 
00075 typedef struct tuple_str tuple_str;
00076 
00077 static const tuple_str errStrings[] = {
00078 {CKR_OK                              , "CKR_OK                              "},
00079 {CKR_CANCEL                          , "CKR_CANCEL                          "},
00080 {CKR_HOST_MEMORY                     , "CKR_HOST_MEMORY                     "},
00081 {CKR_SLOT_ID_INVALID                 , "CKR_SLOT_ID_INVALID                 "},
00082 {CKR_GENERAL_ERROR                   , "CKR_GENERAL_ERROR                   "},
00083 {CKR_FUNCTION_FAILED                 , "CKR_FUNCTION_FAILED                 "},
00084 {CKR_ARGUMENTS_BAD                   , "CKR_ARGUMENTS_BAD                   "},
00085 {CKR_NO_EVENT                        , "CKR_NO_EVENT                        "},
00086 {CKR_NEED_TO_CREATE_THREADS          , "CKR_NEED_TO_CREATE_THREADS          "},
00087 {CKR_CANT_LOCK                       , "CKR_CANT_LOCK                       "},
00088 {CKR_ATTRIBUTE_READ_ONLY             , "CKR_ATTRIBUTE_READ_ONLY             "},
00089 {CKR_ATTRIBUTE_SENSITIVE             , "CKR_ATTRIBUTE_SENSITIVE             "},
00090 {CKR_ATTRIBUTE_TYPE_INVALID          , "CKR_ATTRIBUTE_TYPE_INVALID          "},
00091 {CKR_ATTRIBUTE_VALUE_INVALID         , "CKR_ATTRIBUTE_VALUE_INVALID         "},
00092 {CKR_DATA_INVALID                    , "CKR_DATA_INVALID                    "},
00093 {CKR_DATA_LEN_RANGE                  , "CKR_DATA_LEN_RANGE                  "},
00094 {CKR_DEVICE_ERROR                    , "CKR_DEVICE_ERROR                    "},
00095 {CKR_DEVICE_MEMORY                   , "CKR_DEVICE_MEMORY                   "},
00096 {CKR_DEVICE_REMOVED                  , "CKR_DEVICE_REMOVED                  "},
00097 {CKR_ENCRYPTED_DATA_INVALID          , "CKR_ENCRYPTED_DATA_INVALID          "},
00098 {CKR_ENCRYPTED_DATA_LEN_RANGE        , "CKR_ENCRYPTED_DATA_LEN_RANGE        "},
00099 {CKR_FUNCTION_CANCELED               , "CKR_FUNCTION_CANCELED               "},
00100 {CKR_FUNCTION_NOT_PARALLEL           , "CKR_FUNCTION_NOT_PARALLEL           "},
00101 {CKR_FUNCTION_NOT_SUPPORTED          , "CKR_FUNCTION_NOT_SUPPORTED          "},
00102 {CKR_KEY_HANDLE_INVALID              , "CKR_KEY_HANDLE_INVALID              "},
00103 {CKR_KEY_SIZE_RANGE                  , "CKR_KEY_SIZE_RANGE                  "},
00104 {CKR_KEY_TYPE_INCONSISTENT           , "CKR_KEY_TYPE_INCONSISTENT           "},
00105 {CKR_KEY_NOT_NEEDED                  , "CKR_KEY_NOT_NEEDED                  "},
00106 {CKR_KEY_CHANGED                     , "CKR_KEY_CHANGED                     "},
00107 {CKR_KEY_NEEDED                      , "CKR_KEY_NEEDED                      "},
00108 {CKR_KEY_INDIGESTIBLE                , "CKR_KEY_INDIGESTIBLE                "},
00109 {CKR_KEY_FUNCTION_NOT_PERMITTED      , "CKR_KEY_FUNCTION_NOT_PERMITTED      "},
00110 {CKR_KEY_NOT_WRAPPABLE               , "CKR_KEY_NOT_WRAPPABLE               "},
00111 {CKR_KEY_UNEXTRACTABLE               , "CKR_KEY_UNEXTRACTABLE               "},
00112 {CKR_MECHANISM_INVALID               , "CKR_MECHANISM_INVALID               "},
00113 {CKR_MECHANISM_PARAM_INVALID         , "CKR_MECHANISM_PARAM_INVALID         "},
00114 {CKR_OBJECT_HANDLE_INVALID           , "CKR_OBJECT_HANDLE_INVALID           "},
00115 {CKR_OPERATION_ACTIVE                , "CKR_OPERATION_ACTIVE                "},
00116 {CKR_OPERATION_NOT_INITIALIZED       , "CKR_OPERATION_NOT_INITIALIZED       "},
00117 {CKR_PIN_INCORRECT                   , "CKR_PIN_INCORRECT                   "},
00118 {CKR_PIN_INVALID                     , "CKR_PIN_INVALID                     "},
00119 {CKR_PIN_LEN_RANGE                   , "CKR_PIN_LEN_RANGE                   "},
00120 {CKR_PIN_EXPIRED                     , "CKR_PIN_EXPIRED                     "},
00121 {CKR_PIN_LOCKED                      , "CKR_PIN_LOCKED                      "},
00122 {CKR_SESSION_CLOSED                  , "CKR_SESSION_CLOSED                  "},
00123 {CKR_SESSION_COUNT                   , "CKR_SESSION_COUNT                   "},
00124 {CKR_SESSION_HANDLE_INVALID          , "CKR_SESSION_HANDLE_INVALID          "},
00125 {CKR_SESSION_PARALLEL_NOT_SUPPORTED  , "CKR_SESSION_PARALLEL_NOT_SUPPORTED  "},
00126 {CKR_SESSION_READ_ONLY               , "CKR_SESSION_READ_ONLY               "},
00127 {CKR_SESSION_EXISTS                  , "CKR_SESSION_EXISTS                  "},
00128 {CKR_SESSION_READ_ONLY_EXISTS        , "CKR_SESSION_READ_ONLY_EXISTS        "},
00129 {CKR_SESSION_READ_WRITE_SO_EXISTS    , "CKR_SESSION_READ_WRITE_SO_EXISTS    "},
00130 {CKR_SIGNATURE_INVALID               , "CKR_SIGNATURE_INVALID               "},
00131 {CKR_SIGNATURE_LEN_RANGE             , "CKR_SIGNATURE_LEN_RANGE             "},
00132 {CKR_TEMPLATE_INCOMPLETE             , "CKR_TEMPLATE_INCOMPLETE             "},
00133 {CKR_TEMPLATE_INCONSISTENT           , "CKR_TEMPLATE_INCONSISTENT           "},
00134 {CKR_TOKEN_NOT_PRESENT               , "CKR_TOKEN_NOT_PRESENT               "},
00135 {CKR_TOKEN_NOT_RECOGNIZED            , "CKR_TOKEN_NOT_RECOGNIZED            "},
00136 {CKR_TOKEN_WRITE_PROTECTED           , "CKR_TOKEN_WRITE_PROTECTED           "},
00137 {CKR_UNWRAPPING_KEY_HANDLE_INVALID   , "CKR_UNWRAPPING_KEY_HANDLE_INVALID   "},
00138 {CKR_UNWRAPPING_KEY_SIZE_RANGE       , "CKR_UNWRAPPING_KEY_SIZE_RANGE       "},
00139 {CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"},
00140 {CKR_USER_ALREADY_LOGGED_IN          , "CKR_USER_ALREADY_LOGGED_IN          "},
00141 {CKR_USER_NOT_LOGGED_IN              , "CKR_USER_NOT_LOGGED_IN              "},
00142 {CKR_USER_PIN_NOT_INITIALIZED        , "CKR_USER_PIN_NOT_INITIALIZED        "},
00143 {CKR_USER_TYPE_INVALID               , "CKR_USER_TYPE_INVALID               "},
00144 {CKR_USER_ANOTHER_ALREADY_LOGGED_IN  , "CKR_USER_ANOTHER_ALREADY_LOGGED_IN  "},
00145 {CKR_USER_TOO_MANY_TYPES             , "CKR_USER_TOO_MANY_TYPES             "},
00146 {CKR_WRAPPED_KEY_INVALID             , "CKR_WRAPPED_KEY_INVALID             "},
00147 {CKR_WRAPPED_KEY_LEN_RANGE           , "CKR_WRAPPED_KEY_LEN_RANGE           "},
00148 {CKR_WRAPPING_KEY_HANDLE_INVALID     , "CKR_WRAPPING_KEY_HANDLE_INVALID     "},
00149 {CKR_WRAPPING_KEY_SIZE_RANGE         , "CKR_WRAPPING_KEY_SIZE_RANGE         "},
00150 {CKR_WRAPPING_KEY_TYPE_INCONSISTENT  , "CKR_WRAPPING_KEY_TYPE_INCONSISTENT  "},
00151 {CKR_RANDOM_SEED_NOT_SUPPORTED       , "CKR_RANDOM_SEED_NOT_SUPPORTED       "},
00152 {CKR_RANDOM_NO_RNG                   , "CKR_RANDOM_NO_RNG                   "},
00153 {CKR_DOMAIN_PARAMS_INVALID           , "CKR_DOMAIN_PARAMS_INVALID           "},
00154 {CKR_BUFFER_TOO_SMALL                , "CKR_BUFFER_TOO_SMALL                "},
00155 {CKR_SAVED_STATE_INVALID             , "CKR_SAVED_STATE_INVALID             "},
00156 {CKR_INFORMATION_SENSITIVE           , "CKR_INFORMATION_SENSITIVE           "},
00157 {CKR_STATE_UNSAVEABLE                , "CKR_STATE_UNSAVEABLE                "},
00158 {CKR_CRYPTOKI_NOT_INITIALIZED        , "CKR_CRYPTOKI_NOT_INITIALIZED        "},
00159 {CKR_CRYPTOKI_ALREADY_INITIALIZED    , "CKR_CRYPTOKI_ALREADY_INITIALIZED    "},
00160 {CKR_MUTEX_BAD                       , "CKR_MUTEX_BAD                       "},
00161 {CKR_MUTEX_NOT_LOCKED                , "CKR_MUTEX_NOT_LOCKED                "},
00162 {CKR_FUNCTION_REJECTED               , "CKR_FUNCTION_REJECTED               "},
00163 {CKR_VENDOR_DEFINED                  , "CKR_VENDOR_DEFINED                  "},
00164 {0xCE534351                          , "CKR_NETSCAPE_CERTDB_FAILED          "},
00165 {0xCE534352                          , "CKR_NETSCAPE_KEYDB_FAILED           "}
00166 };
00167 
00168 static const CK_ULONG numStrings = sizeof(errStrings) / sizeof(tuple_str);
00169 
00170 /* Returns constant error string for "CRV".
00171  * Returns "unknown error" if errNum is unknown.
00172  */
00173 const char *
00174 PKM_CK_RVtoStr(CK_RV errNum) {
00175     CK_ULONG low  = 1;
00176     CK_ULONG high = numStrings - 1;
00177     CK_ULONG i;
00178     CK_RV num;
00179     static int initDone;
00180 
00181     /* make sure table is in  ascending order.
00182      * binary search depends on it.
00183      */
00184     if (!initDone) {
00185         CK_RV lastNum = CKR_OK;
00186         for (i = low; i <= high; ++i) {
00187             num = errStrings[i].errNum;
00188             if (num <= lastNum) {
00189                     fprintf(stderr,
00190 "sequence error in error strings at item %d\n"
00191 "error %d (%s)\n"
00192 "should come after \n"
00193 "error %d (%s)\n",
00194                         (int) i, (int) lastNum, errStrings[i-1].errString,
00195                         (int) num, errStrings[i].errString);
00196             }
00197             lastNum = num;
00198         }
00199         initDone = 1;
00200     }
00201 
00202     /* Do binary search of table. */
00203     while (low + 1 < high) {
00204         i = (low + high) / 2;
00205         num = errStrings[i].errNum;
00206         if (errNum == num)
00207             return errStrings[i].errString;
00208         if (errNum < num)
00209             high = i;
00210         else
00211             low = i;
00212     }
00213     if (errNum == errStrings[low].errNum)
00214             return errStrings[low].errString;
00215     if (errNum == errStrings[high].errNum)
00216             return errStrings[high].errString;
00217     return "unknown error";
00218 }
00219 
00220 #include "pkcs11p.h"
00221 
00222 typedef struct CK_C_INITIALIZE_ARGS_NSS {
00223     CK_CREATEMUTEX CreateMutex;
00224     CK_DESTROYMUTEX DestroyMutex;
00225     CK_LOCKMUTEX LockMutex;
00226     CK_UNLOCKMUTEX UnlockMutex;
00227     CK_FLAGS flags;
00228     /* The official PKCS #11 spec does not have a 'LibraryParameters' field, but
00229      * a reserved field. NSS needs a way to pass instance-specific information
00230      * to the library (like where to find its config files, etc). This
00231      * information is usually provided by the installer and passed uninterpreted
00232      * by NSS to the library, though NSS does know the specifics of the softoken
00233      * version of this parameter. Most compliant PKCS#11 modules expect this
00234      * parameter to be NULL, and will return CKR_ARGUMENTS_BAD from
00235      * C_Initialize if Library parameters is supplied. */
00236     CK_CHAR_PTR *LibraryParameters;
00237     /* This field is only present if the LibraryParameters is not NULL. It must
00238      * be NULL in all cases */
00239     CK_VOID_PTR pReserved;
00240 } CK_C_INITIALIZE_ARGS_NSS;
00241 
00242 #include "pkcs11u.h"
00243 
00244 static CK_ATTRIBUTE_TYPE all_known_attribute_types[] = {
00245     CKA_CLASS,
00246     CKA_TOKEN,
00247     CKA_PRIVATE,
00248     CKA_LABEL,
00249     CKA_APPLICATION,
00250     CKA_VALUE,
00251     CKA_CERTIFICATE_TYPE,
00252     CKA_ISSUER,
00253     CKA_SERIAL_NUMBER,
00254     CKA_KEY_TYPE,
00255     CKA_SUBJECT,
00256     CKA_ID,
00257     CKA_SENSITIVE,
00258     CKA_ENCRYPT,
00259     CKA_DECRYPT,
00260     CKA_WRAP,
00261     CKA_UNWRAP,
00262     CKA_SIGN,
00263     CKA_SIGN_RECOVER,
00264     CKA_VERIFY,
00265     CKA_VERIFY_RECOVER,
00266     CKA_DERIVE,
00267     CKA_START_DATE,
00268     CKA_END_DATE,
00269     CKA_MODULUS,
00270     CKA_MODULUS_BITS,
00271     CKA_PUBLIC_EXPONENT,
00272     CKA_PRIVATE_EXPONENT,
00273     CKA_PRIME_1,
00274     CKA_PRIME_2,
00275     CKA_EXPONENT_1,
00276     CKA_EXPONENT_2,
00277     CKA_COEFFICIENT,
00278     CKA_PRIME,
00279     CKA_SUBPRIME,
00280     CKA_BASE,
00281     CKA_VALUE_BITS,
00282     CKA_VALUE_LEN,
00283     CKA_EXTRACTABLE,
00284     CKA_LOCAL,
00285     CKA_NEVER_EXTRACTABLE,
00286     CKA_ALWAYS_SENSITIVE,
00287     CKA_MODIFIABLE,
00288 #ifdef CKA_NETSCAPE
00289     CKA_NETSCAPE_URL,
00290     CKA_NETSCAPE_EMAIL,
00291     CKA_NETSCAPE_SMIME_INFO,
00292     CKA_NETSCAPE_SMIME_TIMESTAMP,
00293     CKA_NETSCAPE_PKCS8_SALT,
00294     CKA_NETSCAPE_PASSWORD_CHECK,
00295     CKA_NETSCAPE_EXPIRES,
00296 #endif /* CKA_NETSCAPE */
00297 #ifdef CKA_TRUST
00298     CKA_TRUST_DIGITAL_SIGNATURE,
00299     CKA_TRUST_NON_REPUDIATION,
00300     CKA_TRUST_KEY_ENCIPHERMENT,
00301     CKA_TRUST_DATA_ENCIPHERMENT,
00302     CKA_TRUST_KEY_AGREEMENT,
00303     CKA_TRUST_KEY_CERT_SIGN,
00304     CKA_TRUST_CRL_SIGN,
00305     CKA_TRUST_SERVER_AUTH,
00306     CKA_TRUST_CLIENT_AUTH,
00307     CKA_TRUST_CODE_SIGNING,
00308     CKA_TRUST_EMAIL_PROTECTION,
00309     CKA_TRUST_IPSEC_END_SYSTEM,
00310     CKA_TRUST_IPSEC_TUNNEL,
00311     CKA_TRUST_IPSEC_USER,
00312     CKA_TRUST_TIME_STAMPING,
00313 #endif /* CKA_TRUST */
00314 };
00315 
00316 static int number_of_all_known_attribute_types =
00317 (sizeof(all_known_attribute_types)/sizeof(all_known_attribute_types[0]));
00318 
00319 #define MAX_SIG_SZ 128
00320 #define MAX_CIPHER_SZ 128
00321 #define MAX_DATA_SZ 64
00322 #define MAX_DIGEST_SZ 64
00323 #define HMAC_MAX_LENGTH 64
00324 #define FIPSMODE 0
00325 #define NONFIPSMODE 1
00326 #define HYBRIDMODE 2
00327 #define NOMODE 3
00328 int MODE = FIPSMODE;
00329 
00330 CK_BBOOL true = CK_TRUE;
00331 CK_BBOOL false = CK_FALSE;
00332 static const CK_BYTE PLAINTEXT[] = {"Firefox  Rules!"};
00333 static const CK_BYTE PLAINTEXT_PAD[] = 
00334                                   {"Firefox and thunderbird rule the world!"};
00335 CK_ULONG NUMTESTS = 0;
00336 
00337 static const char * slotFlagName[] = {
00338     "CKF_TOKEN_PRESENT",
00339     "CKF_REMOVABLE_DEVICE",
00340     "CKF_HW_SLOT",
00341     "unknown token flag 0x00000008",
00342     "unknown token flag 0x00000010",
00343     "unknown token flag 0x00000020",
00344     "unknown token flag 0x00000040",
00345     "unknown token flag 0x00000080",
00346     "unknown token flag 0x00000100",
00347     "unknown token flag 0x00000200",
00348     "unknown token flag 0x00000400",
00349     "unknown token flag 0x00000800",
00350     "unknown token flag 0x00001000",
00351     "unknown token flag 0x00002000",
00352     "unknown token flag 0x00004000",
00353     "unknown token flag 0x00008000"
00354     "unknown token flag 0x00010000",
00355     "unknown token flag 0x00020000",
00356     "unknown token flag 0x00040000",
00357     "unknown token flag 0x00080000",
00358     "unknown token flag 0x00100000",
00359     "unknown token flag 0x00200000",
00360     "unknown token flag 0x00400000",
00361     "unknown token flag 0x00800000"
00362     "unknown token flag 0x01000000",
00363     "unknown token flag 0x02000000",
00364     "unknown token flag 0x04000000",
00365     "unknown token flag 0x08000000",
00366     "unknown token flag 0x10000000",
00367     "unknown token flag 0x20000000",
00368     "unknown token flag 0x40000000",
00369     "unknown token flag 0x80000000"
00370 };
00371 
00372 static const char * tokenFlagName[] = {
00373     "CKF_PKM_RNG",
00374     "CKF_WRITE_PROTECTED",
00375     "CKF_LOGIN_REQUIRED",
00376     "CKF_USER_PIN_INITIALIZED",
00377     "unknown token flag 0x00000010",
00378     "CKF_RESTORE_KEY_NOT_NEEDED",
00379     "CKF_CLOCK_ON_TOKEN",
00380     "unknown token flag 0x00000080",
00381     "CKF_PROTECTED_AUTHENTICATION_PATH",
00382     "CKF_DUAL_CRYPTO_OPERATIONS",
00383     "CKF_TOKEN_INITIALIZED",
00384     "CKF_SECONDARY_AUTHENTICATION",
00385     "unknown token flag 0x00001000",
00386     "unknown token flag 0x00002000",
00387     "unknown token flag 0x00004000",
00388     "unknown token flag 0x00008000",
00389     "CKF_USER_PIN_COUNT_LOW",
00390     "CKF_USER_PIN_FINAL_TRY",
00391     "CKF_USER_PIN_LOCKED",
00392     "CKF_USER_PIN_TO_BE_CHANGED",
00393     "CKF_SO_PIN_COUNT_LOW",
00394     "CKF_SO_PIN_FINAL_TRY",
00395     "CKF_SO_PIN_LOCKED",
00396     "CKF_SO_PIN_TO_BE_CHANGED",
00397     "unknown token flag 0x01000000",
00398     "unknown token flag 0x02000000",
00399     "unknown token flag 0x04000000",
00400     "unknown token flag 0x08000000",
00401     "unknown token flag 0x10000000",
00402     "unknown token flag 0x20000000",
00403     "unknown token flag 0x40000000",
00404     "unknown token flag 0x80000000"
00405 };
00406 
00407 static const unsigned char TLSClientRandom[] = {
00408     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00409     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00410     0x0d, 0x90, 0xbb, 0x5e, 0xc6, 0xe1, 0x3f, 0x71,
00411     0x0a, 0xa2, 0x70, 0x5a, 0x4f, 0xbc, 0x3f, 0x0d
00412 };
00413 static const unsigned char TLSServerRandom[] = {
00414     0x00, 0x00, 0x1d, 0x4a, 0x7a, 0x0a, 0xa5, 0x01,
00415     0x8e, 0x79, 0x72, 0xde, 0x9e, 0x2f, 0x8a, 0x0d,
00416     0xed, 0xb2, 0x5d, 0xf1, 0x14, 0xc2, 0xc6, 0x66,
00417     0x95, 0x86, 0xb0, 0x0d, 0x87, 0x2a, 0x2a, 0xc9
00418 };
00419 
00420 typedef enum {
00421     CORRECT,
00422     BOGUS_CLIENT_RANDOM,
00423     BOGUS_CLIENT_RANDOM_LEN,
00424     BOGUS_SERVER_RANDOM,
00425     BOGUS_SERVER_RANDOM_LEN
00426 } enum_random_t;
00427 
00428 void
00429 dumpToHash64(const unsigned char *buf, unsigned int bufLen)
00430 {
00431     unsigned int i;
00432     for (i = 0; i < bufLen; i += 8) {
00433         if (i % 32 == 0)
00434             printf("\n");
00435         printf(" 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,",
00436                buf[i  ], buf[i+1], buf[i+2], buf[i+3],
00437                buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
00438     }
00439     printf("\n");
00440 }
00441 
00442 
00443 #ifdef _WIN32
00444 HMODULE hModule;
00445 #else
00446 PRLibrary *lib;
00447 #endif
00448 
00449 /*
00450 * All api that belongs to pk11mode.c layer start with the prefix PKM_
00451 */
00452 void PKM_LogIt(const char *fmt, ...);
00453 void PKM_Error(const char *fmt, ...);
00454 CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
00455                             CK_ULONG slotID);
00456 CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID);
00457 CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
00458                       CK_SLOT_ID *pSlotList, CK_ULONG slotID,
00459                       CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00460 CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
00461                     CK_SLOT_ID * pSlotList, CK_ULONG slotID);
00462 CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID * pSlotList,
00463               CK_ULONG slotID);
00464 CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,
00465                        CK_SLOT_ID *pSlotList, CK_ULONG slotID,
00466                        CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00467 CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
00468                     CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00469 CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
00470                     CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00471 CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, 
00472                      CK_C_INITIALIZE_ARGS_NSS *initArgs);
00473 CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,
00474                           CK_SLOT_ID * pSlotList, CK_ULONG slotID,
00475                           CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00476 CK_RV PKM_MultiObjectManagement(CK_FUNCTION_LIST_PTR pFunctionList,
00477                                  CK_SLOT_ID * pSlotList, CK_ULONG slotID,
00478                                  CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00479 CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,
00480                             CK_SLOT_ID * pSlotList, CK_ULONG slotID,
00481                             CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00482 CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
00483                           CK_SLOT_ID *pSlotList, CK_ULONG slotID,
00484                           CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00485 CK_RV PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,
00486                          CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj,
00487                          CK_ATTRIBUTE_PTR expected_attrs,
00488                          CK_ULONG expected_attrs_count);
00489 CK_RV PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList,
00490                     CK_SESSION_HANDLE hSession, CK_MECHANISM_TYPE mechType,
00491                     CK_FLAGS flags, CK_BBOOL check_sizes,
00492                     CK_ULONG minkeysize, CK_ULONG maxkeysize);
00493 CK_RV PKM_TLSKeyAndMacDerive(CK_FUNCTION_LIST_PTR pFunctionList,
00494                             CK_SLOT_ID * pSlotList, CK_ULONG slotID,
00495                             CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
00496                             CK_MECHANISM_TYPE mechType, enum_random_t rnd);
00497 CK_RV PKM_TLSMasterKeyDerive(CK_FUNCTION_LIST_PTR pFunctionList,
00498                             CK_SLOT_ID * pSlotList, CK_ULONG slotID,
00499                             CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
00500                             CK_MECHANISM_TYPE mechType,
00501                             enum_random_t rnd);
00502 CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
00503                        CK_SLOT_ID *pSlotList, CK_ULONG slotID,
00504                        CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
00505 CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,
00506                       CK_SESSION_HANDLE hRwSession,
00507                       CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey,
00508                       CK_MECHANISM *sigMech, CK_OBJECT_HANDLE secretKey,
00509                       CK_MECHANISM *cryptMech, 
00510                       const CK_BYTE *  pData, CK_ULONG pDataLen);
00511 CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,
00512                        CK_SESSION_HANDLE hSession,
00513                        CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech,
00514                        CK_OBJECT_HANDLE hSecKeyDigest, 
00515                        CK_MECHANISM *digestMech, 
00516                        const CK_BYTE *  pData, CK_ULONG pDataLen); 
00517 CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList, 
00518                      CK_SESSION_HANDLE hRwSession,
00519                      CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
00520                      CK_MECHANISM *signMech, const CK_BYTE *  pData, 
00521                      CK_ULONG dataLen);
00522 CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList, 
00523                       CK_SESSION_HANDLE hSession,
00524                       CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech,
00525                       const CK_BYTE *  pData, CK_ULONG dataLen);
00526 CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
00527                 CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech, 
00528                 const CK_BYTE *  pData, CK_ULONG pDataLen);
00529 CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList, 
00530                  CK_SESSION_HANDLE hRwSession,
00531                  CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey,
00532                  const CK_BYTE *  pData, CK_ULONG pDataLen);
00533 CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,
00534                      CK_SESSION_HANDLE hSession, 
00535                      CK_OBJECT_HANDLE hPublicKey, 
00536                      CK_OBJECT_HANDLE hPrivateKey,
00537                      CK_MECHANISM *wrapMechanism,
00538                      CK_OBJECT_HANDLE hSecretKey,
00539                      CK_ATTRIBUTE *sKeyTemplate,
00540                      CK_ULONG skeyTempSize);
00541 CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList, 
00542                     CK_SESSION_HANDLE hSession,
00543                     CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
00544                     CK_MECHANISM *signMech, const CK_BYTE * pData, 
00545                     CK_ULONG pDataLen);
00546 void  PKM_Help(); 
00547 void  PKM_CheckPath(char *string);
00548 char  *PKM_FilePasswd(char *pwFile);
00549 static PRBool verbose = PR_FALSE;
00550 
00551 int main(int argc, char **argv)
00552 {
00553     CK_C_GetFunctionList pC_GetFunctionList;
00554     CK_FUNCTION_LIST_PTR pFunctionList;
00555     CK_RV crv = CKR_OK;
00556     CK_C_INITIALIZE_ARGS_NSS initArgs;
00557     CK_SLOT_ID *pSlotList = NULL;
00558     CK_TOKEN_INFO tokenInfo;
00559     CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */
00560 
00561     CK_UTF8CHAR *pwd = NULL;
00562     CK_ULONG pwdLen = 0;
00563     char *moduleSpec = NULL;
00564     char *configDir = NULL;
00565     char *dbPrefix = NULL;
00566     char *disableUnload = NULL;
00567 
00568     PLOptStatus os;
00569     PLOptState *opt = PL_CreateOptState(argc, argv, "nvhf:d:p:");
00570     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
00571     {
00572         if (PL_OPT_BAD == os) continue;
00573        switch (opt->option)
00574         {
00575         case 'n':  /* non fips mode */
00576             MODE = NONFIPSMODE;
00577             slotID = 1;
00578             break;
00579         case 'f':  /* password file */
00580             pwd = (CK_UTF8CHAR *) PKM_FilePasswd((char *)opt->value);
00581             if (!pwd) PKM_Help();
00582             break;
00583         case 'd':  /* opt_CertDir */
00584             if (!opt->value) PKM_Help();
00585             configDir = strdup(opt->value);
00586             PKM_CheckPath(configDir);
00587             break;
00588         case 'p':  /* opt_DBPrefix */
00589             if (!opt->value) PKM_Help();
00590             dbPrefix = strdup(opt->value);
00591             break;
00592         case 'v':
00593             verbose = PR_TRUE;
00594             break;
00595         case 'h':  /* help message */
00596         default:
00597             PKM_Help();
00598             break;
00599         }
00600     }
00601     PL_DestroyOptState(opt);
00602 
00603     if (!pwd) {
00604         pwd = (CK_UTF8CHAR *)strdup("1Mozilla");
00605     }
00606     pwdLen = strlen((const char*)pwd); 
00607     if (!configDir) {
00608         configDir = strdup(".");
00609     }
00610     if (!dbPrefix) {
00611         dbPrefix = strdup("");
00612     }
00613 
00614 #ifdef _WIN32
00615     hModule = LoadLibrary(LIB_NAME);
00616     if (hModule == NULL) {
00617         PKM_Error( "cannot load %s\n", LIB_NAME);
00618         goto cleanup;
00619     }
00620     if (MODE == FIPSMODE) {
00621         /* FIPS mode == FC_GetFunctionList */
00622         pC_GetFunctionList = (CK_C_GetFunctionList)
00623                              GetProcAddress(hModule, "FC_GetFunctionList");
00624     } else {
00625         /* NON FIPS mode  == C_GetFunctionList */
00626         pC_GetFunctionList = (CK_C_GetFunctionList)
00627                              GetProcAddress(hModule, "C_GetFunctionList");
00628      }
00629     if (pC_GetFunctionList == NULL) {
00630         PKM_Error( "cannot load %s\n", LIB_NAME);
00631         goto cleanup;
00632     }
00633 #else
00634     {
00635     char *libname = NULL;
00636     /* Get the platform-dependent library name of the NSS cryptographic module */
00637     libname = PR_GetLibraryName(NULL, "softokn3");
00638     assert(libname != NULL);
00639     lib = PR_LoadLibrary(libname);
00640     assert(lib != NULL);
00641     PR_FreeLibraryName(libname);
00642     } 
00643     if (MODE == FIPSMODE) {
00644         pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
00645         "FC_GetFunctionList");
00646         assert(pC_GetFunctionList != NULL);
00647         slotID = 0;
00648     } else {
00649         pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
00650         "C_GetFunctionList");
00651         assert(pC_GetFunctionList != NULL);
00652         slotID = 1;
00653     }
00654 #endif
00655 
00656     if (MODE == FIPSMODE) {
00657         printf("Loaded FC_GetFunctionList for FIPS MODE; slotID %d \n",
00658                (int) slotID);
00659     } else {
00660         printf("loaded C_GetFunctionList for NON FIPS MODE; slotID %d \n",
00661                 (int) slotID);
00662     }
00663 
00664     crv = (*pC_GetFunctionList)(&pFunctionList);
00665     assert(crv == CKR_OK);
00666 
00667     initArgs.CreateMutex = NULL;
00668     initArgs.DestroyMutex = NULL;
00669     initArgs.LockMutex = NULL;
00670     initArgs.UnlockMutex = NULL;
00671     initArgs.flags = CKF_OS_LOCKING_OK;
00672     moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' "
00673                              "keyPrefix='%s' secmod='secmod.db' flags= ",
00674                              configDir, dbPrefix, dbPrefix);
00675     initArgs.LibraryParameters = (CK_CHAR_PTR *) moduleSpec;
00676     initArgs.pReserved = NULL;
00677 
00678     /*DebugBreak();*/
00679     /* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */
00680     /* NSS cryptographic module library initialization for the FIPS  */
00681     /* Approved mode when FC_Initialize is envoked will perfom       */
00682     /* software integrity test, and power-up self-tests before       */
00683     /* FC_Initialize returns                                         */
00684     crv = pFunctionList->C_Initialize(&initArgs);
00685     if (crv == CKR_OK) {
00686         PKM_LogIt("C_Initialize succeeded\n");
00687     } else {
00688         PKM_Error( "C_Initialize failed with 0x%08X, %-26s\n", crv, 
00689                    PKM_CK_RVtoStr(crv));
00690         goto cleanup;
00691     }
00692     crv = PKM_ShowInfo(pFunctionList, slotID);
00693     if (crv == CKR_OK) {
00694         PKM_LogIt("PKM_ShowInfo succeeded\n");
00695     } else {
00696         PKM_Error( "PKM_ShowInfo failed with 0x%08X, %-26s\n", crv, 
00697                    PKM_CK_RVtoStr(crv));
00698         goto cleanup;
00699     }
00700     pSlotList = PKM_GetSlotList(pFunctionList, slotID);
00701     if (pSlotList == NULL) {
00702         PKM_Error( "PKM_GetSlotList failed with \n");
00703         goto cleanup;
00704     }
00705     crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
00706     if (crv == CKR_OK) {
00707         PKM_LogIt("C_GetTokenInfo succeeded\n\n");
00708     } else {
00709         PKM_Error( "C_GetTokenInfo failed with 0x%08X, %-26s\n", crv, 
00710                    PKM_CK_RVtoStr(crv));
00711         goto cleanup;
00712     }
00713 
00714     if (!(tokenInfo.flags & CKF_USER_PIN_INITIALIZED)) {
00715         PKM_LogIt("Initing PW for DB\n");
00716         crv = PKM_InitPWforDB(pFunctionList, pSlotList, slotID,
00717                         pwd, pwdLen);
00718         if (crv == CKR_OK) {
00719             PKM_LogIt("PKM_InitPWforDB succeeded\n\n");
00720         } else {
00721             PKM_Error( "PKM_InitPWforDB failed with 0x%08X, %-26s\n", crv, 
00722                    PKM_CK_RVtoStr(crv));
00723             goto cleanup;
00724         }
00725     } else {
00726         PKM_LogIt("using existing DB\n");
00727     }
00728 
00729     /* general mechanism by token */ 
00730     crv = PKM_Mechanism(pFunctionList, pSlotList, slotID);
00731     if (crv == CKR_OK) {
00732         PKM_LogIt("PKM_Mechanism succeeded\n\n");
00733     } else {
00734         PKM_Error( "PKM_Mechanism failed with 0x%08X, %-26s\n", crv, 
00735                    PKM_CK_RVtoStr(crv));
00736         goto cleanup;
00737     } 
00738     /* RNG example without Login */
00739     crv = PKM_RNG(pFunctionList, pSlotList, slotID);
00740     if (crv == CKR_OK) {
00741         PKM_LogIt("PKM_RNG succeeded\n\n");
00742     } else {
00743         PKM_Error( "PKM_RNG failed with 0x%08X, %-26s\n", crv, 
00744                    PKM_CK_RVtoStr(crv));
00745         goto cleanup;
00746     }
00747 
00748     crv = PKM_SessionLogin(pFunctionList, pSlotList, slotID,
00749                            pwd, pwdLen);
00750     if (crv == CKR_OK) {
00751         PKM_LogIt("PKM_SessionLogin succeeded\n\n");
00752     } else {
00753         PKM_Error( "PKM_SessionLogin failed with 0x%08X, %-26s\n", crv, 
00754                    PKM_CK_RVtoStr(crv));
00755         goto cleanup;
00756     }
00757 
00758     /*
00759      * PKM_KeyTest creates RSA,DSA public keys 
00760      * and AES, DES3 secret keys.
00761      * then does digest, hmac, encrypt/decrypt, signing operations. 
00762      */
00763     crv = PKM_KeyTests(pFunctionList, pSlotList, slotID,
00764                             pwd, pwdLen);
00765     if (crv == CKR_OK) {
00766         PKM_LogIt("PKM_KeyTests succeeded\n\n");
00767     } else {
00768         PKM_Error( "PKM_KeyTest failed with 0x%08X, %-26s\n", crv, 
00769                    PKM_CK_RVtoStr(crv));
00770         goto cleanup;
00771     }
00772 
00773     crv = PKM_SecretKey(pFunctionList, pSlotList, slotID, pwd, 
00774                         pwdLen);
00775     if (crv == CKR_OK) {
00776         PKM_LogIt("PKM_SecretKey succeeded\n\n");
00777     } else {
00778         PKM_Error( "PKM_SecretKey failed with 0x%08X, %-26s\n", crv, 
00779                    PKM_CK_RVtoStr(crv));
00780         goto cleanup;
00781     }
00782 
00783     crv = PKM_PublicKey(pFunctionList, pSlotList, slotID,
00784                         pwd, pwdLen);
00785     if (crv == CKR_OK) {
00786         PKM_LogIt("PKM_PublicKey succeeded\n\n");
00787     } else {
00788         PKM_Error( "PKM_PublicKey failed with 0x%08X, %-26s\n", crv, 
00789                    PKM_CK_RVtoStr(crv));
00790         goto cleanup;
00791     }
00792     crv = PKM_OperationalState(pFunctionList, pSlotList, slotID,
00793                                pwd, pwdLen);
00794     if (crv == CKR_OK) {
00795         PKM_LogIt("PKM_OperationalState succeeded\n\n");
00796     } else {
00797         PKM_Error( "PKM_OperationalState failed with 0x%08X, %-26s\n", crv, 
00798                    PKM_CK_RVtoStr(crv));
00799         goto cleanup;
00800     }
00801     crv = PKM_MultiObjectManagement(pFunctionList, pSlotList, slotID,
00802                                     pwd, pwdLen);
00803     if (crv == CKR_OK) {
00804         PKM_LogIt("PKM_MultiObjectManagement succeeded\n\n");
00805     } else {
00806         PKM_Error( "PKM_MultiObjectManagement failed with 0x%08X, %-26s\n", crv, 
00807                    PKM_CK_RVtoStr(crv));
00808         goto cleanup;
00809     }
00810     crv = PKM_LegacyFunctions(pFunctionList, pSlotList, slotID,
00811                               pwd, pwdLen);
00812     if (crv == CKR_OK) {
00813         PKM_LogIt("PKM_LegacyFunctions succeeded\n\n");
00814     } else {
00815         PKM_Error( "PKM_LegacyFunctions failed with 0x%08X, %-26s\n", crv, 
00816                    PKM_CK_RVtoStr(crv));
00817         goto cleanup;
00818     }
00819     crv = PKM_TLSKeyAndMacDerive(pFunctionList, pSlotList, slotID,
00820                                  pwd, pwdLen,
00821                                  CKM_TLS_KEY_AND_MAC_DERIVE, CORRECT);
00822 
00823     if (crv == CKR_OK) {
00824         PKM_LogIt("PKM_TLSKeyAndMacDerive succeeded\n\n");
00825     } else {
00826         PKM_Error( "PKM_TLSKeyAndMacDerive failed with 0x%08X, %-26s\n", crv, 
00827                    PKM_CK_RVtoStr(crv));
00828         goto cleanup;
00829     }
00830     crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
00831                                  pwd, pwdLen,
00832                                  CKM_TLS_MASTER_KEY_DERIVE,
00833                                  CORRECT);
00834     if (crv == CKR_OK) {
00835         PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
00836     } else {
00837         PKM_Error( "PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv, 
00838                    PKM_CK_RVtoStr(crv));
00839         goto cleanup;
00840     }
00841     crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
00842                                  pwd, pwdLen,
00843                                  CKM_TLS_MASTER_KEY_DERIVE_DH,
00844                                  CORRECT);
00845     if (crv == CKR_OK) {
00846         PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
00847     } else {
00848         PKM_Error( "PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv, 
00849                    PKM_CK_RVtoStr(crv));
00850         goto cleanup;
00851     }
00852     crv = PKM_FindAllObjects(pFunctionList, pSlotList, slotID,
00853                              pwd, pwdLen);
00854     if (crv == CKR_OK) {
00855         PKM_LogIt("PKM_FindAllObjects succeeded\n\n");
00856     } else {
00857         PKM_Error( "PKM_FindAllObjects failed with 0x%08X, %-26s\n", crv, 
00858                    PKM_CK_RVtoStr(crv));
00859         goto cleanup;
00860     }
00861     crv = pFunctionList->C_Finalize(NULL);
00862     if (crv == CKR_OK) {
00863         PKM_LogIt("C_Finalize succeeded\n");
00864     } else {
00865         PKM_Error( "C_Finalize failed with 0x%08X, %-26s\n", crv, 
00866                    PKM_CK_RVtoStr(crv));
00867         goto cleanup;
00868     }
00869 
00870     if (pSlotList) free(pSlotList);
00871 
00872     /* demostrate how an application can be in Hybrid mode */
00873     /* PKM_HybridMode shows how to switch between NONFIPS */
00874     /* mode to FIPS mode */
00875 
00876     PKM_LogIt("Testing Hybrid mode \n");
00877     crv = PKM_HybridMode(pwd, pwdLen, &initArgs);
00878     if (crv == CKR_OK) {
00879         PKM_LogIt("PKM_HybridMode succeeded\n");
00880     } else {
00881         PKM_Error( "PKM_HybridMode failed with 0x%08X, %-26s\n", crv, 
00882                    PKM_CK_RVtoStr(crv));
00883         goto cleanup;
00884     }
00885 
00886     printf("**** Total number of TESTS ran in %s is %d. ****\n", 
00887           ((MODE == FIPSMODE) ? "FIPS MODE" : "NON FIPS MODE"), (int) NUMTESTS);    
00888     printf("**** ALL TESTS PASSED ****\n");
00889     PKM_LogIt("unloading NSS PKCS # 11 softoken and exiting\n");
00890 
00891 cleanup:
00892 
00893     if (pwd) {
00894         free(pwd);
00895     }
00896     if (configDir) {
00897         free(configDir);
00898     }
00899     if (dbPrefix) {
00900         free(dbPrefix);
00901     }
00902     if (moduleSpec) {
00903         free(moduleSpec);
00904     }
00905 
00906 #ifdef _WIN32
00907     FreeLibrary(hModule);
00908 #else
00909     disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
00910     if (!disableUnload) {
00911         PR_UnloadLibrary(lib);
00912     }
00913 #endif
00914 
00915     return crv;
00916 }
00917 
00918 /*
00919 *  PKM_KeyTests
00920 *
00921 *
00922 */
00923 
00924 CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
00925                         CK_SLOT_ID * pSlotList, CK_ULONG slotID,
00926                         CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
00927     CK_SESSION_HANDLE hRwSession;
00928 
00929     CK_RV crv = CKR_OK;
00930 
00931 /*** DSA Key ***/
00932     CK_MECHANISM dsaParamGenMech;
00933     CK_ULONG primeBits = 1024;
00934     CK_ATTRIBUTE dsaParamGenTemplate[1]; 
00935     CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE;
00936     CK_BYTE DSA_P[128];
00937     CK_BYTE DSA_Q[20];
00938     CK_BYTE DSA_G[128];
00939     CK_MECHANISM dsaKeyPairGenMech;
00940     CK_ATTRIBUTE dsaPubKeyTemplate[5]; 
00941     CK_ATTRIBUTE dsaPrivKeyTemplate[5]; 
00942     CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
00943     CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
00944 
00945 /**** RSA Key ***/
00946     CK_KEY_TYPE rsatype = CKK_RSA;
00947     CK_MECHANISM rsaKeyPairGenMech;
00948     CK_BYTE subject[] = {"RSA Private Key"};
00949     CK_ULONG modulusBits = 1024;
00950     CK_BYTE publicExponent[] = {0x01, 0x00, 0x01};
00951     CK_BYTE id[] = {"RSA123"};
00952     CK_ATTRIBUTE rsaPubKeyTemplate[9]; 
00953     CK_ATTRIBUTE rsaPrivKeyTemplate[11]; 
00954     CK_OBJECT_HANDLE hRSApubKey = CK_INVALID_HANDLE;
00955     CK_OBJECT_HANDLE hRSAprivKey = CK_INVALID_HANDLE;
00956 
00957  /*** AES Key ***/
00958     CK_MECHANISM sAESKeyMech = {
00959         CKM_AES_KEY_GEN, NULL, 0
00960     };
00961     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
00962     CK_KEY_TYPE keyAESType = CKK_AES;
00963     CK_UTF8CHAR AESlabel[] = "An AES secret key object";
00964     CK_ULONG AESvalueLen = 32;
00965     CK_ATTRIBUTE sAESKeyTemplate[9];    
00966     CK_OBJECT_HANDLE hAESSecKey;
00967 
00968 /*** DES3 Key ***/
00969     CK_KEY_TYPE keyDES3Type = CKK_DES3;
00970     CK_UTF8CHAR DES3label[] = "An Triple DES secret key object";
00971     CK_ULONG DES3valueLen = 56;
00972     CK_MECHANISM sDES3KeyGenMechanism = {
00973         CKM_DES3_KEY_GEN, NULL, 0
00974     };
00975     CK_ATTRIBUTE sDES3KeyTemplate[9];
00976     CK_OBJECT_HANDLE hDES3SecKey;
00977     
00978     CK_MECHANISM dsaWithSha1Mech = {
00979         CKM_DSA_SHA1, NULL, 0
00980     };
00981 
00982     CK_BYTE IV[16];
00983     CK_MECHANISM mech_DES3_CBC; 
00984     CK_MECHANISM mech_DES3_CBC_PAD; 
00985     CK_MECHANISM mech_AES_CBC_PAD;
00986     CK_MECHANISM mech_AES_CBC;
00987     struct mech_str {
00988         CK_ULONG    mechanism;
00989         const char *mechanismStr;
00990     };
00991 
00992     typedef struct mech_str mech_str;
00993 
00994     mech_str digestMechs[] = {
00995         {CKM_SHA_1, "CKM_SHA_1 "},
00996         {CKM_SHA256, "CKM_SHA256"},
00997         {CKM_SHA384, "CKM_SHA384"},
00998         {CKM_SHA512, "CKM_SHA512"}
00999     };
01000     mech_str hmacMechs[] = {
01001         {CKM_SHA_1_HMAC, "CKM_SHA_1_HMAC"}, 
01002         {CKM_SHA256_HMAC, "CKM_SHA256_HMAC"},
01003         {CKM_SHA384_HMAC, "CKM_SHA384_HMAC"},
01004         {CKM_SHA512_HMAC, "CKM_SHA512_HMAC"}
01005     };
01006     mech_str sigRSAMechs[] = {
01007         {CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS"}, 
01008         {CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS"},
01009         {CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS"},
01010         {CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS"}
01011     };
01012 
01013     CK_ULONG digestMechsSZ = NUM_ELEM(digestMechs);
01014     CK_ULONG sigRSAMechsSZ = NUM_ELEM(sigRSAMechs);
01015     CK_ULONG hmacMechsSZ = NUM_ELEM(hmacMechs);
01016     CK_MECHANISM mech;
01017 
01018     unsigned int i;
01019 
01020     NUMTESTS++; /* increment NUMTESTS */
01021 
01022     /* DSA key init */
01023     dsaParamGenMech.mechanism      = CKM_DSA_PARAMETER_GEN; 
01024     dsaParamGenMech.pParameter = NULL_PTR; 
01025     dsaParamGenMech.ulParameterLen = 0;
01026     dsaParamGenTemplate[0].type = CKA_PRIME_BITS; 
01027     dsaParamGenTemplate[0].pValue     = &primeBits; 
01028     dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits);
01029     dsaPubKeyTemplate[0].type       = CKA_PRIME; 
01030     dsaPubKeyTemplate[0].pValue     = DSA_P;
01031     dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P);
01032     dsaPubKeyTemplate[1].type = CKA_SUBPRIME; 
01033     dsaPubKeyTemplate[1].pValue = DSA_Q;
01034     dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q);
01035     dsaPubKeyTemplate[2].type = CKA_BASE; 
01036     dsaPubKeyTemplate[2].pValue = DSA_G; 
01037     dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G);
01038     dsaPubKeyTemplate[3].type = CKA_TOKEN; 
01039     dsaPubKeyTemplate[3].pValue = &true; 
01040     dsaPubKeyTemplate[3].ulValueLen = sizeof(true);
01041     dsaPubKeyTemplate[4].type = CKA_VERIFY; 
01042     dsaPubKeyTemplate[4].pValue = &true; 
01043     dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
01044     dsaKeyPairGenMech.mechanism      = CKM_DSA_KEY_PAIR_GEN;
01045     dsaKeyPairGenMech.pParameter = NULL_PTR;
01046     dsaKeyPairGenMech.ulParameterLen = 0;
01047     dsaPrivKeyTemplate[0].type       = CKA_TOKEN;
01048     dsaPrivKeyTemplate[0].pValue     = &true; 
01049     dsaPrivKeyTemplate[0].ulValueLen = sizeof(true);
01050     dsaPrivKeyTemplate[1].type       = CKA_PRIVATE; 
01051     dsaPrivKeyTemplate[1].pValue     = &true; 
01052     dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
01053     dsaPrivKeyTemplate[2].type       = CKA_SENSITIVE; 
01054     dsaPrivKeyTemplate[2].pValue     = &true; 
01055     dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
01056     dsaPrivKeyTemplate[3].type       = CKA_SIGN, 
01057     dsaPrivKeyTemplate[3].pValue     = &true;
01058     dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
01059     dsaPrivKeyTemplate[4].type       = CKA_EXTRACTABLE; 
01060     dsaPrivKeyTemplate[4].pValue     = &true; 
01061     dsaPrivKeyTemplate[4].ulValueLen = sizeof(true);
01062 
01063     /* RSA key init */
01064     rsaKeyPairGenMech.mechanism      = CKM_RSA_PKCS_KEY_PAIR_GEN;
01065     rsaKeyPairGenMech.pParameter = NULL_PTR;
01066     rsaKeyPairGenMech.ulParameterLen = 0;
01067 
01068     rsaPubKeyTemplate[0].type       = CKA_KEY_TYPE; 
01069     rsaPubKeyTemplate[0].pValue     = &rsatype; 
01070     rsaPubKeyTemplate[0].ulValueLen = sizeof(rsatype);
01071     rsaPubKeyTemplate[1].type       = CKA_PRIVATE; 
01072     rsaPubKeyTemplate[1].pValue     = &true; 
01073     rsaPubKeyTemplate[1].ulValueLen = sizeof(true);
01074     rsaPubKeyTemplate[2].type       = CKA_ENCRYPT;
01075     rsaPubKeyTemplate[2].pValue     = &true; 
01076     rsaPubKeyTemplate[2].ulValueLen = sizeof(true);
01077     rsaPubKeyTemplate[3].type       = CKA_DECRYPT;
01078     rsaPubKeyTemplate[3].pValue     = &true;
01079     rsaPubKeyTemplate[3].ulValueLen = sizeof(true);
01080     rsaPubKeyTemplate[4].type       = CKA_VERIFY;
01081     rsaPubKeyTemplate[4].pValue     = &true; 
01082     rsaPubKeyTemplate[4].ulValueLen = sizeof(true);
01083     rsaPubKeyTemplate[5].type       = CKA_SIGN;
01084     rsaPubKeyTemplate[5].pValue     = &true; 
01085     rsaPubKeyTemplate[5].ulValueLen = sizeof(true);
01086     rsaPubKeyTemplate[6].type       = CKA_WRAP; 
01087     rsaPubKeyTemplate[6].pValue     = &true; 
01088     rsaPubKeyTemplate[6].ulValueLen = sizeof(true);
01089     rsaPubKeyTemplate[7].type       = CKA_MODULUS_BITS; 
01090     rsaPubKeyTemplate[7].pValue     = &modulusBits; 
01091     rsaPubKeyTemplate[7].ulValueLen = sizeof(modulusBits);
01092     rsaPubKeyTemplate[8].type       = CKA_PUBLIC_EXPONENT; 
01093     rsaPubKeyTemplate[8].pValue     = publicExponent; 
01094     rsaPubKeyTemplate[8].ulValueLen = sizeof (publicExponent);
01095 
01096     rsaPrivKeyTemplate[0].type       = CKA_KEY_TYPE;
01097     rsaPrivKeyTemplate[0].pValue     = &rsatype; 
01098     rsaPrivKeyTemplate[0].ulValueLen = sizeof(rsatype);
01099     rsaPrivKeyTemplate[1].type       = CKA_TOKEN;
01100     rsaPrivKeyTemplate[1].pValue     = &true; 
01101     rsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
01102     rsaPrivKeyTemplate[2].type       = CKA_PRIVATE;
01103     rsaPrivKeyTemplate[2].pValue     = &true; 
01104     rsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
01105     rsaPrivKeyTemplate[3].type       = CKA_SUBJECT; 
01106     rsaPrivKeyTemplate[3].pValue     = subject; 
01107     rsaPrivKeyTemplate[3].ulValueLen = sizeof(subject);
01108     rsaPrivKeyTemplate[4].type       = CKA_ID; 
01109     rsaPrivKeyTemplate[4].pValue     = id; 
01110     rsaPrivKeyTemplate[4].ulValueLen = sizeof(id);
01111     rsaPrivKeyTemplate[5].type       = CKA_SENSITIVE; 
01112     rsaPrivKeyTemplate[5].pValue     = &true; 
01113     rsaPrivKeyTemplate[5].ulValueLen = sizeof(true);
01114     rsaPrivKeyTemplate[6].type       = CKA_ENCRYPT; 
01115     rsaPrivKeyTemplate[6].pValue     = &true; 
01116     rsaPrivKeyTemplate[6].ulValueLen = sizeof(true);
01117     rsaPrivKeyTemplate[7].type       = CKA_DECRYPT; 
01118     rsaPrivKeyTemplate[7].pValue     = &true; 
01119     rsaPrivKeyTemplate[7].ulValueLen = sizeof(true);
01120     rsaPrivKeyTemplate[8].type       = CKA_VERIFY; 
01121     rsaPrivKeyTemplate[8].pValue     = &true; 
01122     rsaPrivKeyTemplate[8].ulValueLen = sizeof(true);
01123     rsaPrivKeyTemplate[9].type       = CKA_SIGN; 
01124     rsaPrivKeyTemplate[9].pValue     = &true; 
01125     rsaPrivKeyTemplate[9].ulValueLen = sizeof(true);
01126     rsaPrivKeyTemplate[10].type       = CKA_UNWRAP; 
01127     rsaPrivKeyTemplate[10].pValue     = &true; 
01128     rsaPrivKeyTemplate[10].ulValueLen = sizeof(true);
01129     
01130     /* AES key template */
01131     sAESKeyTemplate[0].type       = CKA_CLASS; 
01132     sAESKeyTemplate[0].pValue     = &class;
01133     sAESKeyTemplate[0].ulValueLen = sizeof(class);
01134     sAESKeyTemplate[1].type       = CKA_KEY_TYPE; 
01135     sAESKeyTemplate[1].pValue     = &keyAESType; 
01136     sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
01137     sAESKeyTemplate[2].type       = CKA_LABEL;
01138     sAESKeyTemplate[2].pValue     = AESlabel; 
01139     sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1;
01140     sAESKeyTemplate[3].type       = CKA_ENCRYPT; 
01141     sAESKeyTemplate[3].pValue     = &true; 
01142     sAESKeyTemplate[3].ulValueLen = sizeof(true);
01143     sAESKeyTemplate[4].type       = CKA_DECRYPT; 
01144     sAESKeyTemplate[4].pValue     = &true; 
01145     sAESKeyTemplate[4].ulValueLen = sizeof(true);
01146     sAESKeyTemplate[5].type       = CKA_SIGN; 
01147     sAESKeyTemplate[5].pValue     = &true; 
01148     sAESKeyTemplate[5].ulValueLen = sizeof (true);
01149     sAESKeyTemplate[6].type       = CKA_VERIFY; 
01150     sAESKeyTemplate[6].pValue     = &true; 
01151     sAESKeyTemplate[6].ulValueLen = sizeof(true);
01152     sAESKeyTemplate[7].type       = CKA_UNWRAP; 
01153     sAESKeyTemplate[7].pValue     = &true; 
01154     sAESKeyTemplate[7].ulValueLen = sizeof(true);
01155     sAESKeyTemplate[8].type       = CKA_VALUE_LEN; 
01156     sAESKeyTemplate[8].pValue     = &AESvalueLen; 
01157     sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
01158 
01159     /* DES3 key template */
01160     sDES3KeyTemplate[0].type       = CKA_CLASS;
01161     sDES3KeyTemplate[0].pValue     = &class; 
01162     sDES3KeyTemplate[0].ulValueLen = sizeof(class);
01163     sDES3KeyTemplate[1].type       = CKA_KEY_TYPE; 
01164     sDES3KeyTemplate[1].pValue     = &keyDES3Type; 
01165     sDES3KeyTemplate[1].ulValueLen = sizeof(keyDES3Type);
01166     sDES3KeyTemplate[2].type       = CKA_LABEL; 
01167     sDES3KeyTemplate[2].pValue     = DES3label; 
01168     sDES3KeyTemplate[2].ulValueLen = sizeof(DES3label)-1;
01169     sDES3KeyTemplate[3].type       = CKA_ENCRYPT; 
01170     sDES3KeyTemplate[3].pValue     = &true; 
01171     sDES3KeyTemplate[3].ulValueLen = sizeof(true);
01172     sDES3KeyTemplate[4].type       = CKA_DECRYPT; 
01173     sDES3KeyTemplate[4].pValue     = &true; 
01174     sDES3KeyTemplate[4].ulValueLen = sizeof(true);
01175     sDES3KeyTemplate[5].type       = CKA_UNWRAP; 
01176     sDES3KeyTemplate[5].pValue     = &true; 
01177     sDES3KeyTemplate[5].ulValueLen = sizeof(true);
01178     sDES3KeyTemplate[6].type       = CKA_SIGN, 
01179     sDES3KeyTemplate[6].pValue     = &true; 
01180     sDES3KeyTemplate[6].ulValueLen = sizeof (true);
01181     sDES3KeyTemplate[7].type       = CKA_VERIFY; 
01182     sDES3KeyTemplate[7].pValue     = &true; 
01183     sDES3KeyTemplate[7].ulValueLen = sizeof(true);
01184     sDES3KeyTemplate[8].type       = CKA_VALUE_LEN; 
01185     sDES3KeyTemplate[8].pValue     = &DES3valueLen; 
01186     sDES3KeyTemplate[8].ulValueLen = sizeof(DES3valueLen);
01187     
01188     /* mech init */
01189     memset(IV, 0x01, sizeof(IV));
01190     mech_DES3_CBC.mechanism      = CKM_DES3_CBC; 
01191     mech_DES3_CBC.pParameter = IV; 
01192     mech_DES3_CBC.ulParameterLen = sizeof(IV);
01193     mech_DES3_CBC_PAD.mechanism      = CKM_DES3_CBC_PAD; 
01194     mech_DES3_CBC_PAD.pParameter = IV; 
01195     mech_DES3_CBC_PAD.ulParameterLen = sizeof(IV);
01196     mech_AES_CBC.mechanism      = CKM_AES_CBC; 
01197     mech_AES_CBC.pParameter = IV; 
01198     mech_AES_CBC.ulParameterLen = sizeof(IV);
01199     mech_AES_CBC_PAD.mechanism      = CKM_AES_CBC_PAD; 
01200     mech_AES_CBC_PAD.pParameter = IV; 
01201     mech_AES_CBC_PAD.ulParameterLen = sizeof(IV);
01202 
01203 
01204     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
01205                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
01206                                        NULL, NULL, &hRwSession);
01207     if (crv == CKR_OK) {
01208         PKM_LogIt("Opening a read/write session succeeded\n");
01209     } else {
01210         PKM_Error( "Opening a read/write session failed "
01211                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01212         return crv;
01213     }
01214 
01215     if (MODE == FIPSMODE) {
01216         crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
01217                                            sAESKeyTemplate,
01218                                            NUM_ELEM(sAESKeyTemplate),
01219                                            &hAESSecKey);
01220         if (crv == CKR_OK) {
01221             PKM_Error("C_GenerateKey succeeded when not logged in.\n");
01222             return CKR_GENERAL_ERROR;
01223         } else {
01224             PKM_LogIt("C_GenerateKey returned as EXPECTED with 0x%08X, %-26s\n"
01225                       "since not logged in\n", crv, PKM_CK_RVtoStr(crv));
01226         }
01227         crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
01228                                                rsaPubKeyTemplate,
01229                                                NUM_ELEM(rsaPubKeyTemplate),
01230                                                rsaPrivKeyTemplate,
01231                                                NUM_ELEM(rsaPrivKeyTemplate),
01232                                                &hRSApubKey, &hRSAprivKey);
01233         if (crv == CKR_OK) {
01234             PKM_Error("C_GenerateKeyPair succeeded when not logged in.\n");
01235             return CKR_GENERAL_ERROR;
01236         } else {
01237             PKM_LogIt("C_GenerateKeyPair returned as EXPECTED with 0x%08X, "
01238                       "%-26s\n since not logged in\n", crv, 
01239                       PKM_CK_RVtoStr(crv));
01240         }
01241     }
01242 
01243     crv = pFunctionList->C_Login(hRwSession, CKU_USER, pwd, pwdLen);
01244     if (crv == CKR_OK) {
01245         PKM_LogIt("C_Login with correct password succeeded\n");
01246     } else {
01247         PKM_Error("C_Login with correct password failed "
01248                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01249         return crv;
01250     }
01251 
01252     PKM_LogIt("Generate an AES key ... \n");
01253     /* generate an AES Secret Key */
01254     crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
01255                                        sAESKeyTemplate,
01256                                        NUM_ELEM(sAESKeyTemplate),
01257                                        &hAESSecKey);
01258     if (crv == CKR_OK) {
01259         PKM_LogIt("C_GenerateKey AES succeeded\n");
01260     } else {
01261         PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n", 
01262                    crv, PKM_CK_RVtoStr(crv));
01263         return crv;
01264     }
01265     
01266     PKM_LogIt("Generate an 3DES key ...\n");
01267     /* generate an 3DES Secret Key */   
01268     crv = pFunctionList->C_GenerateKey(hRwSession, &sDES3KeyGenMechanism,
01269                                        sDES3KeyTemplate,
01270                                        NUM_ELEM(sDES3KeyTemplate),
01271                                        &hDES3SecKey);
01272     if (crv == CKR_OK) {
01273         PKM_LogIt("C_GenerateKey DES3 succeeded\n");
01274     } else {
01275         PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv, 
01276                    PKM_CK_RVtoStr(crv));
01277         return crv;
01278     }
01279 
01280     PKM_LogIt("Generate DSA PQG domain parameters ... \n");
01281     /* Generate DSA domain parameters PQG */
01282     crv = pFunctionList->C_GenerateKey(hRwSession, &dsaParamGenMech,
01283                                        dsaParamGenTemplate,
01284                                        1,
01285                                        &hDsaParams);
01286     if (crv == CKR_OK) {
01287         PKM_LogIt("DSA domain parameter generation succeeded\n");
01288     } else {
01289         PKM_Error( "DSA domain parameter generation failed "
01290                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01291         return crv;
01292     }
01293     crv = pFunctionList->C_GetAttributeValue(hRwSession, hDsaParams,
01294                                              dsaPubKeyTemplate, 3);
01295     if (crv == CKR_OK) {
01296         PKM_LogIt("Getting DSA domain parameters succeeded\n");
01297     } else {
01298         PKM_Error( "Getting DSA domain parameters failed "
01299                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01300         return crv;
01301     }
01302     crv = pFunctionList->C_DestroyObject(hRwSession, hDsaParams);
01303     if (crv == CKR_OK) {
01304         PKM_LogIt("Destroying DSA domain parameters succeeded\n");
01305     } else {
01306         PKM_Error( "Destroying DSA domain parameters failed "
01307                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01308         return crv;
01309     }
01310     
01311     PKM_LogIt("Generate a DSA key pair ... \n");
01312     /* Generate a persistent DSA key pair */
01313     crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech,
01314                                            dsaPubKeyTemplate,
01315                                            NUM_ELEM(dsaPubKeyTemplate),
01316                                            dsaPrivKeyTemplate,
01317                                            NUM_ELEM(dsaPrivKeyTemplate),
01318                                            &hDSApubKey, &hDSAprivKey);
01319     if (crv == CKR_OK) {
01320         PKM_LogIt("DSA key pair generation succeeded\n");
01321     } else {
01322         PKM_Error( "DSA key pair generation failed "
01323                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01324         return crv;
01325     }
01326     
01327     PKM_LogIt("Generate a RSA key pair ... \n");
01328     /*** GEN RSA Key ***/
01329     crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
01330                                            rsaPubKeyTemplate,
01331                                            NUM_ELEM(rsaPubKeyTemplate),
01332                                            rsaPrivKeyTemplate,
01333                                            NUM_ELEM(rsaPrivKeyTemplate),
01334                                            &hRSApubKey, &hRSAprivKey);
01335     if (crv == CKR_OK) {
01336         PKM_LogIt("C_GenerateKeyPair created an RSA key pair. \n");
01337     } else {
01338         PKM_Error("C_GenerateKeyPair failed to create an RSA key pair.\n"
01339                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01340         return crv;
01341     }
01342 
01343     PKM_LogIt("**** Generation of keys completed ***** \n");
01344     
01345     mech.mechanism = CKM_RSA_PKCS;
01346     mech.pParameter = NULL;
01347     mech.ulParameterLen = 0;
01348 
01349     crv = PKM_wrapUnwrap(pFunctionList,
01350                      hRwSession, 
01351                      hRSApubKey, hRSAprivKey,
01352                      &mech,
01353                      hAESSecKey,
01354                      sAESKeyTemplate,
01355                      NUM_ELEM(sAESKeyTemplate));
01356     
01357    if (crv == CKR_OK) {
01358         PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap AES key "
01359                   "succeeded\n\n");
01360     } else {
01361         PKM_Error( "PKM_wrapUnwrap using RSA keypair to wrap AES key failed "
01362                    "with 0x%08X, %-26s\n", crv, 
01363                    PKM_CK_RVtoStr(crv));
01364         return crv;
01365     }
01366 
01367     crv = PKM_wrapUnwrap(pFunctionList,
01368                      hRwSession, 
01369                      hRSApubKey, hRSAprivKey,
01370                      &mech,
01371                      hDES3SecKey,
01372                      sDES3KeyTemplate,
01373                      NUM_ELEM(sDES3KeyTemplate));
01374     
01375    if (crv == CKR_OK) {
01376         PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
01377                   "succeeded\n\n");
01378     } else {
01379         PKM_Error( "PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
01380                    "failed with 0x%08X, %-26s\n", crv, 
01381                    PKM_CK_RVtoStr(crv));
01382         return crv;
01383     }
01384 
01385     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
01386                     hAESSecKey, &mech_AES_CBC_PAD,
01387                     PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
01388     if (crv == CKR_OK) {
01389         PKM_LogIt("PKM_SecKeyCrypt succeeded \n\n");
01390     } else {
01391         PKM_Error( "PKM_SecKeyCrypt failed "
01392                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01393         return crv;
01394     }
01395     
01396     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
01397                     hAESSecKey, &mech_AES_CBC,
01398                     PLAINTEXT, sizeof(PLAINTEXT));
01399     if (crv == CKR_OK) {
01400         PKM_LogIt("PKM_SecKeyCrypt AES succeeded \n\n");
01401     } else {
01402         PKM_Error( "PKM_SecKeyCrypt failed "
01403                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01404         return crv;
01405     }
01406 
01407     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
01408                     hDES3SecKey, &mech_DES3_CBC,
01409                     PLAINTEXT, sizeof(PLAINTEXT));
01410     if (crv == CKR_OK) {
01411         PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n");
01412     } else {
01413         PKM_Error( "PKM_SecKeyCrypt DES3 failed "
01414                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01415         return crv;
01416     }
01417 
01418     crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
01419                     hDES3SecKey, &mech_DES3_CBC_PAD,
01420                     PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
01421     if (crv == CKR_OK) {
01422         PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n\n");
01423     } else {
01424         PKM_Error( "PKM_SecKeyCrypt DES3 failed "
01425                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01426         return crv;
01427     }
01428     
01429     mech.mechanism = CKM_RSA_PKCS;
01430     crv = PKM_RecoverFunctions(pFunctionList, hRwSession,
01431                        hRSApubKey, hRSAprivKey,
01432                        &mech,
01433                        PLAINTEXT, sizeof(PLAINTEXT));
01434     if (crv == CKR_OK) {
01435         PKM_LogIt("PKM_RecoverFunctions for CKM_RSA_PKCS succeeded\n\n");
01436     } else {
01437         PKM_Error( "PKM_RecoverFunctions failed with 0x%08X, %-26s\n", crv, 
01438                    PKM_CK_RVtoStr(crv));
01439         return crv;
01440     }
01441 
01442     mech.pParameter = NULL;
01443     mech.ulParameterLen = 0;
01444 
01445     for (i=0; i < sigRSAMechsSZ; i++) {
01446 
01447         mech.mechanism = sigRSAMechs[i].mechanism;
01448 
01449         crv = PKM_PubKeySign(pFunctionList, hRwSession,
01450                        hRSApubKey, hRSAprivKey,
01451                        &mech,
01452                        PLAINTEXT, sizeof(PLAINTEXT));
01453         if (crv == CKR_OK) {
01454             PKM_LogIt("PKM_PubKeySign succeeded for %-10s\n\n", 
01455                 sigRSAMechs[i].mechanismStr );
01456         } else {
01457             PKM_Error( "PKM_PubKeySign failed for %-10s  "
01458                 "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, 
01459                 PKM_CK_RVtoStr(crv));
01460             return crv;
01461         }
01462         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01463                        hRSApubKey, hRSAprivKey,
01464                        &mech,
01465                        hAESSecKey, &mech_AES_CBC,
01466                        PLAINTEXT, sizeof(PLAINTEXT));
01467         if (crv == CKR_OK) {
01468             PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
01469                       "for %-10s\n\n", 
01470                 sigRSAMechs[i].mechanismStr );
01471         } else {
01472             PKM_Error( "PKM_DualFuncSign with AES secret key failed "
01473                        "for %-10s  "
01474                 "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, 
01475                 PKM_CK_RVtoStr(crv));
01476             return crv;
01477         }
01478         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01479                        hRSApubKey, hRSAprivKey,
01480                        &mech,
01481                        hDES3SecKey, &mech_DES3_CBC,
01482                        PLAINTEXT, sizeof(PLAINTEXT));
01483         if (crv == CKR_OK) {
01484             PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
01485                       "for %-10s\n\n", 
01486                 sigRSAMechs[i].mechanismStr );
01487         } else {
01488             PKM_Error( "PKM_DualFuncSign with DES3 secret key failed "
01489                        "for %-10s  "
01490                 "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, 
01491                 PKM_CK_RVtoStr(crv));
01492             return crv;
01493         }
01494         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01495                        hRSApubKey, hRSAprivKey,
01496                        &mech,
01497                        hAESSecKey, &mech_AES_CBC_PAD,
01498                        PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
01499         if (crv == CKR_OK) {
01500             PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD "
01501                       "succeeded for %-10s\n\n", 
01502                 sigRSAMechs[i].mechanismStr );
01503         } else {
01504             PKM_Error( "PKM_DualFuncSign with AES secret key CBC_PAD "
01505                        "failed for %-10s  "
01506                 "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, 
01507                 PKM_CK_RVtoStr(crv));
01508             return crv;
01509         }
01510         crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01511                        hRSApubKey, hRSAprivKey,
01512                        &mech,
01513                        hDES3SecKey, &mech_DES3_CBC_PAD,
01514                        PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
01515         if (crv == CKR_OK) {
01516             PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD "
01517                       "succeeded for %-10s\n\n", 
01518                 sigRSAMechs[i].mechanismStr );
01519         } else {
01520             PKM_Error( "PKM_DualFuncSign with DES3 secret key CBC_PAD "
01521                        "failed for %-10s  "
01522                 "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv, 
01523                 PKM_CK_RVtoStr(crv));
01524             return crv;
01525         }
01526 
01527     } /* end of RSA for loop */
01528 
01529     crv = PKM_PubKeySign(pFunctionList, hRwSession,
01530                     hDSApubKey, hDSAprivKey,
01531                     &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT));
01532     if (crv == CKR_OK) {
01533         PKM_LogIt("PKM_PubKeySign for DSAwithSHA1 succeeded \n\n");
01534     } else {
01535         PKM_Error( "PKM_PubKeySign failed "
01536                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01537         return crv;
01538     }
01539     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01540                        hDSApubKey, hDSAprivKey,
01541                        &dsaWithSha1Mech,
01542                        hAESSecKey, &mech_AES_CBC,
01543                        PLAINTEXT, sizeof(PLAINTEXT));
01544     if (crv == CKR_OK) {
01545         PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
01546                 "for DSAWithSHA1\n\n");
01547     } else {
01548         PKM_Error( "PKM_DualFuncSign with AES secret key failed "
01549                 "for DSAWithSHA1 with 0x%08X, %-26s\n", 
01550                 crv, PKM_CK_RVtoStr(crv));
01551            return crv;
01552     }
01553     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01554                        hDSApubKey, hDSAprivKey,
01555                        &dsaWithSha1Mech,
01556                        hDES3SecKey, &mech_DES3_CBC,
01557                        PLAINTEXT, sizeof(PLAINTEXT));
01558     if (crv == CKR_OK) {
01559         PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
01560                 "for DSAWithSHA1\n\n");
01561     } else {
01562         PKM_Error( "PKM_DualFuncSign with DES3 secret key failed "
01563                 "for DSAWithSHA1 with 0x%08X, %-26s\n", 
01564                 crv, PKM_CK_RVtoStr(crv));
01565            return crv;
01566     }
01567     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01568                        hDSApubKey, hDSAprivKey,
01569                        &dsaWithSha1Mech,
01570                        hAESSecKey, &mech_AES_CBC_PAD,
01571                        PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
01572     if (crv == CKR_OK) {
01573         PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD succeeded "
01574                 "for DSAWithSHA1\n\n");
01575     } else {
01576         PKM_Error( "PKM_DualFuncSign with AES secret key CBC_PAD failed "
01577                 "for DSAWithSHA1 with 0x%08X, %-26s\n", 
01578                 crv, PKM_CK_RVtoStr(crv));
01579            return crv;
01580     }
01581     crv = PKM_DualFuncSign(pFunctionList, hRwSession,
01582                        hDSApubKey, hDSAprivKey,
01583                        &dsaWithSha1Mech,
01584                        hDES3SecKey, &mech_DES3_CBC_PAD,
01585                        PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
01586     if (crv == CKR_OK) {
01587         PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD succeeded "
01588                 "for DSAWithSHA1\n\n");
01589     } else {
01590         PKM_Error( "PKM_DualFuncSign with DES3 secret key CBC_PAD failed "
01591                 "for DSAWithSHA1 with 0x%08X, %-26s\n", 
01592                 crv, PKM_CK_RVtoStr(crv));
01593            return crv;
01594     }
01595 
01596 
01597     for (i=0; i < digestMechsSZ; i++) {
01598         mech.mechanism = digestMechs[i].mechanism;
01599         crv = PKM_Digest(pFunctionList, hRwSession,
01600                      &mech, hAESSecKey,
01601                      PLAINTEXT, sizeof(PLAINTEXT));
01602         if (crv == CKR_OK) {
01603             PKM_LogIt("PKM_Digest with AES secret key succeeded for %-10s\n\n", 
01604                 digestMechs[i].mechanismStr);
01605         } else {
01606             PKM_Error( "PKM_Digest with AES secret key failed for "
01607                        "%-10s with 0x%08X,  %-26s\n", 
01608                        digestMechs[i].mechanismStr, crv, 
01609                        PKM_CK_RVtoStr(crv));
01610             return crv;
01611         }
01612         crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
01613                      hAESSecKey, &mech_AES_CBC,
01614                      0,&mech,
01615                      PLAINTEXT, sizeof(PLAINTEXT));
01616         if (crv == CKR_OK) {
01617             PKM_LogIt("PKM_DualFuncDigest with AES secret key succeeded\n\n");
01618         } else {
01619             PKM_Error( "PKM_DualFuncDigest with AES secret key "
01620                        "failed with 0x%08X, %-26s\n", crv, 
01621                        PKM_CK_RVtoStr(crv));
01622         }
01623 
01624         crv = PKM_Digest(pFunctionList, hRwSession,
01625                      &mech, hDES3SecKey,
01626                      PLAINTEXT, sizeof(PLAINTEXT));
01627         if (crv == CKR_OK) {
01628             PKM_LogIt("PKM_Digest with DES3 secret key succeeded for %-10s\n\n", 
01629                 digestMechs[i].mechanismStr);
01630         } else {
01631             PKM_Error( "PKM_Digest with DES3 secret key failed for "
01632                        "%-10s with 0x%08X,  %-26s\n", 
01633                        digestMechs[i].mechanismStr, crv, 
01634                        PKM_CK_RVtoStr(crv));
01635             return crv;
01636         }
01637         crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
01638                      hDES3SecKey, &mech_DES3_CBC,
01639                      0,&mech,
01640                      PLAINTEXT, sizeof(PLAINTEXT));
01641         if (crv == CKR_OK) {
01642             PKM_LogIt("PKM_DualFuncDigest DES3 secret key succeeded\n\n");
01643         } else {
01644             PKM_Error( "PKM_DualFuncDigest DES3 secret key "
01645                        "failed with 0x%08X, %-26s\n", crv, 
01646                        PKM_CK_RVtoStr(crv));
01647         }
01648 
01649         crv = PKM_Digest(pFunctionList, hRwSession,
01650                      &mech, 0,
01651                      PLAINTEXT, sizeof(PLAINTEXT));
01652         if (crv == CKR_OK) {
01653             PKM_LogIt("PKM_Digest with no secret key succeeded for %-10s\n\n", 
01654                 digestMechs[i].mechanismStr );
01655         } else {
01656             PKM_Error( "PKM_Digest with no secret key failed for %-10s  "
01657                 "with 0x%08X, %-26s\n", digestMechs[i].mechanismStr, crv, 
01658                 PKM_CK_RVtoStr(crv));
01659             return crv;
01660         }
01661     } /* end of digest loop */
01662 
01663     for (i=0; i < hmacMechsSZ; i++) {
01664         mech.mechanism = hmacMechs[i].mechanism;
01665         crv = PKM_Hmac(pFunctionList, hRwSession,
01666                       hAESSecKey, &mech,
01667                      PLAINTEXT, sizeof(PLAINTEXT));
01668         if (crv == CKR_OK) {
01669             PKM_LogIt("PKM_Hmac with AES secret key succeeded for %-10s\n\n", 
01670                 hmacMechs[i].mechanismStr);
01671         } else {
01672             PKM_Error( "PKM_Hmac with AES secret key failed for %-10s "
01673                        "with 0x%08X, %-26s\n", 
01674                        hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
01675             return crv;
01676         }
01677         if ((MODE == FIPSMODE) && (mech.mechanism == CKM_SHA512_HMAC)) break;
01678         crv = PKM_Hmac(pFunctionList, hRwSession,
01679                       hDES3SecKey, &mech,
01680                      PLAINTEXT, sizeof(PLAINTEXT));
01681         if (crv == CKR_OK) {
01682             PKM_LogIt("PKM_Hmac with DES3 secret key succeeded for %-10s\n\n", 
01683                 hmacMechs[i].mechanismStr);
01684         } else {
01685             PKM_Error( "PKM_Hmac with DES3 secret key failed for %-10s "
01686                        "with 0x%08X,  %-26s\n", 
01687                        hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
01688             return crv;
01689         }
01690 
01691     } /* end of hmac loop */
01692 
01693     crv = pFunctionList->C_Logout(hRwSession);
01694     if (crv == CKR_OK) {
01695         PKM_LogIt("C_Logout succeeded\n");
01696     } else {
01697         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
01698                    PKM_CK_RVtoStr(crv));
01699         return crv;
01700     }
01701 
01702     crv = pFunctionList->C_CloseSession(hRwSession);
01703     if (crv != CKR_OK) {
01704         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
01705                    PKM_CK_RVtoStr(crv));
01706         return crv;
01707     }
01708 
01709     return crv;
01710 
01711 }
01712 
01713 void PKM_LogIt(const char *fmt, ...) {
01714     va_list args;
01715     
01716     if (verbose) {
01717         va_start (args, fmt);
01718         if (MODE == FIPSMODE) {
01719             printf("FIPS MODE: ");
01720         } else if (MODE == NONFIPSMODE) {
01721             printf("NON FIPS MODE: ");
01722         } else if (MODE == HYBRIDMODE) {
01723             printf("Hybrid MODE: ");
01724         } else printf ("NO MODE: ");
01725         vprintf(fmt, args);
01726         va_end(args);
01727     }
01728 }
01729 
01730 void PKM_Error(const char *fmt, ...) {
01731     va_list args;
01732     va_start (args, fmt);
01733 
01734     if (MODE == FIPSMODE) {
01735         fprintf(stderr, "\nFIPS MODE PKM_Error: ");
01736     } else if (MODE == NONFIPSMODE) {
01737         fprintf(stderr, "NON FIPS MODE PKM_Error: ");
01738     } else if (MODE == HYBRIDMODE) {
01739         fprintf(stderr, "Hybrid MODE PKM_Error: ");
01740     } else fprintf(stderr, "NOMODE PKM_Error: ");
01741     vfprintf(stderr, fmt, args);
01742     va_end(args);
01743 }
01744 CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
01745                             CK_ULONG slotID) {
01746     CK_RV crv = CKR_OK;
01747     CK_SLOT_ID *pSlotList = NULL;
01748     CK_ULONG slotCount;
01749     
01750     NUMTESTS++; /* increment NUMTESTS */
01751 
01752     /* Get slot list */
01753     crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
01754                                        NULL, &slotCount);
01755     if (crv != CKR_OK) {
01756         PKM_Error( "C_GetSlotList failed with 0x%08X, %-26s\n", crv, 
01757                    PKM_CK_RVtoStr(crv));
01758         return NULL;
01759     }
01760     PKM_LogIt("C_GetSlotList reported there are %lu slots\n", slotCount);
01761     pSlotList = (CK_SLOT_ID *)malloc(slotCount * sizeof(CK_SLOT_ID));
01762     if (!pSlotList) {
01763         PKM_Error( "failed to allocate slot list\n");
01764         return NULL;
01765     }
01766     crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
01767                                        pSlotList, &slotCount);
01768     if (crv != CKR_OK) {
01769         PKM_Error( "C_GetSlotList failed with 0x%08X, %-26s\n", crv, 
01770                    PKM_CK_RVtoStr(crv));
01771         if (pSlotList) free(pSlotList);
01772         return NULL;
01773     }
01774     return pSlotList;
01775 }
01776 
01777 CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
01778                       CK_SLOT_ID * pSlotList, CK_ULONG slotID,
01779                       CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen)  {
01780     CK_RV crv = CKR_OK;
01781     CK_SESSION_HANDLE hSession;
01782     static const CK_UTF8CHAR testPin[] = {"0Mozilla"};
01783     static const CK_UTF8CHAR weakPin[] = {"mozilla"};
01784 
01785     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
01786                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
01787                                        NULL, NULL, &hSession);
01788     if (crv != CKR_OK) {
01789         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
01790                    PKM_CK_RVtoStr(crv));
01791         return crv;
01792     }
01793     PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER); 
01794 
01795     crv = pFunctionList->C_Login(hSession, CKU_SO, NULL, 0);
01796     if (crv != CKR_OK) {
01797         PKM_Error( "C_Login failed with 0x%08X, %-26s\n", crv, 
01798                    PKM_CK_RVtoStr(crv));
01799         return crv;
01800     }
01801     if (MODE == FIPSMODE) {
01802         crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *) weakPin, 
01803                                        sizeof(weakPin));
01804         if (crv == CKR_OK) {
01805             PKM_Error( "C_InitPIN with a weak password succeeded\n");
01806             return crv;
01807         } else {
01808             PKM_LogIt("C_InitPIN with a weak password failed with "
01809                       "0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01810         }
01811     }
01812     crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *) testPin, 
01813                                    sizeof(testPin));
01814     if (crv == CKR_OK) {
01815         PKM_LogIt("C_InitPIN succeeded\n");
01816     } else {
01817         PKM_Error( "C_InitPIN failed with 0x%08X, %-26s\n", crv, 
01818                    PKM_CK_RVtoStr(crv));
01819         return crv;
01820     }
01821     crv = pFunctionList->C_Logout(hSession);
01822     if (crv != CKR_OK) {
01823         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
01824                    PKM_CK_RVtoStr(crv));
01825         return crv;
01826     }
01827     crv = pFunctionList->C_CloseSession(hSession);
01828     if (crv != CKR_OK) {
01829         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
01830                    PKM_CK_RVtoStr(crv));
01831         return crv;
01832     }
01833 
01834 
01835     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
01836                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
01837                                        NULL, NULL, &hSession);
01838     if (crv != CKR_OK) {
01839         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
01840                    PKM_CK_RVtoStr(crv));
01841         return crv;
01842     }
01843 
01844     PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER); 
01845 
01846     crv = pFunctionList->C_Login(hSession, CKU_USER, (CK_UTF8CHAR *) testPin,
01847                                  strlen((const char *)testPin));
01848     if (crv != CKR_OK) {
01849         PKM_Error( "C_Login failed with 0x%08X, %-26s\n", crv, 
01850                    PKM_CK_RVtoStr(crv));
01851         return crv;
01852     }
01853     if (MODE == FIPSMODE) {
01854         crv = pFunctionList->C_SetPIN(
01855                                      hSession, (CK_UTF8CHAR *) testPin, 
01856                                      strlen((const char *)testPin),
01857                                      (CK_UTF8CHAR *) weakPin, 
01858                                      strlen((const char *)weakPin));
01859         if (crv == CKR_OK) {
01860             PKM_Error( "C_SetPIN with a weak password succeeded\n");
01861             return crv;
01862         } else {
01863             PKM_LogIt("C_SetPIN with a weak password returned with "
01864                       "0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
01865         }
01866     }
01867     crv = pFunctionList->C_SetPIN(
01868                                  hSession, (CK_UTF8CHAR *) testPin, 
01869                                  strlen((const char *)testPin),
01870                                  pwd, pwdLen);
01871     if (crv != CKR_OK) {
01872         PKM_Error( "C_CSetPin failed with 0x%08X, %-26s\n", crv, 
01873                    PKM_CK_RVtoStr(crv));
01874         return crv;
01875     }
01876     crv = pFunctionList->C_Logout(hSession);
01877     if (crv != CKR_OK) {
01878         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
01879                    PKM_CK_RVtoStr(crv));
01880         return crv;
01881     }
01882     crv = pFunctionList->C_CloseSession(hSession);
01883     if (crv != CKR_OK) {
01884         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
01885                    PKM_CK_RVtoStr(crv));
01886         return crv;
01887     }
01888     return crv;
01889 }
01890 
01891 CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID) {
01892     CK_RV crv = CKR_OK;
01893     CK_INFO info;
01894     CK_SLOT_ID *pSlotList = NULL;
01895     unsigned i;
01896 
01897     CK_SLOT_INFO slotInfo;
01898     CK_TOKEN_INFO tokenInfo;
01899     CK_FLAGS bitflag;
01900     
01901     NUMTESTS++; /* increment NUMTESTS */
01902 
01903 
01904     crv = pFunctionList->C_GetInfo(&info);
01905     if (crv == CKR_OK) {
01906         PKM_LogIt("C_GetInfo succeeded\n");
01907     } else {
01908         PKM_Error( "C_GetInfo failed with 0x%08X, %-26s\n", crv, 
01909                    PKM_CK_RVtoStr(crv));
01910         return crv;
01911     }
01912     PKM_LogIt("General information about the PKCS #11 library:\n");
01913     PKM_LogIt("    PKCS #11 version: %d.%d\n",
01914               (int)info.cryptokiVersion.major,
01915               (int)info.cryptokiVersion.minor);
01916     PKM_LogIt("    manufacturer ID: %.32s\n", info.manufacturerID);
01917     PKM_LogIt("    flags: 0x%08lX\n", info.flags);
01918     PKM_LogIt("    library description: %.32s\n", info.libraryDescription);
01919     PKM_LogIt("    library version: %d.%d\n",
01920               (int)info.libraryVersion.major, (int)info.libraryVersion.minor);
01921     PKM_LogIt("\n");
01922 
01923     /* Get slot list */
01924     pSlotList = PKM_GetSlotList(pFunctionList, slotID);
01925     if (pSlotList == NULL) {
01926         PKM_Error( "PKM_GetSlotList failed with \n");
01927         return crv;
01928     }
01929     crv = pFunctionList->C_GetSlotInfo(pSlotList[slotID], &slotInfo);
01930     if (crv == CKR_OK) {
01931         PKM_LogIt("C_GetSlotInfo succeeded\n");
01932     } else {
01933         PKM_Error( "C_GetSlotInfo failed with 0x%08X, %-26s\n", crv, 
01934                    PKM_CK_RVtoStr(crv));
01935         return crv;
01936     }
01937     PKM_LogIt("Information about slot %lu:\n", pSlotList[slotID]);
01938     PKM_LogIt("    slot description: %.64s\n", slotInfo.slotDescription);
01939     PKM_LogIt("    slot manufacturer ID: %.32s\n", slotInfo.manufacturerID);
01940     PKM_LogIt("    flags: 0x%08lX\n", slotInfo.flags);
01941     bitflag = 1;
01942     for (i = 0; i < sizeof(slotFlagName)/sizeof(slotFlagName[0]); i++) {
01943         if (slotInfo.flags & bitflag) {
01944             PKM_LogIt("           %s\n", slotFlagName[i]);
01945         }
01946         bitflag <<= 1;
01947     }
01948     PKM_LogIt("    slot's hardware version number: %d.%d\n",
01949               (int)slotInfo.hardwareVersion.major,
01950               (int)slotInfo.hardwareVersion.minor);
01951     PKM_LogIt("    slot's firmware version number: %d.%d\n",
01952               (int)slotInfo.firmwareVersion.major,
01953               (int)slotInfo.firmwareVersion.minor);
01954     PKM_LogIt("\n");
01955 
01956     crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
01957     if (crv == CKR_OK) {
01958         PKM_LogIt("C_GetTokenInfo succeeded\n");
01959     } else {
01960         PKM_Error( "C_GetTokenInfo failed with 0x%08X, %-26s\n", crv, 
01961                    PKM_CK_RVtoStr(crv));
01962         return crv;
01963     }
01964     PKM_LogIt("Information about the token in slot %lu:\n",
01965               pSlotList[slotID]);
01966     PKM_LogIt("    label: %.32s\n", tokenInfo.label);
01967     PKM_LogIt("    device manufacturer ID: %.32s\n",
01968               tokenInfo.manufacturerID);
01969     PKM_LogIt("    device model: %.16s\n", tokenInfo.model);
01970     PKM_LogIt("    device serial number: %.16s\n", tokenInfo.serialNumber);
01971     PKM_LogIt("    flags: 0x%08lX\n", tokenInfo.flags);
01972     bitflag = 1;
01973     for (i = 0; i < sizeof(tokenFlagName)/sizeof(tokenFlagName[0]); i++) {
01974         if (tokenInfo.flags & bitflag) {
01975             PKM_LogIt("           %s\n", tokenFlagName[i]);
01976         }
01977         bitflag <<= 1;
01978     }
01979     PKM_LogIt("    maximum session count: %lu\n",
01980               tokenInfo.ulMaxSessionCount);
01981     PKM_LogIt("    session count: %lu\n", tokenInfo.ulSessionCount);
01982     PKM_LogIt("    maximum read/write session count: %lu\n",
01983               tokenInfo.ulMaxRwSessionCount);
01984     PKM_LogIt("    read/write session count: %lu\n",
01985               tokenInfo.ulRwSessionCount);
01986     PKM_LogIt("    maximum PIN length: %lu\n", tokenInfo.ulMaxPinLen);
01987     PKM_LogIt("    minimum PIN length: %lu\n", tokenInfo.ulMinPinLen);
01988     PKM_LogIt("    total public memory: %lu\n",
01989               tokenInfo.ulTotalPublicMemory);
01990     PKM_LogIt("    free public memory: %lu\n",
01991               tokenInfo.ulFreePublicMemory);
01992     PKM_LogIt("    total private memory: %lu\n",
01993               tokenInfo.ulTotalPrivateMemory);
01994     PKM_LogIt("    free private memory: %lu\n",
01995               tokenInfo.ulFreePrivateMemory);
01996     PKM_LogIt("    hardware version number: %d.%d\n",
01997               (int)tokenInfo.hardwareVersion.major,
01998               (int)tokenInfo.hardwareVersion.minor);
01999     PKM_LogIt("    firmware version number: %d.%d\n",
02000               (int)tokenInfo.firmwareVersion.major,
02001               (int)tokenInfo.firmwareVersion.minor);
02002     if (tokenInfo.flags & CKF_CLOCK_ON_TOKEN) {
02003         PKM_LogIt("    current time: %.16s\n", tokenInfo.utcTime);
02004     }
02005     PKM_LogIt("PKM_ShowInfo done \n\n");
02006     if (pSlotList) free(pSlotList);
02007     return crv;
02008 }
02009 
02010 /* PKM_HybridMode                                                         */
02011 /* The NSS cryptographic module has two modes of operation: FIPS Approved */
02012 /* mode and NONFIPS Approved mode. The two modes of operation are         */
02013 /* independent of each other -- they have their own copies of data        */
02014 /* structures and they are even allowed to be active at the same time.    */
02015 /* The module is FIPS 140-2 compliant only when the NONFIPS mode          */
02016 /* is inactive.                                                           */
02017 /* PKM_HybridMode demostrates how an application can switch between the   */
02018 /* two modes: FIPS Approved mode and NONFIPS mode.                        */
02019 CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen, 
02020                      CK_C_INITIALIZE_ARGS_NSS *initArgs) {
02021 
02022     CK_C_GetFunctionList pC_GetFunctionList;  /* NONFIPSMode */
02023     CK_FUNCTION_LIST_PTR pC_FunctionList;
02024     CK_SLOT_ID *pC_SlotList = NULL;
02025     CK_ULONG slotID_C = 1;
02026     CK_C_GetFunctionList pFC_GetFunctionList; /* FIPSMode */
02027     CK_FUNCTION_LIST_PTR pFC_FunctionList;
02028     CK_SLOT_ID *pFC_SlotList = NULL;
02029     CK_ULONG slotID_FC = 0;
02030     CK_RV crv = CKR_OK;
02031     CK_SESSION_HANDLE hSession;
02032     int origMode = MODE; /* remember the orginal MODE value */ 
02033 
02034     NUMTESTS++; /* increment NUMTESTS */
02035     MODE = NONFIPSMODE;
02036 #ifdef _WIN32
02037     /* NON FIPS mode  == C_GetFunctionList */
02038     pC_GetFunctionList = (CK_C_GetFunctionList)
02039                          GetProcAddress(hModule, "C_GetFunctionList");
02040     if (pC_GetFunctionList == NULL) {
02041         PKM_Error( "cannot load %s\n", LIB_NAME);
02042         return crv;
02043     }
02044 #else
02045         pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
02046         "C_GetFunctionList");
02047         assert(pC_GetFunctionList != NULL);
02048 #endif
02049     PKM_LogIt("loading C_GetFunctionList for Non FIPS Mode; slotID %d \n",
02050               slotID_C);
02051     crv = (*pC_GetFunctionList)(&pC_FunctionList);
02052     assert(crv == CKR_OK);
02053 
02054     /* invoke C_Initialize as pC_FunctionList->C_Initialize */
02055     crv = pC_FunctionList->C_Initialize(initArgs);
02056     if (crv == CKR_OK) {
02057         PKM_LogIt("C_Initialize succeeded\n");
02058     } else {
02059         PKM_Error( "C_Initialize failed with 0x%08X, %-26s\n", crv, 
02060                    PKM_CK_RVtoStr(crv));
02061         return crv;
02062     }
02063 
02064     pC_SlotList = PKM_GetSlotList(pC_FunctionList, slotID_C);
02065     if (pC_SlotList == NULL) {
02066         PKM_Error( "PKM_GetSlotList failed with \n");
02067         return crv;
02068     }
02069     crv = pC_FunctionList->C_OpenSession(pC_SlotList[slotID_C],
02070                                          CKF_SERIAL_SESSION,
02071                                          NULL, NULL, &hSession);
02072     if (crv == CKR_OK) {
02073         PKM_LogIt("NONFIPS C_OpenSession succeeded\n");
02074     } else {
02075         PKM_Error( "C_OpenSession failed for NONFIPS token "
02076                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02077         return crv;
02078     }
02079 
02080     crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
02081     if (crv == CKR_OK) {
02082         PKM_LogIt("able to login in NONFIPS token\n");
02083     } else {
02084         PKM_Error( "Unable to login in to NONFIPS token "
02085                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02086         return crv;
02087     }
02088 
02089     crv = pC_FunctionList->C_Logout(hSession);
02090     if (crv == CKR_OK) {
02091         PKM_LogIt("C_Logout succeeded\n");
02092     } else {
02093         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
02094                    PKM_CK_RVtoStr(crv));
02095         return crv;
02096     }
02097 
02098     PKM_ShowInfo(pC_FunctionList, slotID_C);
02099     MODE = HYBRIDMODE;
02100 
02101     /* Now load the FIPS token */
02102     /* FIPS mode == FC_GetFunctionList */
02103     pFC_GetFunctionList = NULL; 
02104 #ifdef _WIN32
02105     pFC_GetFunctionList = (CK_C_GetFunctionList)
02106                           GetProcAddress(hModule, "FC_GetFunctionList");
02107 #else
02108      pFC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
02109         "FC_GetFunctionList");
02110         assert(pFC_GetFunctionList != NULL);
02111 #endif
02112 
02113     PKM_LogIt("loading FC_GetFunctionList for FIPS Mode; slotID %d \n",
02114               slotID_FC);
02115     PKM_LogIt("pFC_FunctionList->C_Foo == pFC_FunctionList->FC_Foo\n");
02116     if (pFC_GetFunctionList == NULL) {
02117         PKM_Error( "unable to load pFC_GetFunctionList\n");
02118         return crv;
02119     }
02120 
02121     crv = (*pFC_GetFunctionList)(&pFC_FunctionList);
02122     assert(crv == CKR_OK);
02123 
02124     /* invoke FC_Initialize as pFunctionList->C_Initialize */
02125     crv = pFC_FunctionList->C_Initialize(initArgs);
02126     if (crv == CKR_OK) {
02127         PKM_LogIt("FC_Initialize succeeded\n");
02128     } else {
02129         PKM_Error( "FC_Initialize failed with 0x%08X, %-26s\n", crv, 
02130                    PKM_CK_RVtoStr(crv));
02131         return crv;
02132     }
02133     PKM_ShowInfo(pFC_FunctionList, slotID_FC);
02134 
02135     pFC_SlotList = PKM_GetSlotList(pFC_FunctionList, slotID_FC);
02136     if (pFC_SlotList == NULL) {
02137         PKM_Error( "PKM_GetSlotList failed with \n");
02138         return crv;
02139     }
02140 
02141     crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
02142     if (crv != CKR_OK) {
02143         PKM_LogIt("NONFIPS token cannot log in when FIPS token is loaded\n");
02144     } else {
02145         PKM_Error("Able to login in to NONFIPS token\n");
02146         return crv;
02147     }
02148     crv = pC_FunctionList->C_CloseSession(hSession);
02149     if (crv == CKR_OK) {
02150         PKM_LogIt("NONFIPS pC_CloseSession succeeded\n");
02151     } else {
02152         PKM_Error( "pC_CloseSession failed for NONFIPS token "
02153                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02154         return crv;
02155     }
02156 
02157     PKM_LogIt("The module is FIPS 140-2 compliant\n"
02158               "only when the NONFIPS Approved mode is inactive by \n"
02159               "calling C_Finalize on the NONFIPS token.\n");
02160 
02161 
02162     /* to go in FIPSMODE you must Finalize the NONFIPS mode pointer */
02163     crv = pC_FunctionList->C_Finalize(NULL);
02164     if (crv == CKR_OK) {
02165         PKM_LogIt("C_Finalize of NONFIPS Token succeeded\n");
02166         MODE = FIPSMODE;
02167     } else {
02168         PKM_Error( "C_Finalize of NONFIPS Token failed with "
02169                    "0x%08X, %-26s\n", crv, 
02170                    PKM_CK_RVtoStr(crv));
02171         return crv;
02172     }
02173 
02174     PKM_LogIt("*** In FIPS mode!  ***\n");
02175 
02176     /* could do some operations in FIPS MODE */
02177 
02178     crv = pFC_FunctionList->C_Finalize(NULL);
02179     if (crv == CKR_OK) {
02180         PKM_LogIt("Exiting FIPSMODE by caling FC_Finalize.\n");
02181         MODE = NOMODE;
02182     } else {
02183         PKM_Error( "FC_Finalize failed with 0x%08X, %-26s\n", crv, 
02184                    PKM_CK_RVtoStr(crv));
02185         return crv;
02186     }
02187 
02188     if (pC_SlotList) free(pC_SlotList);
02189     if (pFC_SlotList) free(pFC_SlotList);
02190 
02191     MODE = origMode; /* set the mode back to the orginal Mode value */
02192     PKM_LogIt("PKM_HybridMode test Completed\n\n");
02193     return crv;
02194 }
02195 
02196 CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
02197                     CK_SLOT_ID * pSlotList, CK_ULONG slotID) {
02198 
02199     CK_RV crv = CKR_OK;
02200     CK_MECHANISM_TYPE *pMechanismList;
02201     CK_ULONG mechanismCount;
02202     CK_ULONG i;
02203     
02204     NUMTESTS++; /* increment NUMTESTS */
02205 
02206     /* Get the mechanism list */
02207     crv = pFunctionList->C_GetMechanismList(pSlotList[slotID],
02208                                             NULL, &mechanismCount);
02209     if (crv != CKR_OK) {
02210         PKM_Error( "C_GetMechanismList failed with 0x%08X, %-26s\n", crv, 
02211                    PKM_CK_RVtoStr(crv));
02212         return crv;
02213     }
02214     PKM_LogIt("C_GetMechanismList reported there are %lu mechanisms\n",
02215               mechanismCount);
02216     pMechanismList = (CK_MECHANISM_TYPE *)
02217                      malloc(mechanismCount * sizeof(CK_MECHANISM_TYPE));
02218     if (!pMechanismList) {
02219         PKM_Error( "failed to allocate mechanism list\n");
02220         return crv;
02221     }
02222     crv = pFunctionList->C_GetMechanismList(pSlotList[slotID],
02223                                             pMechanismList, &mechanismCount);
02224     if (crv != CKR_OK) {
02225         PKM_Error( "C_GetMechanismList failed with 0x%08X, %-26s\n", crv, 
02226                    PKM_CK_RVtoStr(crv));
02227         return crv;
02228     }
02229     PKM_LogIt("C_GetMechanismList returned the mechanism types:\n");
02230     if (verbose) {
02231         for (i = 0; i < mechanismCount; i++) {
02232             printf("    0x%08lX", pMechanismList[i]);
02233             if ((i != 0) && ((i % 4) == 0 )) printf("\n");
02234         }
02235         printf("\n");
02236     }
02237     
02238     for ( i = 0; i < mechanismCount; i++ ) {
02239         CK_MECHANISM_INFO minfo;
02240 
02241         memset(&minfo, 0, sizeof(CK_MECHANISM_INFO));
02242         crv = pFunctionList->C_GetMechanismInfo(pSlotList[slotID],
02243                                                 pMechanismList[i], &minfo);
02244         if ( CKR_OK != crv ) {
02245             PKM_Error( "C_GetMechanismInfo(%lu, %lu) returned 0x%08X, %-26s\n",
02246                        pSlotList[slotID], pMechanismList[i], crv, 
02247                        PKM_CK_RVtoStr(crv));
02248             return crv;
02249         }
02250 
02251         PKM_LogIt( "    [%lu]: CK_MECHANISM_TYPE = %lu\n", (i+1),
02252                    pMechanismList[i]);
02253         PKM_LogIt( "    ulMinKeySize = %lu\n", minfo.ulMinKeySize);
02254         PKM_LogIt( "    ulMaxKeySize = %lu\n", minfo.ulMaxKeySize);
02255         PKM_LogIt( "    flags = 0x%08x\n", minfo.flags);
02256         PKM_LogIt( "        -> HW = %s\n", minfo.flags & CKF_HW ?
02257                    "TRUE" : "FALSE");
02258         PKM_LogIt( "        -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ?
02259                    "TRUE" : "FALSE");
02260         PKM_LogIt( "        -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ?
02261                    "TRUE" : "FALSE");
02262         PKM_LogIt( "        -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ?
02263                    "TRUE" : "FALSE");
02264         PKM_LogIt( "        -> SIGN = %s\n", minfo.flags & CKF_SIGN ?
02265                    "TRUE" : "FALSE");
02266         PKM_LogIt( "        -> SIGN_RECOVER = %s\n", minfo.flags &
02267                    CKF_SIGN_RECOVER ? "TRUE" : "FALSE");
02268         PKM_LogIt( "        -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ?
02269                    "TRUE" : "FALSE");
02270         PKM_LogIt( "        -> VERIFY_RECOVER = %s\n",
02271                    minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE");
02272         PKM_LogIt( "        -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ?
02273                    "TRUE" : "FALSE");
02274         PKM_LogIt( "        -> GENERATE_KEY_PAIR = %s\n",
02275                    minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE");
02276         PKM_LogIt( "        -> WRAP = %s\n", minfo.flags & CKF_WRAP ?
02277                    "TRUE" : "FALSE");
02278         PKM_LogIt( "        -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ?
02279                    "TRUE" : "FALSE");
02280         PKM_LogIt( "        -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ?
02281                    "TRUE" : "FALSE");
02282         PKM_LogIt( "        -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ?
02283                    "TRUE" : "FALSE");
02284 
02285         PKM_LogIt( "\n");
02286     }
02287 
02288 
02289     return crv;
02290 
02291 }
02292 
02293 CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID * pSlotList,
02294               CK_ULONG slotID) {
02295     CK_SESSION_HANDLE hSession;
02296     CK_RV crv = CKR_OK;
02297     CK_BYTE randomData[16];
02298     CK_BYTE seed[] = {0x01, 0x03, 0x35, 0x55, 0xFF};
02299 
02300     NUMTESTS++; /* increment NUMTESTS */
02301 
02302     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
02303                                        NULL, NULL, &hSession);
02304     if (crv != CKR_OK) {
02305         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
02306                    PKM_CK_RVtoStr(crv));
02307         return crv;
02308     }
02309 
02310     crv = pFunctionList->C_GenerateRandom(hSession,
02311                                           randomData, sizeof randomData);
02312     if (crv == CKR_OK) {
02313         PKM_LogIt("C_GenerateRandom without login succeeded\n");
02314     } else {
02315         PKM_Error( "C_GenerateRandom without login failed "
02316                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02317         return crv;
02318     }
02319     crv = pFunctionList->C_SeedRandom(hSession, seed, sizeof(seed));
02320     if (crv == CKR_OK) {
02321         PKM_LogIt("C_SeedRandom without login succeeded\n");
02322     } else {
02323         PKM_Error( "C_SeedRandom without login failed "
02324                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02325         return crv;
02326     }
02327     crv = pFunctionList->C_GenerateRandom(hSession,
02328                                           randomData, sizeof randomData);
02329     if (crv == CKR_OK) {
02330         PKM_LogIt("C_GenerateRandom without login succeeded\n");
02331     } else {
02332         PKM_Error( "C_GenerateRandom without login failed "
02333                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02334         return crv;
02335     }
02336     crv = pFunctionList->C_CloseSession(hSession);
02337     if (crv != CKR_OK) {
02338         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
02339                    PKM_CK_RVtoStr(crv));
02340         return crv;
02341     }
02342 
02343     return crv;
02344 
02345 }
02346 
02347 CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,
02348                        CK_SLOT_ID *pSlotList, CK_ULONG slotID,
02349                        CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
02350     CK_SESSION_HANDLE hSession;
02351     CK_RV crv = CKR_OK;
02352     
02353     NUMTESTS++; /* increment NUMTESTS */
02354 
02355     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
02356                                        NULL, NULL, &hSession);
02357     if (crv != CKR_OK) {
02358         PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv, 
02359                    PKM_CK_RVtoStr(crv));
02360         return crv;
02361     }
02362 
02363     crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *) 
02364                                  "netscape", 8);
02365     if (crv == CKR_OK) {
02366         PKM_Error("C_Login with wrong password succeeded\n");
02367         return CKR_FUNCTION_FAILED;
02368     } else {
02369         PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
02370                   "%-26s.\n ", crv, PKM_CK_RVtoStr(crv));
02371     }
02372     crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *) 
02373                                  "red hat", 7);
02374     if (crv == CKR_OK) {
02375         PKM_Error("C_Login with wrong password succeeded\n");
02376         return CKR_FUNCTION_FAILED;
02377     } else {
02378         PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
02379                   "%-26s.\n ", crv, PKM_CK_RVtoStr(crv));
02380     }
02381     crv = pFunctionList->C_Login(hSession, CKU_USER, 
02382                                  (unsigned char *) "sun", 3);
02383     if (crv == CKR_OK) {
02384         PKM_Error("C_Login with wrong password succeeded\n");
02385         return CKR_FUNCTION_FAILED;
02386     } else {
02387         PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
02388                   "%-26s.\n ", crv, PKM_CK_RVtoStr(crv));
02389     }
02390     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
02391     if (crv == CKR_OK) {
02392         PKM_LogIt("C_Login with correct password succeeded\n");
02393     } else {
02394         PKM_Error("C_Login with correct password failed "
02395                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02396         return crv;
02397     }
02398 
02399     crv = pFunctionList->C_Logout(hSession);
02400     if (crv == CKR_OK) {
02401         PKM_LogIt("C_Logout succeeded\n");
02402     } else {
02403         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
02404                    PKM_CK_RVtoStr(crv));
02405         return crv;
02406     }
02407 
02408     crv = pFunctionList->C_CloseSession(hSession);
02409     if (crv != CKR_OK) {
02410         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
02411                    PKM_CK_RVtoStr(crv));
02412         return crv;
02413     }
02414 
02415     return crv;
02416 
02417 }
02418 
02419 /*
02420 * PKM_LegacyFunctions
02421 *
02422 * Legacyfunctions exist only for backwards compatibility.
02423 * C_GetFunctionStatus and C_CancelFunction functions were
02424 * meant for managing parallel execution of cryptographic functions.
02425 *
02426 * C_GetFunctionStatus is a legacy function which should simply return
02427 * the value CKR_FUNCTION_NOT_PARALLEL.
02428 *
02429 * C_CancelFunction is a legacy function which should simply return the
02430 * value CKR_FUNCTION_NOT_PARALLEL.
02431 *
02432 */
02433 CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
02434                           CK_SLOT_ID * pSlotList, CK_ULONG slotID,
02435                           CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
02436     CK_SESSION_HANDLE hSession;
02437     CK_RV crv = CKR_OK;
02438     NUMTESTS++; /* increment NUMTESTS */
02439 
02440     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
02441                                        NULL, NULL, &hSession);
02442     if (crv != CKR_OK) {
02443         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
02444                    PKM_CK_RVtoStr(crv));
02445         return crv;
02446     }
02447 
02448     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
02449     if (crv == CKR_OK) {
02450         PKM_LogIt("C_Login with correct password succeeded\n");
02451     } else {
02452         PKM_Error( "C_Login with correct password failed "
02453                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02454         return crv;
02455     }
02456 
02457     crv = pFunctionList->C_GetFunctionStatus(hSession);
02458     if (crv == CKR_FUNCTION_NOT_PARALLEL) {
02459         PKM_LogIt("C_GetFunctionStatus correctly"
02460                   "returned CKR_FUNCTION_NOT_PARALLEL \n");
02461     } else {
02462         PKM_Error( "C_GetFunctionStatus failed "
02463                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02464         return crv;
02465     }
02466 
02467     crv = pFunctionList->C_CancelFunction(hSession);
02468     if (crv == CKR_FUNCTION_NOT_PARALLEL) {
02469         PKM_LogIt("C_CancelFunction correctly "
02470                   "returned CKR_FUNCTION_NOT_PARALLEL \n");
02471     } else {
02472         PKM_Error( "C_CancelFunction failed "
02473                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02474         return crv;
02475     }
02476 
02477     crv = pFunctionList->C_Logout(hSession);
02478     if (crv == CKR_OK) {
02479         PKM_LogIt("C_Logout succeeded\n");
02480     } else {
02481         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
02482                    PKM_CK_RVtoStr(crv));
02483         return crv;
02484     }
02485 
02486     crv = pFunctionList->C_CloseSession(hSession);
02487     if (crv != CKR_OK) {
02488         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
02489                    PKM_CK_RVtoStr(crv));
02490         return crv;
02491     }
02492 
02493     return crv;
02494 
02495 }
02496 
02497 /*
02498 *  PKM_DualFuncDigest - demostrates the Dual-function
02499 *  cryptograpic functions:
02500 *
02501 *   C_DigestEncryptUpdate - multi-part Digest and Encrypt
02502 *   C_DecryptDigestUpdate - multi-part Decrypt and Digest
02503 *
02504 *
02505 */
02506 
02507 CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,
02508                        CK_SESSION_HANDLE hSession,
02509                        CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech,
02510                        CK_OBJECT_HANDLE hSecKeyDigest, 
02511                        CK_MECHANISM *digestMech, 
02512                        const CK_BYTE *  pData, CK_ULONG pDataLen) {
02513     CK_RV crv = CKR_OK;
02514     CK_BYTE eDigest[MAX_DIGEST_SZ];
02515     CK_BYTE dDigest[MAX_DIGEST_SZ];
02516     CK_ULONG ulDigestLen;
02517     CK_BYTE ciphertext[MAX_CIPHER_SZ];
02518     CK_ULONG ciphertextLen, lastLen;
02519     CK_BYTE plaintext[MAX_DATA_SZ];
02520     CK_ULONG plaintextLen;
02521     unsigned int i;
02522 
02523     memset(eDigest, 0, sizeof(eDigest));
02524     memset(dDigest, 0, sizeof(dDigest));
02525     memset(ciphertext, 0, sizeof(ciphertext));
02526     memset(plaintext, 0, sizeof(plaintext));
02527 
02528     NUMTESTS++; /* increment NUMTESTS */
02529 
02530     /*
02531      * First init the Digest and Ecrypt operations
02532      */
02533     crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSecKey);
02534     if (crv != CKR_OK) {
02535         PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, 
02536                    PKM_CK_RVtoStr(crv));
02537         return crv;
02538     }
02539     crv = pFunctionList->C_DigestInit(hSession, digestMech);
02540     if (crv != CKR_OK) {
02541         PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, 
02542                    PKM_CK_RVtoStr(crv));
02543         return crv;
02544     }
02545 
02546     ciphertextLen = sizeof(ciphertext);
02547     crv = pFunctionList->C_DigestEncryptUpdate(hSession, (CK_BYTE * ) pData,
02548                                                pDataLen,
02549                                                ciphertext, &ciphertextLen);
02550     if (crv != CKR_OK) {
02551         PKM_Error( "C_DigestEncryptUpdate failed with 0x%08X, %-26s\n", crv, 
02552                    PKM_CK_RVtoStr(crv));
02553         return crv;
02554     }
02555 
02556     ulDigestLen = sizeof(eDigest);
02557     crv = pFunctionList->C_DigestFinal(hSession, eDigest, &ulDigestLen);
02558     if (crv != CKR_OK) {
02559         PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv, 
02560                    PKM_CK_RVtoStr(crv));
02561         return crv;
02562     }
02563 
02564 
02565     /* get the last piece of ciphertext (length should be 0 */
02566     lastLen = sizeof(ciphertext) - ciphertextLen;
02567     crv = pFunctionList->C_EncryptFinal(hSession,
02568                                       (CK_BYTE * )&ciphertext[ciphertextLen],
02569                                       &lastLen);
02570     if (crv != CKR_OK) {
02571         PKM_Error( "C_EncryptFinal failed with 0x%08X, %-26s\n", crv, 
02572                    PKM_CK_RVtoStr(crv));
02573         return crv;
02574     }
02575     ciphertextLen = ciphertextLen + lastLen;
02576     if (verbose) {
02577         printf("ciphertext = ");
02578         for (i = 0; i < ciphertextLen; i++) {
02579             printf("%02x", (unsigned)ciphertext[i]);
02580         }
02581         printf("\n");
02582         printf("eDigest = ");
02583         for (i = 0; i < ulDigestLen; i++) {
02584             printf("%02x", (unsigned)eDigest[i]);
02585         }
02586         printf("\n");
02587     }
02588 
02589     /* Decrypt the text */
02590     crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSecKey);
02591     if (crv != CKR_OK) {
02592         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
02593                    PKM_CK_RVtoStr(crv));
02594         return crv;
02595     }
02596     crv = pFunctionList->C_DigestInit(hSession, digestMech);
02597     if (crv != CKR_OK) {
02598         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
02599                    PKM_CK_RVtoStr(crv));
02600         return crv;
02601     }
02602 
02603     plaintextLen = sizeof(plaintext);
02604     crv = pFunctionList->C_DecryptDigestUpdate(hSession, ciphertext,
02605                                                ciphertextLen,
02606                                                plaintext,
02607                                                &plaintextLen);
02608     if (crv != CKR_OK) {
02609         PKM_Error( "C_DecryptDigestUpdate failed with 0x%08X, %-26s\n", crv, 
02610                    PKM_CK_RVtoStr(crv));
02611         return crv;
02612     }
02613     lastLen = sizeof(plaintext) - plaintextLen;
02614 
02615     crv = pFunctionList->C_DecryptFinal(hSession,
02616                                         (CK_BYTE * )&plaintext[plaintextLen],
02617                                         &lastLen);
02618     if (crv != CKR_OK) {
02619         PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, 
02620                    PKM_CK_RVtoStr(crv));
02621         return crv;
02622     }
02623     plaintextLen = plaintextLen + lastLen;
02624 
02625     ulDigestLen = sizeof(dDigest);
02626     crv = pFunctionList->C_DigestFinal(hSession, dDigest, &ulDigestLen);
02627     if (crv != CKR_OK) {
02628         PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv, 
02629                    PKM_CK_RVtoStr(crv));
02630         return crv;
02631     }
02632 
02633     if (plaintextLen != pDataLen) {
02634         PKM_Error( "plaintextLen is %lu\n", plaintextLen);
02635         return crv;
02636     }
02637     
02638     if (verbose) {
02639         printf("plaintext = ");
02640         for (i = 0; i < plaintextLen; i++) {
02641             printf("%02x", (unsigned)plaintext[i]);
02642         }
02643         printf("\n");
02644         printf("dDigest = ");
02645         for (i = 0; i < ulDigestLen; i++) {
02646             printf("%02x", (unsigned)dDigest[i]);
02647         }
02648         printf("\n");
02649     }
02650     
02651     if (memcmp(eDigest, dDigest, ulDigestLen) == 0) {
02652         PKM_LogIt("Encrypted Digest equals Decrypted Digest\n");
02653     } else {
02654         PKM_Error( "Digests don't match\n");
02655     }
02656 
02657     if ((plaintextLen == pDataLen) &&
02658         (memcmp(plaintext, pData, pDataLen))  == 0) {
02659         PKM_LogIt("DualFuncDigest decrypt test case passed\n");
02660     } else {
02661         PKM_Error( "DualFuncDigest derypt test case failed\n");
02662     }
02663 
02664     return crv;
02665 
02666 }
02667 
02668 /*
02669 * PKM_SecKeyCrypt - Symmetric key encrypt/decyprt
02670 *
02671 */
02672 
02673 CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList, 
02674                       CK_SESSION_HANDLE hSession,
02675                        CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech,
02676                        const CK_BYTE *  pData, CK_ULONG dataLen) {
02677     CK_RV crv = CKR_OK;
02678 
02679     CK_BYTE cipher1[MAX_CIPHER_SZ];
02680     CK_BYTE cipher2[MAX_CIPHER_SZ];
02681     CK_BYTE data1[MAX_DATA_SZ];
02682     CK_BYTE data2[MAX_DATA_SZ];
02683     CK_ULONG cipher1Len =0, cipher2Len =0, lastLen =0;
02684     CK_ULONG data1Len =0, data2Len =0;
02685     
02686     NUMTESTS++; /* increment NUMTESTS */
02687 
02688     memset(cipher1, 0, sizeof(cipher1));
02689     memset(cipher2, 0, sizeof(cipher2));
02690     memset(data1, 0, sizeof(data1));
02691     memset(data2, 0, sizeof(data2));
02692 
02693     /* C_Encrypt */
02694     crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey);
02695     if (crv != CKR_OK) {
02696         PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, 
02697                    PKM_CK_RVtoStr(crv));
02698         return crv;
02699     }
02700     cipher1Len = sizeof(cipher1);
02701     crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE * ) pData, dataLen,
02702                                    cipher1, &cipher1Len);
02703     if (crv != CKR_OK) {
02704         PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv, 
02705                    PKM_CK_RVtoStr(crv));
02706         return crv;
02707     }
02708 
02709     /* C_EncryptUpdate */
02710     crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey);
02711     if (crv != CKR_OK) {
02712         PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, 
02713                    PKM_CK_RVtoStr(crv));
02714         return crv;
02715     }
02716     cipher2Len = sizeof(cipher2);
02717     crv = pFunctionList->C_EncryptUpdate (hSession, (CK_BYTE * ) pData,
02718                                           dataLen,
02719                                           cipher2, &cipher2Len);
02720     if (crv != CKR_OK) {
02721         PKM_Error( "C_EncryptUpdate failed with 0x%08X, %-26s\n", crv, 
02722                    PKM_CK_RVtoStr(crv));
02723         return crv;
02724     }
02725     lastLen = sizeof(cipher2) - cipher2Len;
02726 
02727     crv = pFunctionList->C_EncryptFinal(hSession,
02728                                     (CK_BYTE * )&cipher2[cipher2Len],
02729                                     &lastLen);
02730     cipher2Len = cipher2Len + lastLen;
02731 
02732     if ( (cipher1Len == cipher2Len) &&
02733          (memcmp(cipher1, cipher2, sizeof(cipher1Len)) == 0) ) {
02734         PKM_LogIt("encrypt test case passed\n");
02735     } else {
02736         PKM_Error( "encrypt test case failed\n");
02737         return CKR_GENERAL_ERROR;
02738     }
02739 
02740     /* C_Decrypt */
02741     crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey);
02742     if (crv != CKR_OK) {
02743         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
02744                    PKM_CK_RVtoStr(crv));
02745         return crv;
02746     }
02747     data1Len = sizeof(data1);
02748     crv = pFunctionList->C_Decrypt(hSession, cipher1, cipher1Len,
02749                                    data1, &data1Len);
02750     if (crv != CKR_OK) {
02751         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
02752                    PKM_CK_RVtoStr(crv));
02753         return crv;
02754     }
02755     /* now use C_DecryptUpdate the text */
02756     crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey);
02757     if (crv != CKR_OK) {
02758         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
02759                    PKM_CK_RVtoStr(crv));
02760         return crv;
02761     }
02762     data2Len = sizeof(data2);
02763     crv = pFunctionList->C_DecryptUpdate(hSession, cipher2,
02764                                          cipher2Len,
02765                                          data2, &data2Len);
02766     if (crv != CKR_OK) {
02767         PKM_Error( "C_DecryptUpdate failed with 0x%08X, %-26s\n", crv, 
02768                    PKM_CK_RVtoStr(crv));
02769         return crv;
02770     }
02771     lastLen = sizeof(data2) - data2Len;
02772     crv = pFunctionList->C_DecryptFinal(hSession,
02773                                         (CK_BYTE * )&data2[data2Len],
02774                                         &lastLen);
02775     if (crv != CKR_OK) {
02776         PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, 
02777                    PKM_CK_RVtoStr(crv));
02778         return crv;
02779     }
02780     data2Len = data2Len + lastLen;
02781 
02782 
02783     /* Comparison of Decrypt data */
02784 
02785     if ( (data1Len == data2Len) && (dataLen == data1Len) &&
02786          (memcmp(data1, pData, dataLen) == 0) &&
02787          (memcmp(data2, pData, dataLen) == 0) ) {
02788         PKM_LogIt("decrypt test case passed\n");
02789     } else {
02790         PKM_Error( "derypt test case failed\n");
02791     }
02792 
02793     return crv;
02794 
02795 }
02796     
02797 
02798 CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList,
02799                     CK_SLOT_ID * pSlotList, CK_ULONG slotID,
02800                     CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
02801     CK_SESSION_HANDLE hSession;
02802     CK_RV crv = CKR_OK;
02803     CK_MECHANISM sAESKeyMech = {
02804         CKM_AES_KEY_GEN, NULL, 0
02805     };
02806     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
02807     CK_KEY_TYPE keyAESType = CKK_AES;
02808     CK_UTF8CHAR AESlabel[] = "An AES secret key object";
02809     CK_ULONG AESvalueLen = 16;
02810     CK_ATTRIBUTE sAESKeyTemplate[9];    
02811     CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
02812 
02813     CK_BYTE KEY[16];
02814     CK_BYTE IV[16];
02815     static const CK_BYTE CIPHERTEXT[] = {
02816         0x7e,0x6a,0x3f,0x3b,0x39,0x3c,0xf2,0x4b, 
02817         0xce,0xcc,0x23,0x6d,0x80,0xfd,0xe0,0xff
02818     };
02819     CK_BYTE ciphertext[64];
02820     CK_BYTE ciphertext2[64];
02821     CK_ULONG ciphertextLen, ciphertext2Len, lastLen;
02822     CK_BYTE plaintext[32];
02823     CK_BYTE plaintext2[32];
02824     CK_ULONG plaintextLen, plaintext2Len;
02825     CK_BYTE wrappedKey[16];
02826     CK_ULONG wrappedKeyLen;
02827     CK_MECHANISM aesEcbMech = {
02828         CKM_AES_ECB, NULL, 0
02829     };
02830     CK_OBJECT_HANDLE hTestKey;
02831     CK_MECHANISM mech_AES_CBC;
02832 
02833     NUMTESTS++; /* increment NUMTESTS */
02834 
02835     memset(ciphertext, 0, sizeof(ciphertext));
02836     memset(ciphertext2, 0, sizeof(ciphertext2));
02837     memset(IV, 0x00, sizeof(IV));
02838     memset(KEY, 0x00, sizeof(KEY));
02839     
02840     mech_AES_CBC.mechanism      = CKM_AES_CBC; 
02841     mech_AES_CBC.pParameter = IV; 
02842     mech_AES_CBC.ulParameterLen = sizeof(IV);
02843 
02844     /* AES key template */
02845     sAESKeyTemplate[0].type       = CKA_CLASS; 
02846     sAESKeyTemplate[0].pValue     = &class;
02847     sAESKeyTemplate[0].ulValueLen = sizeof(class);
02848     sAESKeyTemplate[1].type       = CKA_KEY_TYPE; 
02849     sAESKeyTemplate[1].pValue     = &keyAESType; 
02850     sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
02851     sAESKeyTemplate[2].type       = CKA_LABEL;
02852     sAESKeyTemplate[2].pValue     = AESlabel; 
02853     sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1;
02854     sAESKeyTemplate[3].type       = CKA_ENCRYPT; 
02855     sAESKeyTemplate[3].pValue     = &true; 
02856     sAESKeyTemplate[3].ulValueLen = sizeof(true);
02857     sAESKeyTemplate[4].type       = CKA_DECRYPT; 
02858     sAESKeyTemplate[4].pValue     = &true; 
02859     sAESKeyTemplate[4].ulValueLen = sizeof(true);
02860     sAESKeyTemplate[5].type       = CKA_SIGN; 
02861     sAESKeyTemplate[5].pValue     = &true; 
02862     sAESKeyTemplate[5].ulValueLen = sizeof (true);
02863     sAESKeyTemplate[6].type       = CKA_VERIFY; 
02864     sAESKeyTemplate[6].pValue     = &true; 
02865     sAESKeyTemplate[6].ulValueLen = sizeof(true);
02866     sAESKeyTemplate[7].type       = CKA_UNWRAP; 
02867     sAESKeyTemplate[7].pValue     = &true; 
02868     sAESKeyTemplate[7].ulValueLen = sizeof(true);
02869     sAESKeyTemplate[8].type       = CKA_VALUE_LEN; 
02870     sAESKeyTemplate[8].pValue     = &AESvalueLen; 
02871     sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
02872 
02873     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
02874                                        NULL, NULL, &hSession);
02875     if (crv != CKR_OK) {
02876         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
02877                    PKM_CK_RVtoStr(crv));
02878         return crv;
02879     }
02880 
02881     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
02882     if (crv == CKR_OK) {
02883         PKM_LogIt("C_Login with correct password succeeded\n");
02884     } else {
02885         PKM_Error( "C_Login with correct password failed "
02886                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
02887         return crv;
02888     }
02889 
02890     PKM_LogIt("Generate an AES key ... \n");
02891     /* generate an AES Secret Key */
02892     crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech,
02893                                        sAESKeyTemplate,
02894                                        NUM_ELEM(sAESKeyTemplate),
02895                                        &hKey);
02896     if (crv == CKR_OK) {
02897         PKM_LogIt("C_GenerateKey AES succeeded\n");
02898     } else {
02899         PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n", 
02900                    crv, PKM_CK_RVtoStr(crv));
02901         return crv;
02902     }
02903 
02904     crv = pFunctionList->C_EncryptInit(hSession, &aesEcbMech, hKey);
02905     if (crv != CKR_OK) {
02906         PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, 
02907                    PKM_CK_RVtoStr(crv));
02908         return crv;
02909     }
02910     wrappedKeyLen = sizeof(wrappedKey);
02911     crv = pFunctionList->C_Encrypt(hSession, KEY, sizeof(KEY),
02912                                    wrappedKey, &wrappedKeyLen);
02913     if (crv != CKR_OK) {
02914         PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv, 
02915                    PKM_CK_RVtoStr(crv));
02916         return crv;
02917     }
02918     if (wrappedKeyLen != sizeof(wrappedKey)) {
02919         PKM_Error( "wrappedKeyLen is %lu\n", wrappedKeyLen);
02920         return crv;
02921     }
02922     /* Import an encrypted key */
02923     crv = pFunctionList->C_UnwrapKey(hSession, &aesEcbMech, hKey,
02924                                      wrappedKey, wrappedKeyLen,
02925                                      sAESKeyTemplate,
02926                                      NUM_ELEM(sAESKeyTemplate),
02927                                      &hTestKey);
02928     if (crv != CKR_OK) {
02929         PKM_Error( "C_UnwraPKey failed with 0x%08X, %-26s\n", crv, 
02930                    PKM_CK_RVtoStr(crv));
02931         return crv;
02932     }
02933     /* AES Encrypt the text */
02934     crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey);
02935     if (crv != CKR_OK) {
02936         PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, 
02937                    PKM_CK_RVtoStr(crv));
02938         return crv;
02939     }
02940     ciphertextLen = sizeof(ciphertext);
02941     crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE *) PLAINTEXT, 
02942                                    sizeof(PLAINTEXT),
02943                                    ciphertext, &ciphertextLen);
02944     if (crv != CKR_OK) {
02945         PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv, 
02946                    PKM_CK_RVtoStr(crv));
02947         return crv;
02948     }
02949 
02950     if ( (ciphertextLen == sizeof(CIPHERTEXT)) &&
02951        (memcmp(ciphertext, CIPHERTEXT, ciphertextLen) == 0)) {
02952         PKM_LogIt("AES CBCVarKey128 encrypt test case 1 passed\n");
02953     } else {
02954         PKM_Error( "AES CBCVarKey128 encrypt test case 1 failed\n");
02955         return crv;
02956     }
02957 
02958     /* now use EncryptUpdate the text */
02959     crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey);
02960     if (crv != CKR_OK) {
02961         PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, 
02962                    PKM_CK_RVtoStr(crv));
02963         return crv;
02964     }
02965     ciphertext2Len = sizeof(ciphertext2);
02966     crv = pFunctionList->C_EncryptUpdate (hSession, (CK_BYTE *) PLAINTEXT,
02967                                           sizeof(PLAINTEXT),
02968                                           ciphertext2, &ciphertext2Len);
02969     if (crv != CKR_OK) {
02970         PKM_Error( "C_EncryptUpdate failed with 0x%08X, %-26s\n", crv, 
02971                    PKM_CK_RVtoStr(crv));
02972         return crv;
02973     }
02974     lastLen = sizeof(ciphertext2) - ciphertext2Len;
02975 
02976     crv = pFunctionList->C_EncryptFinal(hSession,
02977                                     (CK_BYTE * )&ciphertext2[ciphertext2Len],
02978                                     &lastLen);
02979     ciphertext2Len = ciphertext2Len + lastLen;
02980 
02981     if ( (ciphertextLen == ciphertext2Len) &&
02982          (memcmp(ciphertext, ciphertext2, sizeof(CIPHERTEXT)) == 0) &&
02983          (memcmp(ciphertext2, CIPHERTEXT, sizeof(CIPHERTEXT)) == 0)) {
02984         PKM_LogIt("AES CBCVarKey128 encrypt test case 2 passed\n");
02985     } else {
02986         PKM_Error( "AES CBCVarKey128 encrypt test case 2 failed\n");
02987         return CKR_GENERAL_ERROR;
02988     }
02989 
02990     /* AES CBC Decrypt the text */
02991     crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey);
02992     if (crv != CKR_OK) {
02993         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
02994                    PKM_CK_RVtoStr(crv));
02995         return crv;
02996     }
02997     plaintextLen = sizeof(plaintext);
02998     crv = pFunctionList->C_Decrypt(hSession, ciphertext, ciphertextLen,
02999                                    plaintext, &plaintextLen);
03000     if (crv != CKR_OK) {
03001         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
03002                    PKM_CK_RVtoStr(crv));
03003         return crv;
03004     }
03005     if ((plaintextLen == sizeof(PLAINTEXT))
03006         && (memcmp(plaintext, PLAINTEXT, plaintextLen) == 0)) {
03007         PKM_LogIt("AES CBCVarKey128 decrypt test case 1 passed\n");
03008     } else {
03009         PKM_Error( "AES CBCVarKey128 derypt test case 1 failed\n");
03010     }
03011     /* now use DecryptUpdate the text */
03012     crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey);
03013     if (crv != CKR_OK) {
03014         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
03015                    PKM_CK_RVtoStr(crv));
03016         return crv;
03017     }
03018     plaintext2Len = sizeof(plaintext2);
03019     crv = pFunctionList->C_DecryptUpdate(hSession, ciphertext2,
03020                                          ciphertext2Len,
03021                                          plaintext2, &plaintext2Len);
03022     if (crv != CKR_OK) {
03023         PKM_Error( "C_DecryptUpdate failed with 0x%08X, %-26s\n", crv, 
03024                    PKM_CK_RVtoStr(crv));
03025         return crv;
03026     }
03027     lastLen = sizeof(plaintext2) - plaintext2Len;
03028     crv = pFunctionList->C_DecryptFinal(hSession,
03029                                      (CK_BYTE * )&plaintext2[plaintext2Len],
03030                                      &lastLen);
03031     plaintext2Len = plaintext2Len + lastLen;
03032 
03033     if ( (plaintextLen == plaintext2Len) &&
03034          (memcmp(plaintext, plaintext2, plaintext2Len) == 0) &&
03035          (memcmp(plaintext2, PLAINTEXT, sizeof(PLAINTEXT)) == 0)) {
03036         PKM_LogIt("AES CBCVarKey128 decrypt test case 2 passed\n");
03037     } else {
03038         PKM_Error( "AES CBCVarKey128 decrypt test case 2 failed\n");
03039         return CKR_GENERAL_ERROR;
03040     }
03041 
03042     crv = pFunctionList->C_Logout(hSession);
03043     if (crv == CKR_OK) {
03044         PKM_LogIt("C_Logout succeeded\n");
03045     } else {
03046         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
03047                    PKM_CK_RVtoStr(crv));
03048         return crv;
03049     }
03050     crv = pFunctionList->C_CloseSession(hSession);
03051     if (crv != CKR_OK) {
03052         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
03053                    PKM_CK_RVtoStr(crv));
03054         return crv;
03055     }
03056 
03057 
03058     return crv;
03059 
03060 }
03061 
03062 CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList, 
03063                     CK_SESSION_HANDLE hRwSession,
03064                     CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
03065                     CK_MECHANISM *signMech, const CK_BYTE *  pData, 
03066                     CK_ULONG pDataLen) {
03067     CK_RV crv = CKR_OK;
03068     CK_BYTE sig[MAX_SIG_SZ];
03069     CK_ULONG sigLen = 0 ;
03070     
03071     NUMTESTS++; /* increment NUMTESTS */
03072     memset(sig, 0, sizeof(sig));
03073 
03074     /* C_Sign  */
03075     crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey);
03076     if (crv != CKR_OK) {
03077         PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, 
03078                    PKM_CK_RVtoStr(crv));
03079         return crv;
03080     }
03081     sigLen = sizeof(sig);
03082     crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE * ) pData, pDataLen,
03083                                 sig, &sigLen);
03084     if (crv != CKR_OK) {
03085         PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, 
03086                    PKM_CK_RVtoStr(crv));
03087         return crv;
03088     }
03089 
03090     /* C_Verify the signature */
03091     crv = pFunctionList->C_VerifyInit(hRwSession, signMech, hPubKey);
03092     if (crv != CKR_OK) {
03093         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
03094                    PKM_CK_RVtoStr(crv));
03095         return crv;
03096     }
03097     crv = pFunctionList->C_Verify(hRwSession, (CK_BYTE * ) pData, pDataLen,
03098                                   sig, sigLen);
03099     if (crv == CKR_OK) {
03100         PKM_LogIt("C_Verify succeeded\n");
03101     } else {
03102         PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv, 
03103                    PKM_CK_RVtoStr(crv));
03104         return crv;
03105     }
03106 
03107    /* Check that the mechanism is Multi-part */
03108     if (signMech->mechanism == CKM_DSA || 
03109         signMech->mechanism == CKM_RSA_PKCS) {
03110         return crv;
03111     }
03112 
03113     memset(sig, 0, sizeof(sig));
03114     /* SignUpdate  */
03115     crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey);
03116     if (crv != CKR_OK) {
03117         PKM_Error( "C_SignInit failed with 0x%08lX %-26s\n", crv, 
03118                    PKM_CK_RVtoStr(crv));
03119         return crv;
03120     }
03121     crv = pFunctionList->C_SignUpdate(hRwSession, (CK_BYTE * ) pData, pDataLen);
03122     if (crv != CKR_OK) {
03123         PKM_Error( "C_Sign failed with 0x%08lX %-26s\n", crv, 
03124                    PKM_CK_RVtoStr(crv));
03125         return crv;
03126     }
03127 
03128     sigLen = sizeof(sig);
03129     crv = pFunctionList->C_SignFinal(hRwSession, sig, &sigLen);
03130     if (crv != CKR_OK) {
03131         PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, 
03132                    PKM_CK_RVtoStr(crv));
03133         return crv;
03134     }
03135 
03136     /* C_VerifyUpdate the signature  */
03137     crv = pFunctionList->C_VerifyInit(hRwSession, signMech,
03138                                       hPubKey);
03139     if (crv != CKR_OK) {
03140         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
03141                    PKM_CK_RVtoStr(crv));
03142         return crv;
03143     }
03144     crv = pFunctionList->C_VerifyUpdate(hRwSession, (CK_BYTE * ) pData, 
03145                                         pDataLen);
03146     if (crv != CKR_OK) {
03147         PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, 
03148                    PKM_CK_RVtoStr(crv));
03149         return crv;
03150     }
03151     crv = pFunctionList->C_VerifyFinal(hRwSession, sig, sigLen);
03152     if (crv == CKR_OK) {
03153         PKM_LogIt("C_VerifyFinal succeeded\n");
03154     } else {
03155         PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, 
03156                    PKM_CK_RVtoStr(crv));
03157         return crv;
03158     }
03159     return crv;
03160 
03161 }
03162 
03163 
03164 
03165 CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList, 
03166                     CK_SLOT_ID * pSlotList,
03167                     CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, 
03168                     CK_ULONG pwdLen){
03169     CK_SESSION_HANDLE hSession;
03170     CK_RV crv = CKR_OK;
03171 
03172 /*** DSA Key ***/
03173     CK_MECHANISM dsaParamGenMech;
03174     CK_ULONG primeBits = 1024;
03175     CK_ATTRIBUTE dsaParamGenTemplate[1]; 
03176     CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE;
03177     CK_BYTE DSA_P[128];
03178     CK_BYTE DSA_Q[20];
03179     CK_BYTE DSA_G[128];
03180     CK_MECHANISM dsaKeyPairGenMech;
03181     CK_ATTRIBUTE dsaPubKeyTemplate[5]; 
03182     CK_ATTRIBUTE dsaPrivKeyTemplate[5]; 
03183     CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
03184     CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
03185     
03186     /* From SHA1ShortMsg.req, Len = 136 */
03187     CK_BYTE MSG[] = {
03188         0xba, 0x33, 0x95, 0xfb,
03189         0x5a, 0xfa, 0x8e, 0x6a,
03190         0x43, 0xdf, 0x41, 0x6b,
03191         0x32, 0x7b, 0x74, 0xfa,
03192         0x44
03193     };
03194     CK_BYTE MD[] = {
03195         0xf7, 0x5d, 0x92, 0xa4,
03196         0xbb, 0x4d, 0xec, 0xc3,
03197         0x7c, 0x5c, 0x72, 0xfa,
03198         0x04, 0x75, 0x71, 0x0a,
03199         0x06, 0x75, 0x8c, 0x1d
03200     };
03201 
03202     CK_BYTE sha1Digest[20];
03203     CK_ULONG sha1DigestLen;
03204     CK_BYTE dsaSig[40];
03205     CK_ULONG dsaSigLen;
03206     CK_MECHANISM sha1Mech = {
03207         CKM_SHA_1, NULL, 0
03208     };
03209     CK_MECHANISM dsaMech = {
03210         CKM_DSA, NULL, 0
03211     };
03212     CK_MECHANISM dsaWithSha1Mech = {
03213         CKM_DSA_SHA1, NULL, 0
03214     };
03215 
03216     NUMTESTS++; /* increment NUMTESTS */
03217 
03218     /* DSA key init */
03219     dsaParamGenMech.mechanism      = CKM_DSA_PARAMETER_GEN; 
03220     dsaParamGenMech.pParameter = NULL_PTR; 
03221     dsaParamGenMech.ulParameterLen = 0;
03222     dsaParamGenTemplate[0].type = CKA_PRIME_BITS; 
03223     dsaParamGenTemplate[0].pValue     = &primeBits; 
03224     dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits);
03225     dsaPubKeyTemplate[0].type       = CKA_PRIME; 
03226     dsaPubKeyTemplate[0].pValue     = DSA_P;
03227     dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P);
03228     dsaPubKeyTemplate[1].type = CKA_SUBPRIME; 
03229     dsaPubKeyTemplate[1].pValue = DSA_Q;
03230     dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q);
03231     dsaPubKeyTemplate[2].type = CKA_BASE; 
03232     dsaPubKeyTemplate[2].pValue = DSA_G; 
03233     dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G);
03234     dsaPubKeyTemplate[3].type = CKA_TOKEN; 
03235     dsaPubKeyTemplate[3].pValue = &true; 
03236     dsaPubKeyTemplate[3].ulValueLen = sizeof(true);
03237     dsaPubKeyTemplate[4].type = CKA_VERIFY; 
03238     dsaPubKeyTemplate[4].pValue = &true; 
03239     dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
03240     dsaKeyPairGenMech.mechanism      = CKM_DSA_KEY_PAIR_GEN;
03241     dsaKeyPairGenMech.pParameter = NULL_PTR;
03242     dsaKeyPairGenMech.ulParameterLen = 0;
03243     dsaPrivKeyTemplate[0].type       = CKA_TOKEN;
03244     dsaPrivKeyTemplate[0].pValue     = &true; 
03245     dsaPrivKeyTemplate[0].ulValueLen = sizeof(true);
03246     dsaPrivKeyTemplate[1].type       = CKA_PRIVATE; 
03247     dsaPrivKeyTemplate[1].pValue     = &true; 
03248     dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
03249     dsaPrivKeyTemplate[2].type       = CKA_SENSITIVE; 
03250     dsaPrivKeyTemplate[2].pValue     = &true; 
03251     dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
03252     dsaPrivKeyTemplate[3].type       = CKA_SIGN, 
03253     dsaPrivKeyTemplate[3].pValue     = &true;
03254     dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
03255     dsaPrivKeyTemplate[4].type       = CKA_EXTRACTABLE; 
03256     dsaPrivKeyTemplate[4].pValue     = &true; 
03257     dsaPrivKeyTemplate[4].ulValueLen = sizeof(true);
03258 
03259     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
03260                                        CKF_RW_SESSION | CKF_SERIAL_SESSION,
03261                                        NULL, NULL, &hSession);
03262     if (crv != CKR_OK) {
03263         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
03264                    PKM_CK_RVtoStr(crv));
03265         return crv;
03266     }
03267 
03268     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
03269     if (crv == CKR_OK) {
03270         PKM_LogIt("C_Login with correct password succeeded\n");
03271     } else {
03272         PKM_Error( "C_Login with correct password failed "
03273                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03274         return crv;
03275     }
03276 
03277     PKM_LogIt("Generate DSA PQG domain parameters ... \n");
03278     /* Generate DSA domain parameters PQG */
03279     crv = pFunctionList->C_GenerateKey(hSession, &dsaParamGenMech,
03280                                        dsaParamGenTemplate,
03281                                        1,
03282                                        &hDsaParams);
03283     if (crv == CKR_OK) {
03284         PKM_LogIt("DSA domain parameter generation succeeded\n");
03285     } else {
03286         PKM_Error( "DSA domain parameter generation failed "
03287                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03288         return crv;
03289     }
03290     crv = pFunctionList->C_GetAttributeValue(hSession, hDsaParams,
03291                                              dsaPubKeyTemplate, 3);
03292     if (crv == CKR_OK) {
03293         PKM_LogIt("Getting DSA domain parameters succeeded\n");
03294     } else {
03295         PKM_Error( "Getting DSA domain parameters failed "
03296                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03297         return crv;
03298     }
03299     crv = pFunctionList->C_DestroyObject(hSession, hDsaParams);
03300     if (crv == CKR_OK) {
03301         PKM_LogIt("Destroying DSA domain parameters succeeded\n");
03302     } else {
03303         PKM_Error( "Destroying DSA domain parameters failed "
03304                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03305         return crv;
03306     }
03307     
03308     PKM_LogIt("Generate a DSA key pair ... \n");
03309     /* Generate a persistent DSA key pair */
03310     crv = pFunctionList->C_GenerateKeyPair(hSession, &dsaKeyPairGenMech,
03311                                            dsaPubKeyTemplate,
03312                                            NUM_ELEM(dsaPubKeyTemplate),
03313                                            dsaPrivKeyTemplate,
03314                                            NUM_ELEM(dsaPrivKeyTemplate),
03315                                            &hDSApubKey, &hDSAprivKey);
03316     if (crv == CKR_OK) {
03317         PKM_LogIt("DSA key pair generation succeeded\n");
03318     } else {
03319         PKM_Error( "DSA key pair generation failed "
03320                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03321         return crv;
03322     }
03323 
03324     /* Compute SHA-1 digest */
03325     crv = pFunctionList->C_DigestInit(hSession, &sha1Mech);
03326     if (crv != CKR_OK) {
03327         PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, 
03328                    PKM_CK_RVtoStr(crv));
03329         return crv;
03330     }
03331     sha1DigestLen = sizeof(sha1Digest);
03332     crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG),
03333                                   sha1Digest, &sha1DigestLen);
03334     if (crv != CKR_OK) {
03335         PKM_Error( "C_Digest failed with 0x%08X, %-26s\n", crv, 
03336                    PKM_CK_RVtoStr(crv));
03337         return crv;
03338     }
03339     if (sha1DigestLen != sizeof(sha1Digest)) {
03340         PKM_Error( "sha1DigestLen is %lu\n", sha1DigestLen);
03341         return crv;
03342     }
03343 
03344     if (memcmp(sha1Digest, MD, sizeof(MD)) == 0) {
03345         PKM_LogIt("SHA-1 SHA1ShortMsg test case Len = 136 passed\n");
03346     } else {
03347         PKM_Error( "SHA-1 SHA1ShortMsg test case Len = 136 failed\n");
03348     }
03349 
03350     crv = PKM_PubKeySign(pFunctionList, hSession,
03351                     hDSApubKey, hDSAprivKey,
03352                     &dsaMech, sha1Digest, sizeof(sha1Digest));
03353     if (crv == CKR_OK) {
03354         PKM_LogIt("PKM_PubKeySign CKM_DSA succeeded \n");
03355     } else {
03356         PKM_Error( "PKM_PubKeySign failed "
03357                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03358         return crv;
03359     }
03360     crv = PKM_PubKeySign(pFunctionList, hSession,
03361                     hDSApubKey, hDSAprivKey,
03362                     &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT));
03363     if (crv == CKR_OK) {
03364         PKM_LogIt("PKM_PubKeySign CKM_DSA_SHA1 succeeded \n");
03365     } else {
03366         PKM_Error( "PKM_PubKeySign failed "
03367                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03368         return crv;
03369     }
03370 
03371     /* Sign with DSA */
03372     crv = pFunctionList->C_SignInit(hSession, &dsaMech, hDSAprivKey);
03373     if (crv != CKR_OK) {
03374         PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, 
03375                    PKM_CK_RVtoStr(crv));
03376         return crv;
03377     }
03378     dsaSigLen = sizeof(dsaSig);
03379     crv = pFunctionList->C_Sign(hSession, sha1Digest, sha1DigestLen,
03380                                 dsaSig, &dsaSigLen);
03381     if (crv != CKR_OK) {
03382         PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, 
03383                    PKM_CK_RVtoStr(crv));
03384         return crv;
03385     }
03386 
03387     /* Verify the DSA signature */
03388     crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey);
03389     if (crv != CKR_OK) {
03390         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
03391                    PKM_CK_RVtoStr(crv));
03392         return crv;
03393     }
03394     crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen,
03395                                   dsaSig, dsaSigLen);
03396     if (crv == CKR_OK) {
03397         PKM_LogIt("C_Verify succeeded\n");
03398     } else {
03399         PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv, 
03400                    PKM_CK_RVtoStr(crv));
03401         return crv;
03402     }
03403 
03404     /* Verify the signature in a different way */
03405     crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech,
03406                                       hDSApubKey);
03407     if (crv != CKR_OK) {
03408         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
03409                    PKM_CK_RVtoStr(crv));
03410         return crv;
03411     }
03412     crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1);
03413     if (crv != CKR_OK) {
03414         PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, 
03415                    PKM_CK_RVtoStr(crv));
03416         return crv;
03417     }
03418     crv = pFunctionList->C_VerifyUpdate(hSession, MSG+1, sizeof(MSG)-1);
03419     if (crv != CKR_OK) {
03420         PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, 
03421                    PKM_CK_RVtoStr(crv));
03422         return crv;
03423     }
03424     crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen);
03425     if (crv == CKR_OK) {
03426         PKM_LogIt("C_VerifyFinal succeeded\n");
03427     } else {
03428         PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, 
03429                    PKM_CK_RVtoStr(crv));
03430         return crv;
03431     }
03432 
03433     /* Verify the signature in a different way */
03434     crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech,
03435                                       hDSApubKey);
03436     if (crv != CKR_OK) {
03437         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", 
03438             crv, PKM_CK_RVtoStr(crv));
03439         return crv;
03440     }
03441     crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1);
03442     if (crv != CKR_OK) {
03443         PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", 
03444             crv, PKM_CK_RVtoStr(crv));
03445         return crv;
03446     }
03447     crv = pFunctionList->C_VerifyUpdate(hSession, MSG+1, sizeof(MSG)-1);
03448     if (crv != CKR_OK) {
03449         PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", 
03450             crv, PKM_CK_RVtoStr(crv));
03451         return crv;
03452     }
03453     crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen);
03454     if (crv == CKR_OK) {
03455         PKM_LogIt("C_VerifyFinal of multi update succeeded.\n");
03456     } else {
03457         PKM_Error("C_VerifyFinal of multi update failed with 0x%08X, %-26s\n", 
03458             crv, PKM_CK_RVtoStr(crv));
03459         return crv;
03460     }
03461     /* Now modify the data */
03462     MSG[0] += 1;
03463     /* Compute SHA-1 digest */
03464     crv = pFunctionList->C_DigestInit(hSession, &sha1Mech);
03465     if (crv != CKR_OK) {
03466         PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, 
03467                    PKM_CK_RVtoStr(crv));
03468         return crv;
03469     }
03470     sha1DigestLen = sizeof(sha1Digest);
03471     crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG),
03472                                   sha1Digest, &sha1DigestLen);
03473     if (crv != CKR_OK) {
03474         PKM_Error( "C_Digest failed with 0x%08X, %-26s\n", crv, 
03475                    PKM_CK_RVtoStr(crv));
03476         return crv;
03477     }
03478     crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey);
03479     if (crv != CKR_OK) {
03480         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
03481                    PKM_CK_RVtoStr(crv));
03482         return crv;
03483     }
03484     crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen,
03485                                   dsaSig, dsaSigLen);
03486     if (crv != CKR_SIGNATURE_INVALID) {
03487         PKM_Error( "C_Verify of modified data succeeded\n");
03488         return crv;
03489     } else {
03490         PKM_LogIt("C_Verify of modified data returned as EXPECTED "
03491             " with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03492     }
03493 
03494     crv = pFunctionList->C_Logout(hSession);
03495     if (crv == CKR_OK) {
03496         PKM_LogIt("C_Logout succeeded\n");
03497     } else {
03498         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
03499                    PKM_CK_RVtoStr(crv));
03500         return crv;
03501     }
03502 
03503     crv = pFunctionList->C_CloseSession(hSession);
03504     if (crv != CKR_OK) {
03505         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
03506                    PKM_CK_RVtoStr(crv));
03507         return crv;
03508     }
03509 
03510     return crv;
03511 
03512 }
03513 
03514 CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
03515                 CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech, 
03516                 const CK_BYTE *  pData, CK_ULONG pDataLen) {
03517 
03518     CK_RV crv = CKR_OK;
03519 
03520     CK_BYTE hmac1[HMAC_MAX_LENGTH];
03521     CK_ULONG hmac1Len = 0;
03522     CK_BYTE hmac2[HMAC_MAX_LENGTH];
03523     CK_ULONG hmac2Len = 0;
03524 
03525     memset(hmac1, 0, sizeof(hmac1));
03526     memset(hmac2, 0, sizeof(hmac2));
03527     
03528     NUMTESTS++; /* increment NUMTESTS */
03529 
03530     crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey);
03531     if (crv == CKR_OK) {
03532         PKM_LogIt("C_SignInit succeeded\n");
03533     } else {
03534         PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, 
03535                    PKM_CK_RVtoStr(crv));
03536         return crv;
03537     }
03538 
03539     hmac1Len = sizeof(hmac1);
03540     crv = pFunctionList->C_Sign(hSession, (CK_BYTE * )pData,
03541                                 pDataLen,
03542                                 (CK_BYTE * )hmac1, &hmac1Len);
03543     if (crv == CKR_OK) {
03544         PKM_LogIt("C_Sign succeeded\n");
03545     } else {
03546         PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, 
03547                    PKM_CK_RVtoStr(crv));
03548         return crv;
03549     }
03550 
03551     crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey);
03552     if (crv == CKR_OK) {
03553         PKM_LogIt("C_SignInit succeeded\n");
03554     } else {
03555         PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, 
03556                    PKM_CK_RVtoStr(crv));
03557         return crv;
03558     }
03559 
03560     crv = pFunctionList->C_SignUpdate(hSession, (CK_BYTE * )pData,
03561                                       pDataLen);
03562     if (crv == CKR_OK) {
03563         PKM_LogIt("C_SignUpdate succeeded\n");
03564     } else {
03565         PKM_Error( "C_SignUpdate failed with 0x%08X, %-26s\n", crv, 
03566                    PKM_CK_RVtoStr(crv));
03567         return crv;
03568     }
03569 
03570     hmac2Len = sizeof(hmac2);
03571     crv = pFunctionList->C_SignFinal(hSession, (CK_BYTE * )hmac2, &hmac2Len);
03572     if (crv == CKR_OK) {
03573         PKM_LogIt("C_SignFinal succeeded\n");
03574     } else {
03575         PKM_Error( "C_SignFinal failed with 0x%08X, %-26s\n", crv, 
03576                    PKM_CK_RVtoStr(crv));
03577         return crv;
03578     }
03579 
03580     if ((hmac1Len == hmac2Len) && (memcmp(hmac1, hmac2, hmac1Len) == 0) ) {
03581         PKM_LogIt("hmacs are equal!\n");
03582     } else {
03583         PKM_Error("hmacs are not equal!\n");
03584     }
03585     crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey);
03586     if (crv != CKR_OK) {
03587         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
03588                    PKM_CK_RVtoStr(crv));
03589         return crv;
03590     }
03591     crv = pFunctionList->C_Verify(hSession, (CK_BYTE * )pData,
03592                                   pDataLen,
03593                                   (CK_BYTE * ) hmac2, hmac2Len);
03594     if (crv == CKR_OK) {
03595         PKM_LogIt("C_Verify of hmac succeeded\n");
03596     } else {
03597         PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv, 
03598                    PKM_CK_RVtoStr(crv));
03599         return crv;
03600     }
03601     crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey);
03602     if (crv != CKR_OK) {
03603         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
03604                    PKM_CK_RVtoStr(crv));
03605         return crv;
03606     }
03607     crv = pFunctionList->C_VerifyUpdate(hSession, (CK_BYTE * )pData,
03608                                   pDataLen);
03609     if (crv == CKR_OK) {
03610         PKM_LogIt("C_VerifyUpdate of hmac succeeded\n");
03611     } else {
03612         PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv, 
03613                    PKM_CK_RVtoStr(crv));
03614         return crv;
03615     }
03616     crv = pFunctionList->C_VerifyFinal(hSession, (CK_BYTE * ) hmac1, 
03617                                        hmac1Len);
03618     if (crv == CKR_OK) {
03619         PKM_LogIt("C_VerifyFinal of hmac succeeded\n");
03620     } else {
03621         PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, 
03622                    PKM_CK_RVtoStr(crv));
03623         return crv;
03624     }
03625     return crv;
03626 }
03627 
03628 CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,
03629                          CK_SLOT_ID * pSlotList, CK_ULONG slotID,
03630                          CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
03631     CK_RV crv = CKR_OK;
03632 
03633     CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
03634     CK_SESSION_INFO sinfo;
03635     CK_ATTRIBUTE_PTR pTemplate;
03636     CK_ULONG tnObjects = 0;
03637     
03638     NUMTESTS++; /* increment NUMTESTS */
03639 
03640     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
03641                                        NULL, NULL, &h);
03642     if ( CKR_OK != crv ) {
03643         PKM_Error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
03644                   "returned 0x%08X, %-26s\n", pSlotList[slotID], crv, 
03645                   PKM_CK_RVtoStr(crv));
03646         return crv;
03647     }
03648 
03649     PKM_LogIt( "    Opened a session: handle = 0x%08x\n", h);
03650 
03651     (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO));
03652     crv = pFunctionList->C_GetSessionInfo(h, &sinfo);
03653     if ( CKR_OK != crv ) {
03654         PKM_LogIt( "C_GetSessionInfo(%lu, ) returned 0x%08X, %-26s\n", h, crv, 
03655                    PKM_CK_RVtoStr(crv));
03656         return crv;
03657     }
03658 
03659     PKM_LogIt( "    SESSION INFO:\n");
03660     PKM_LogIt( "        slotID = %lu\n", sinfo.slotID);
03661     PKM_LogIt( "        state = %lu\n", sinfo.state);
03662     PKM_LogIt( "        flags = 0x%08x\n", sinfo.flags);
03663 #ifdef CKF_EXCLUSIVE_SESSION
03664     PKM_LogIt( "            -> EXCLUSIVE SESSION = %s\n", sinfo.flags &
03665                CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE");
03666 #endif /* CKF_EXCLUSIVE_SESSION */
03667     PKM_LogIt( "            -> RW SESSION = %s\n", sinfo.flags &
03668                CKF_RW_SESSION ? "TRUE" : "FALSE");
03669     PKM_LogIt( "            -> SERIAL SESSION = %s\n", sinfo.flags &
03670                CKF_SERIAL_SESSION ? "TRUE" : "FALSE");
03671 #ifdef CKF_INSERTION_CALLBACK
03672     PKM_LogIt( "            -> INSERTION CALLBACK = %s\n", sinfo.flags &
03673                CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE");
03674 #endif /* CKF_INSERTION_CALLBACK */
03675     PKM_LogIt( "        ulDeviceError = %lu\n", sinfo.ulDeviceError);
03676     PKM_LogIt( "\n");
03677 
03678     crv = pFunctionList->C_FindObjectsInit(h, NULL, 0);
03679     if ( CKR_OK != crv ) {
03680         PKM_LogIt( "C_FindObjectsInit(%lu, NULL, 0) returned "
03681                    "0x%08X, %-26s\n",
03682                    h, crv, PKM_CK_RVtoStr(crv));
03683         return crv;
03684     }
03685 
03686     pTemplate = (CK_ATTRIBUTE_PTR)calloc(number_of_all_known_attribute_types,
03687                                          sizeof(CK_ATTRIBUTE));
03688     if ( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
03689         PKM_Error(  "[memory allocation of %lu bytes failed]\n",
03690                     number_of_all_known_attribute_types *
03691                     sizeof(CK_ATTRIBUTE));
03692         return crv;
03693     }
03694 
03695     PKM_LogIt( "    All objects:\n");
03696 
03697     while (1) {
03698         CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
03699         CK_ULONG nObjects = 0;
03700         CK_ULONG k;
03701         CK_ULONG nAttributes = 0;
03702         CK_ATTRIBUTE_PTR pT2;
03703         CK_ULONG l;
03704 
03705         crv = pFunctionList->C_FindObjects(h, &o, 1, &nObjects);
03706         if ( CKR_OK != crv ) {
03707             PKM_Error(  "C_FindObjects(%lu, , 1, ) returned 0x%08X, %-26s\n", 
03708                         h, crv, PKM_CK_RVtoStr(crv));
03709             return crv;
03710         }
03711 
03712         if ( 0 == nObjects ) {
03713             PKM_LogIt( "\n");
03714             break;
03715         }
03716 
03717         tnObjects++;
03718 
03719         PKM_LogIt( "        OBJECT HANDLE %lu:\n", o);
03720 
03721         for ( k = 0; k < (CK_ULONG)number_of_all_known_attribute_types; k++ ) {
03722             pTemplate[k].type = all_known_attribute_types[k];
03723             pTemplate[k].pValue = (CK_VOID_PTR) NULL;
03724             pTemplate[k].ulValueLen = 0;
03725         }
03726 
03727         crv = pFunctionList->C_GetAttributeValue(h, o, pTemplate,
03728                                        number_of_all_known_attribute_types);
03729         switch ( crv ) {
03730         case CKR_OK:
03731         case CKR_ATTRIBUTE_SENSITIVE:
03732         case CKR_ATTRIBUTE_TYPE_INVALID:
03733         case CKR_BUFFER_TOO_SMALL:
03734             break;
03735         default:
03736             PKM_Error(  "C_GetAtributeValue(%lu, %lu, {all attribute types},"
03737                         "%lu) returned 0x%08X, %-26s\n",
03738                         h, o, number_of_all_known_attribute_types, crv, 
03739                         PKM_CK_RVtoStr(crv));
03740             return crv;
03741         }
03742 
03743         for ( k = 0; k < (CK_ULONG) number_of_all_known_attribute_types; k++) {
03744             if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
03745                 nAttributes++;
03746             }
03747         }
03748 
03749         if ( 1 ) {
03750             PKM_LogIt( "            %lu attributes:\n", nAttributes);
03751             for ( k = 0; k < (CK_ULONG) number_of_all_known_attribute_types;
03752                 k++ ) {
03753                 if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
03754                     PKM_LogIt( "                0x%08x (len = %lu)\n",
03755                                pTemplate[k].type,
03756                                pTemplate[k].ulValueLen);
03757                 }
03758             }
03759             PKM_LogIt( "\n");
03760         }
03761 
03762         pT2 = (CK_ATTRIBUTE_PTR)calloc(nAttributes, sizeof(CK_ATTRIBUTE));
03763         if ( (CK_ATTRIBUTE_PTR)NULL == pT2 ) {
03764             PKM_Error(  "[memory allocation of %lu bytes failed]\n",
03765                         nAttributes * sizeof(CK_ATTRIBUTE));
03766             return crv;
03767         }
03768 
03769         for ( l = 0, k = 0; k < (CK_ULONG) number_of_all_known_attribute_types;
03770             k++ ) {
03771             if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
03772                 pT2[l].type = pTemplate[k].type;
03773                 pT2[l].ulValueLen = pTemplate[k].ulValueLen;
03774                 pT2[l].pValue = (CK_VOID_PTR)malloc(pT2[l].ulValueLen);
03775                 if ( (CK_VOID_PTR)NULL == pT2[l].pValue ) {
03776                     PKM_Error(  "[memory allocation of %lu bytes failed]\n",
03777                                 pT2[l].ulValueLen);
03778                     return crv;
03779                 }
03780                 l++;
03781             }
03782         }
03783 
03784         assert( l == nAttributes );
03785 
03786         crv = pFunctionList->C_GetAttributeValue(h, o, pT2, nAttributes);
03787         switch ( crv ) {
03788         case CKR_OK:
03789         case CKR_ATTRIBUTE_SENSITIVE:
03790         case CKR_ATTRIBUTE_TYPE_INVALID:
03791         case CKR_BUFFER_TOO_SMALL:
03792             break;
03793         default:
03794             PKM_Error(  "C_GetAtributeValue(%lu, %lu, {existant attribute"
03795                         " types}, %lu) returned 0x%08X, %-26s\n",
03796                         h, o, nAttributes, crv, PKM_CK_RVtoStr(crv));
03797             return crv;
03798         }
03799 
03800         for ( l = 0; l < nAttributes; l++ ) {
03801             PKM_LogIt( "            type = 0x%08x, len = %ld", pT2[l].type,
03802                        (CK_LONG)pT2[l].ulValueLen);
03803             if ( -1 == (CK_LONG)pT2[l].ulValueLen ) {
03804                 ;
03805             } else {
03806                 CK_ULONG m;
03807 
03808                 if ( pT2[l].ulValueLen <= 8 ) {
03809                     PKM_LogIt( ", value = ");
03810                 } else {
03811                     PKM_LogIt( ", value = \n                ");
03812                 }
03813 
03814                 for ( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
03815                     PKM_LogIt( "%02x", (CK_ULONG)(0xff &
03816                               ((CK_CHAR_PTR)pT2[l].pValue)[m]));
03817                 }
03818 
03819                 PKM_LogIt( " ");
03820 
03821                 for ( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
03822                     CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m];
03823                     if ( (c < 0x20) || (c >= 0x7f) ) {
03824                         c = '.';
03825                     }
03826                     PKM_LogIt( "%c", c);
03827                 }
03828             }
03829 
03830             PKM_LogIt( "\n");
03831         }
03832 
03833         PKM_LogIt( "\n");
03834 
03835         for ( l = 0; l < nAttributes; l++ ) {
03836             free(pT2[l].pValue);
03837         }
03838         free(pT2);
03839     } /* while(1) */
03840 
03841     crv = pFunctionList->C_FindObjectsFinal(h);
03842     if ( CKR_OK != crv ) {
03843         PKM_Error(  "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h, crv, 
03844                     PKM_CK_RVtoStr(crv));
03845         return crv;
03846     }
03847 
03848     PKM_LogIt( "    (%lu objects total)\n", tnObjects);
03849 
03850     crv = pFunctionList->C_CloseSession(h);
03851     if ( CKR_OK != crv ) {
03852         PKM_Error(  "C_CloseSession(%lu) returned 0x%08X, %-26s\n", h, crv, 
03853                     PKM_CK_RVtoStr(crv));
03854         return crv;
03855     }
03856 
03857     return crv;
03858 }
03859 /* session to create, find, and delete a couple session objects */
03860 CK_RV PKM_MultiObjectManagement (CK_FUNCTION_LIST_PTR pFunctionList,
03861                                  CK_SLOT_ID * pSlotList, CK_ULONG slotID,
03862                                  CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
03863 
03864     CK_RV crv = CKR_OK;
03865 
03866     CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
03867     CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0;
03868     CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1];
03869     CK_OBJECT_CLASS cko_data = CKO_DATA;
03870     char *key = "TEST PROGRAM";
03871     CK_ULONG key_len = 0; 
03872     CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0;
03873     CK_OBJECT_HANDLE hTwoIn = (CK_OBJECT_HANDLE)0;
03874     CK_OBJECT_HANDLE hThreeIn = (CK_OBJECT_HANDLE)0;
03875     CK_OBJECT_HANDLE hDeltaIn = (CK_OBJECT_HANDLE)0;
03876     CK_OBJECT_HANDLE found[10];
03877     CK_ULONG nFound;
03878     CK_ULONG   hDeltaLen, hThreeLen = 0;
03879 
03880     CK_TOKEN_INFO tinfo;
03881     
03882     NUMTESTS++; /* increment NUMTESTS */
03883     key_len = sizeof(key);
03884     crv = pFunctionList->C_OpenSession(pSlotList[slotID],
03885                                        CKF_SERIAL_SESSION, NULL, NULL, &h);
03886     if ( CKR_OK != crv ) {
03887         PKM_Error(  "C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
03888                     "returned 0x%08X, %-26s\n", pSlotList[slotID], crv, 
03889                     PKM_CK_RVtoStr(crv));
03890         return crv;
03891     }
03892     crv = pFunctionList->C_Login(h, CKU_USER, pwd, pwdLen);
03893     if (crv == CKR_OK) {
03894         PKM_LogIt("C_Login with correct password succeeded\n");
03895     } else {
03896         PKM_Error( "C_Login with correct password failed "
03897                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
03898         return crv;
03899     }
03900 
03901 
03902     (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
03903     crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tinfo);
03904     if ( CKR_OK != crv ) {
03905         PKM_Error("C_GetTokenInfo(%lu, ) returned 0x%08X, %-26s\n",
03906                   pSlotList[slotID], crv, PKM_CK_RVtoStr(crv));
03907         return crv;
03908     }
03909 
03910 
03911     PKM_LogIt( "    Opened a session: handle = 0x%08x\n", h);
03912 
03913     one[0].type = CKA_CLASS;
03914     one[0].pValue = &cko_data;
03915     one[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
03916     one[1].type = CKA_TOKEN;
03917     one[1].pValue = &false;
03918     one[1].ulValueLen = sizeof(CK_BBOOL);
03919     one[2].type = CKA_PRIVATE;
03920     one[2].pValue = &false;
03921     one[2].ulValueLen = sizeof(CK_BBOOL);
03922     one[3].type = CKA_MODIFIABLE;
03923     one[3].pValue = &true;
03924     one[3].ulValueLen = sizeof(CK_BBOOL);
03925     one[4].type = CKA_LABEL;
03926     one[4].pValue = "Test data object one";
03927     one[4].ulValueLen = strlen(one[4].pValue);
03928     one[5].type = CKA_APPLICATION;
03929     one[5].pValue = key;
03930     one[5].ulValueLen = key_len;
03931     one[6].type = CKA_VALUE;
03932     one[6].pValue = "Object one";
03933     one[6].ulValueLen = strlen(one[6].pValue);
03934 
03935     two[0].type = CKA_CLASS;
03936     two[0].pValue = &cko_data;
03937     two[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
03938     two[1].type = CKA_TOKEN;
03939     two[1].pValue = &false;
03940     two[1].ulValueLen = sizeof(CK_BBOOL);
03941     two[2].type = CKA_PRIVATE;
03942     two[2].pValue = &false;
03943     two[2].ulValueLen = sizeof(CK_BBOOL);
03944     two[3].type = CKA_MODIFIABLE;
03945     two[3].pValue = &true;
03946     two[3].ulValueLen = sizeof(CK_BBOOL);
03947     two[4].type = CKA_LABEL;
03948     two[4].pValue = "Test data object two";
03949     two[4].ulValueLen = strlen(two[4].pValue);
03950     two[5].type = CKA_APPLICATION;
03951     two[5].pValue = key;
03952     two[5].ulValueLen = key_len;
03953     two[6].type = CKA_VALUE;
03954     two[6].pValue = "Object two";
03955     two[6].ulValueLen = strlen(two[6].pValue);
03956 
03957     three[0].type = CKA_CLASS;
03958     three[0].pValue = &cko_data;
03959     three[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
03960     three[1].type = CKA_TOKEN;
03961     three[1].pValue = &false;
03962     three[1].ulValueLen = sizeof(CK_BBOOL);
03963     three[2].type = CKA_PRIVATE;
03964     three[2].pValue = &false;
03965     three[2].ulValueLen = sizeof(CK_BBOOL);
03966     three[3].type = CKA_MODIFIABLE;
03967     three[3].pValue = &true;
03968     three[3].ulValueLen = sizeof(CK_BBOOL);
03969     three[4].type = CKA_LABEL;
03970     three[4].pValue = "Test data object three";
03971     three[4].ulValueLen = strlen(three[4].pValue);
03972     three[5].type = CKA_APPLICATION;
03973     three[5].pValue = key;
03974     three[5].ulValueLen = key_len;
03975     three[6].type = CKA_VALUE;
03976     three[6].pValue = "Object three";
03977     three[6].ulValueLen = strlen(three[6].pValue);
03978 
03979     crv = pFunctionList->C_CreateObject(h, one, 7, &hOneIn);
03980     if ( CKR_OK != crv ) {
03981         PKM_Error(  "C_CreateObject(%lu, one, 7, ) returned 0x%08X, %-26s\n",
03982                     h, crv, PKM_CK_RVtoStr(crv));
03983         return crv;
03984     }
03985 
03986     PKM_LogIt( "    Created object one: handle = %lu\n", hOneIn);
03987 
03988     crv = pFunctionList->C_CreateObject(h, two, 7, &hTwoIn);
03989     if ( CKR_OK != crv ) {
03990         PKM_Error(  "C_CreateObject(%lu, two, 7, ) returned 0x%08X, %-26s\n",
03991                     h, crv, PKM_CK_RVtoStr(crv));
03992         return crv;
03993     }
03994 
03995     PKM_LogIt( "    Created object two: handle = %lu\n", hTwoIn);
03996 
03997     crv = pFunctionList->C_CreateObject(h, three, 7, &hThreeIn);
03998     if ( CKR_OK != crv ) {
03999         PKM_Error(  "C_CreateObject(%lu, three, 7, ) returned 0x%08x\n",
04000                     h, crv, PKM_CK_RVtoStr(crv));
04001         return crv;
04002     }
04003     crv = pFunctionList->C_GetObjectSize(h, hThreeIn, &hThreeLen);
04004     if (crv == CKR_OK) {
04005         PKM_LogIt("C_GetObjectSize succeeded\n");
04006     } else {
04007         PKM_Error("C_GetObjectSize failed "
04008                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04009         return crv;
04010     }
04011 
04012     PKM_LogIt( "    Created object three: handle = %lu\n", hThreeIn);
04013 
04014     delta[0].type = CKA_VALUE;
04015     delta[0].pValue = "Copied object";
04016     delta[0].ulValueLen = strlen(delta[0].pValue);
04017 
04018     crv = pFunctionList->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn);
04019     if ( CKR_OK != crv ) {
04020         PKM_Error(  "C_CopyObject(%lu, %lu, delta, 1, ) returned "
04021                     "0x%08X, %-26s\n",
04022                     h, hThreeIn, crv, PKM_CK_RVtoStr(crv));
04023         return crv;
04024     }
04025     crv = pFunctionList->C_GetObjectSize(h, hDeltaIn, &hDeltaLen);
04026     if (crv == CKR_OK) {
04027         PKM_LogIt("C_GetObjectSize succeeded\n");
04028     } else {
04029         PKM_Error("C_GetObjectSize failed "
04030                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04031         return crv;
04032     }
04033 
04034     if (hThreeLen == hDeltaLen) {
04035         PKM_LogIt("Copied object size same as orginal\n");
04036     } else {
04037         PKM_Error("Copied object different from original\n");
04038         return CKR_DEVICE_ERROR;
04039     }
04040 
04041     PKM_LogIt( "    Copied object three: new handle = %lu\n", hDeltaIn);
04042 
04043     mask[0].type = CKA_APPLICATION;
04044     mask[0].pValue = key;
04045     mask[0].ulValueLen = key_len;
04046 
04047     crv = pFunctionList->C_FindObjectsInit(h, mask, 1);
04048     if ( CKR_OK != crv ) {
04049         PKM_Error(  "C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n",
04050                     h, crv, PKM_CK_RVtoStr(crv));
04051         return crv;
04052     }
04053 
04054     (void)memset(&found, 0, sizeof(found));
04055     nFound = 0;
04056     crv = pFunctionList->C_FindObjects(h, found, 10, &nFound);
04057     if ( CKR_OK != crv ) {
04058         PKM_Error(  "C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n",
04059                     h, crv, PKM_CK_RVtoStr(crv));
04060         return crv;
04061     }
04062 
04063     if ( 4 != nFound ) {
04064         PKM_Error(  "Found %lu objects, not 4.\n", nFound);
04065         return crv;
04066     }
04067 
04068     PKM_LogIt( "    Found 4 objects: %lu, %lu, %lu, %lu\n",
04069                found[0], found[1], found[2], found[3]);
04070 
04071     crv = pFunctionList->C_FindObjectsFinal(h);
04072     if ( CKR_OK != crv ) {
04073         PKM_Error(  "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", 
04074                     h, crv, PKM_CK_RVtoStr(crv));
04075         return crv;
04076     }
04077 
04078     crv = pFunctionList->C_DestroyObject(h, hThreeIn);
04079     if ( CKR_OK != crv ) {
04080         PKM_Error(  "C_DestroyObject(%lu, %lu) returned 0x%08X, %-26s\n", h,
04081                     hThreeIn, crv, PKM_CK_RVtoStr(crv));
04082         return crv;
04083     }
04084 
04085     PKM_LogIt( "    Destroyed object three (handle = %lu)\n", hThreeIn);
04086 
04087     delta[0].type = CKA_APPLICATION;
04088     delta[0].pValue = "Changed application";
04089     delta[0].ulValueLen = strlen(delta[0].pValue);
04090 
04091     crv = pFunctionList->C_SetAttributeValue(h, hTwoIn, delta, 1);
04092     if ( CKR_OK != crv ) {
04093         PKM_Error("C_SetAttributeValue(%lu, %lu, delta, 1) returned "
04094                   "0x%08X, %-26s\n",
04095                   h, hTwoIn, crv, PKM_CK_RVtoStr(crv));
04096         return crv;
04097     }
04098 
04099     PKM_LogIt( "    Changed object two (handle = %lu).\n", hTwoIn);
04100 
04101     /* Can another session find these session objects? */
04102 
04103     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
04104                                        NULL, NULL, &h2);
04105     if ( CKR_OK != crv ) {
04106         PKM_Error(  "C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
04107                     " returned 0x%08X, %-26s\n", pSlotList[slotID], crv, 
04108                     PKM_CK_RVtoStr(crv));
04109         return crv;
04110     }
04111     PKM_LogIt( "    Opened a second session: handle = 0x%08x\n", h2);
04112 
04113     /* mask is still the same */
04114 
04115     crv = pFunctionList->C_FindObjectsInit(h2, mask, 1);
04116     if ( CKR_OK != crv ) {
04117         PKM_Error(  "C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n",
04118                     h2, crv, PKM_CK_RVtoStr(crv));
04119         return crv;
04120     }
04121 
04122     (void)memset(&found, 0, sizeof(found));
04123     nFound = 0;
04124     crv = pFunctionList->C_FindObjects(h2, found, 10, &nFound);
04125     if ( CKR_OK != crv ) {
04126         PKM_Error(  "C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n",
04127                     h2, crv, PKM_CK_RVtoStr(crv));
04128         return crv;
04129     }
04130 
04131     if ( 2 != nFound ) {
04132         PKM_Error(  "Found %lu objects, not 2.\n", nFound);
04133         return crv;
04134     }
04135 
04136     PKM_LogIt( "    Found 2 objects: %lu, %lu\n",
04137                found[0], found[1]);
04138 
04139     crv = pFunctionList->C_FindObjectsFinal(h2);
04140     if ( CKR_OK != crv ) {
04141         PKM_Error(  "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h2, crv, 
04142                     PKM_CK_RVtoStr(crv));
04143         return crv;
04144     }
04145     crv = pFunctionList->C_Logout(h);
04146     if (crv == CKR_OK) {
04147         PKM_LogIt("C_Logout succeeded\n");
04148     } else {
04149         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
04150                    PKM_CK_RVtoStr(crv));
04151         return crv;
04152     }
04153     crv = pFunctionList->C_CloseAllSessions(pSlotList[slotID]);
04154     if ( CKR_OK != crv ) {
04155         PKM_Error(  "C_CloseAllSessions(%lu) returned 0x%08X, %-26s\n",
04156                     pSlotList[slotID], crv, PKM_CK_RVtoStr(crv));
04157         return crv;
04158     }
04159 
04160     PKM_LogIt( "\n");
04161     return crv;
04162 }
04163 
04164 CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,
04165                            CK_SLOT_ID * pSlotList, CK_ULONG slotID,
04166                            CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
04167     CK_SESSION_HANDLE hSession;
04168     CK_RV crv = CKR_OK;
04169     CK_MECHANISM sAESKeyMech = {
04170         CKM_AES_KEY_GEN, NULL, 0
04171     };
04172     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
04173     CK_KEY_TYPE keyAESType = CKK_AES;
04174     CK_UTF8CHAR AESlabel[] = "An AES secret key object";
04175     CK_ULONG AESvalueLen = 16;
04176     CK_ATTRIBUTE sAESKeyTemplate[9];    
04177     CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE;
04178     CK_BYTE_PTR     pstate = NULL;
04179     CK_ULONG statelen, digestlen, plainlen, plainlen_1, plainlen_2, slen;
04180 
04181     static const CK_UTF8CHAR *plaintext = (CK_UTF8CHAR *)"Firefox rules.";
04182     static const CK_UTF8CHAR *plaintext_1 = (CK_UTF8CHAR *)"Thunderbird rules.";
04183     static const CK_UTF8CHAR *plaintext_2 = (CK_UTF8CHAR *)
04184                                             "Firefox and Thunderbird.";
04185 
04186     char    digest[MAX_DIGEST_SZ], digest_1[MAX_DIGEST_SZ];
04187     char    sign[MAX_SIG_SZ];
04188     CK_MECHANISM signmech;
04189     CK_MECHANISM digestmech;
04190 
04191     NUMTESTS++; /* increment NUMTESTS */
04192 
04193 
04194     /* AES key template */
04195     sAESKeyTemplate[0].type       = CKA_CLASS; 
04196     sAESKeyTemplate[0].pValue     = &class;
04197     sAESKeyTemplate[0].ulValueLen = sizeof(class);
04198     sAESKeyTemplate[1].type       = CKA_KEY_TYPE; 
04199     sAESKeyTemplate[1].pValue     = &keyAESType; 
04200     sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
04201     sAESKeyTemplate[2].type       = CKA_LABEL;
04202     sAESKeyTemplate[2].pValue     = AESlabel; 
04203     sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1;
04204     sAESKeyTemplate[3].type       = CKA_ENCRYPT; 
04205     sAESKeyTemplate[3].pValue     = &true; 
04206     sAESKeyTemplate[3].ulValueLen = sizeof(true);
04207     sAESKeyTemplate[4].type       = CKA_DECRYPT; 
04208     sAESKeyTemplate[4].pValue     = &true; 
04209     sAESKeyTemplate[4].ulValueLen = sizeof(true);
04210     sAESKeyTemplate[5].type       = CKA_SIGN; 
04211     sAESKeyTemplate[5].pValue     = &true; 
04212     sAESKeyTemplate[5].ulValueLen = sizeof (true);
04213     sAESKeyTemplate[6].type       = CKA_VERIFY; 
04214     sAESKeyTemplate[6].pValue     = &true; 
04215     sAESKeyTemplate[6].ulValueLen = sizeof(true);
04216     sAESKeyTemplate[7].type       = CKA_UNWRAP; 
04217     sAESKeyTemplate[7].pValue     = &true; 
04218     sAESKeyTemplate[7].ulValueLen = sizeof(true);
04219     sAESKeyTemplate[8].type       = CKA_VALUE_LEN; 
04220     sAESKeyTemplate[8].pValue     = &AESvalueLen; 
04221     sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
04222 
04223     signmech.mechanism = CKM_SHA_1_HMAC;
04224     signmech.pParameter = NULL;
04225     signmech.ulParameterLen = 0;
04226     digestmech.mechanism = CKM_SHA256;
04227     digestmech.pParameter = NULL;
04228     digestmech.ulParameterLen = 0;
04229 
04230 
04231     plainlen = strlen((char *)plaintext);
04232     plainlen_1 = strlen((char *)plaintext_1);
04233     plainlen_2 = strlen((char *)plaintext_2);
04234     digestlen = MAX_DIGEST_SZ;
04235 
04236 
04237     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
04238                                        NULL, NULL, &hSession);
04239     if (crv != CKR_OK) {
04240         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
04241                    PKM_CK_RVtoStr(crv));
04242         return crv;
04243     }
04244 
04245     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
04246     if (crv == CKR_OK) {
04247         PKM_LogIt("C_Login with correct password succeeded\n");
04248     } else {
04249         PKM_Error( "C_Login with correct password failed "
04250                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04251         return crv;
04252     }
04253 
04254     PKM_LogIt("Generate an AES key ...\n");
04255     /* generate an AES Secret Key */
04256     crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech,
04257                                        sAESKeyTemplate,
04258                                        NUM_ELEM(sAESKeyTemplate),
04259                                        &sKey);
04260     if (crv == CKR_OK) {
04261         PKM_LogIt("C_GenerateKey AES succeeded\n");
04262     } else {
04263         PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n", 
04264                    crv, PKM_CK_RVtoStr(crv));
04265         return crv;
04266     }
04267 
04268     crv = pFunctionList->C_SignInit(hSession, &signmech, sKey);
04269     if (crv != CKR_OK) {
04270         PKM_Error("C_SignInit failed returned 0x%08X, %-26s\n", crv, 
04271                   PKM_CK_RVtoStr(crv));
04272         return crv;
04273     }
04274 
04275     slen = sizeof(sign);
04276     crv = pFunctionList->C_Sign(hSession, (CK_BYTE_PTR)plaintext, plainlen,
04277                                 (CK_BYTE_PTR)sign, &slen);
04278     if (crv != CKR_OK) {
04279         PKM_Error("C_Sign failed returned 0x%08X, %-26s\n", crv, 
04280                   PKM_CK_RVtoStr(crv));
04281         return crv;
04282     }
04283 
04284     crv = pFunctionList->C_DestroyObject(hSession, sKey);
04285     if (crv != CKR_OK) {
04286         PKM_Error("C_DestroyObject failed returned 0x%08X, %-26s\n", crv, 
04287                   PKM_CK_RVtoStr(crv));
04288         return crv;
04289     }
04290 
04291     digestlen = MAX_DIGEST_SZ;
04292     crv = pFunctionList->C_DigestInit(hSession, &digestmech);
04293     if (crv != CKR_OK) {
04294         PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv, 
04295                   PKM_CK_RVtoStr(crv));
04296         return crv;
04297     }
04298     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext,
04299                                         plainlen);
04300     if (crv != CKR_OK) {
04301         PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv, 
04302                   PKM_CK_RVtoStr(crv));
04303         return crv;
04304     }
04305 
04306     crv = pFunctionList->C_GetOperationState(hSession, NULL, &statelen);
04307     if (crv != CKR_OK) {
04308         PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv, 
04309                   PKM_CK_RVtoStr(crv));
04310         return crv;
04311     }
04312 
04313     pstate = (CK_BYTE_PTR) malloc(statelen * sizeof (CK_BYTE_PTR));
04314     crv = pFunctionList->C_GetOperationState(hSession, pstate, &statelen);
04315     if (crv != CKR_OK) {
04316         PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv, 
04317                   PKM_CK_RVtoStr(crv));
04318         return crv;
04319     }
04320 
04321     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_1,
04322                                         plainlen_1);
04323     if (crv != CKR_OK) {
04324         PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv, 
04325                   PKM_CK_RVtoStr(crv));
04326         return crv;
04327     }
04328     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_2,
04329                                         plainlen_2);
04330     if (crv != CKR_OK) {
04331         PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv, 
04332                   PKM_CK_RVtoStr(crv));
04333         return crv;
04334     }
04335 
04336     /*
04337      *      This will override/negate the above 2 digest_update
04338      *      operations
04339      */
04340     crv = pFunctionList->C_SetOperationState(hSession, pstate, statelen,
04341                                              0, 0);
04342     if (crv != CKR_OK) {
04343         PKM_Error("C_SetOperationState failed returned 0x%08X, %-26s\n", crv, 
04344                   PKM_CK_RVtoStr(crv));
04345         return crv;
04346     }
04347     crv = pFunctionList->C_DigestFinal(hSession, (CK_BYTE_PTR)digest,
04348                                        &digestlen);
04349     if (crv != CKR_OK) {
04350         PKM_Error("C_DigestFinal failed returned 0x%08X, %-26s\n", crv, 
04351                   PKM_CK_RVtoStr(crv));
04352         return crv;
04353     }
04354     digestlen = MAX_DIGEST_SZ;
04355     crv = pFunctionList->C_DigestInit(hSession, &digestmech);
04356     if (crv != CKR_OK) {
04357         PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv, 
04358                   PKM_CK_RVtoStr(crv));
04359         return crv;
04360     }
04361     crv = pFunctionList->C_Digest(hSession, (CK_BYTE_PTR)plaintext, plainlen,
04362                                   (CK_BYTE_PTR)digest_1, &digestlen);
04363     if (crv != CKR_OK) {
04364         PKM_Error("C_Digest failed returned 0x%08X, %-26s\n", crv, 
04365                   PKM_CK_RVtoStr(crv));
04366         return crv;
04367     }
04368     if (memcmp(digest, digest_1, digestlen) == 0) {
04369         PKM_LogIt("Digest and digest_1 are equal!\n");
04370     } else {
04371         PKM_Error("Digest and digest_1 are not equal!\n");
04372     }
04373     crv = pFunctionList->C_Logout(hSession);
04374     if (crv == CKR_OK) {
04375         PKM_LogIt("C_Logout succeeded\n");
04376     } else {
04377         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
04378                    PKM_CK_RVtoStr(crv));
04379         return crv;
04380     }
04381     crv = pFunctionList->C_CloseSession(hSession);
04382     if ( CKR_OK != crv ) {
04383         PKM_Error(  "C_CloseSession(%lu) returned 0x%08X, %-26s\n", 
04384                     hSession, crv, PKM_CK_RVtoStr(crv));
04385         return crv;
04386     }
04387 
04388     return crv;
04389 }
04390 
04391 
04392 /*
04393 * Recover Functions
04394 */
04395 CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList, 
04396                     CK_SESSION_HANDLE hSession,
04397                     CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
04398                     CK_MECHANISM *signMech, const CK_BYTE * pData, 
04399                     CK_ULONG pDataLen) {
04400     CK_RV crv = CKR_OK;
04401     CK_BYTE sig[MAX_SIG_SZ];
04402     CK_ULONG sigLen = MAX_SIG_SZ;
04403     CK_BYTE recover[MAX_SIG_SZ];
04404     CK_ULONG recoverLen = MAX_SIG_SZ;
04405     
04406     NUMTESTS++; /* increment NUMTESTS */
04407     
04408     /* initializes a signature operation,
04409      *  where the data can be recovered from the signature
04410      */
04411     crv = pFunctionList->C_SignRecoverInit(hSession, signMech,
04412                                            hPrivKey);
04413     if (crv == CKR_OK) {
04414         PKM_LogIt("C_SignRecoverInit succeeded. \n");
04415     } else {
04416         PKM_Error("C_SignRecoverInit failed.\n"
04417                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04418         return crv;
04419     }
04420 
04421     /* signs single-part data,
04422      * where the data can be recovered from the signature
04423      */
04424     crv = pFunctionList->C_SignRecover(hSession, (CK_BYTE * )pData,
04425                                        pDataLen,
04426                                        (CK_BYTE * )sig, &sigLen);
04427     if (crv == CKR_OK) {
04428         PKM_LogIt("C_SignRecover succeeded. \n");
04429     } else {
04430         PKM_Error("C_SignRecoverInit failed to create an RSA key pair.\n"
04431                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04432         return crv;
04433     }
04434 
04435     /*
04436      * initializes a verification operation
04437      *where the data is recovered from the signature
04438      */
04439     crv = pFunctionList->C_VerifyRecoverInit(hSession, signMech,
04440                                              hPubKey);
04441     if (crv == CKR_OK) {
04442         PKM_LogIt("C_VerifyRecoverInit succeeded. \n");
04443     } else {
04444         PKM_Error("C_VerifyRecoverInit failed.\n"
04445                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04446         return crv;
04447     }
04448 
04449     /*
04450     * verifies a signature on single-part data,
04451     * where the data is recovered from the signature
04452     */
04453     crv = pFunctionList->C_VerifyRecover(hSession, (CK_BYTE * )sig,
04454                                          sigLen,
04455                                          (CK_BYTE * )recover, &recoverLen);
04456     if (crv == CKR_OK) {
04457         PKM_LogIt("C_VerifyRecover succeeded. \n");
04458     } else {
04459         PKM_Error("C_VerifyRecover failed.\n"
04460                   "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04461         return crv;
04462     }
04463 
04464     if ((recoverLen == pDataLen)
04465         && (memcmp(recover, pData, pDataLen) == 0)) {
04466         PKM_LogIt("VerifyRecover test case passed\n");
04467     } else {
04468         PKM_Error( "VerifyRecover test case failed\n");
04469     }
04470 
04471     return crv;
04472 }
04473 /*
04474 * wrapUnwrap
04475 * wrap the secretkey with the public key.
04476 * unwrap the secretkey with the private key.
04477 */
04478 CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,
04479                      CK_SESSION_HANDLE hSession, 
04480                      CK_OBJECT_HANDLE hPublicKey, 
04481                      CK_OBJECT_HANDLE hPrivateKey,
04482                      CK_MECHANISM *wrapMechanism,
04483                      CK_OBJECT_HANDLE hSecretKey,
04484                      CK_ATTRIBUTE *sKeyTemplate,
04485                      CK_ULONG skeyTempSize) {
04486     CK_RV crv = CKR_OK;
04487     CK_OBJECT_HANDLE hSecretKeyUnwrapped = CK_INVALID_HANDLE;
04488     CK_BYTE wrappedKey[128];
04489     CK_ULONG ulWrappedKeyLen = 0;
04490 
04491     NUMTESTS++; /* increment NUMTESTS */
04492 
04493     ulWrappedKeyLen = sizeof(wrappedKey);
04494     crv = pFunctionList->C_WrapKey(
04495                                   hSession, wrapMechanism,
04496                                   hPublicKey, hSecretKey,
04497                                   wrappedKey, &ulWrappedKeyLen);
04498     if (crv == CKR_OK) {
04499         PKM_LogIt("C_WrapKey succeeded\n");
04500     } else {
04501         PKM_Error( "C_WrapKey failed with 0x%08X, %-26s\n", crv, 
04502                    PKM_CK_RVtoStr(crv));
04503         return crv;
04504     }
04505     crv = pFunctionList->C_UnwrapKey(
04506                                     hSession, wrapMechanism, hPrivateKey,
04507                                     wrappedKey, ulWrappedKeyLen, sKeyTemplate,
04508                                     skeyTempSize,
04509                                     &hSecretKeyUnwrapped);
04510     if ((crv == CKR_OK) && (hSecretKeyUnwrapped != CK_INVALID_HANDLE)) {
04511         PKM_LogIt("C_UnwrapKey succeeded\n");
04512     } else {
04513         PKM_Error( "C_UnwrapKey failed with 0x%08X, %-26s\n", crv, 
04514                    PKM_CK_RVtoStr(crv));
04515         return crv;
04516     }
04517 
04518     return crv;
04519 }
04520 
04521 /*
04522  * Tests if the object's attributes match the expected_attrs
04523  */
04524 CK_RV
04525 PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,
04526                    CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj,
04527                    CK_ATTRIBUTE_PTR expected_attrs,
04528                    CK_ULONG expected_attrs_count)
04529 {
04530     CK_RV crv;
04531     CK_ATTRIBUTE_PTR tmp_attrs;
04532     unsigned int i;
04533     
04534     NUMTESTS++; /* increment NUMTESTS */
04535 
04536     /* First duplicate the themplate */
04537     tmp_attrs = malloc(expected_attrs_count * sizeof (CK_ATTRIBUTE));
04538 
04539     if (tmp_attrs == NULL) {
04540         PKM_Error("Internal test memory failure\n");
04541         return (CKR_HOST_MEMORY);
04542     }
04543 
04544     for (i = 0; i < expected_attrs_count; i++) {
04545         tmp_attrs[i].type = expected_attrs[i].type;
04546         tmp_attrs[i].ulValueLen = expected_attrs[i].ulValueLen;
04547 
04548         /* Don't give away the expected one. just zeros */
04549         tmp_attrs[i].pValue = calloc(expected_attrs[i].ulValueLen, 1);
04550 
04551         if (tmp_attrs[i].pValue == NULL) {
04552             unsigned int j;
04553             for (j = 0; j < i; j++)
04554                 free(tmp_attrs[j].pValue);
04555 
04556             free(tmp_attrs);
04557             printf("Internal test memory failure\n");
04558             return (CKR_HOST_MEMORY);
04559         }
04560     }
04561 
04562     /* then get the attributes from the object */
04563     crv = pFunctionList->C_GetAttributeValue(hSession, obj, tmp_attrs,
04564                                              expected_attrs_count);
04565     if (crv != CKR_OK) {
04566         PKM_Error( "C_GetAttributeValue failed with 0x%08X, %-26s\n", crv, 
04567                    PKM_CK_RVtoStr(crv));
04568         crv = CKR_FUNCTION_FAILED;
04569         goto out;
04570     }
04571 
04572     /* Finally compare with the expected ones */
04573     for (i = 0; i < expected_attrs_count; i++) {
04574 
04575         if (memcmp(tmp_attrs[i].pValue, expected_attrs[i].pValue,
04576                    expected_attrs[i].ulValueLen) != 0) {
04577         PKM_LogIt("comparing attribute type 0x%x with expected  0x%x\n",
04578                       tmp_attrs[i].type, expected_attrs[i].type);
04579         PKM_LogIt("comparing attribute type value 0x%x with expected 0x%x\n",
04580                       tmp_attrs[i].pValue, expected_attrs[i].pValue);
04581         /* don't report error at this time */
04582         }
04583     }
04584 
04585     out:
04586     for (i = 0; i < expected_attrs_count; i++)
04587         free(tmp_attrs[i].pValue);
04588     free(tmp_attrs);
04589     return (crv);
04590 }
04591 
04592 /*
04593  * Check the validity of a mech
04594  */
04595 CK_RV
04596 PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
04597               CK_MECHANISM_TYPE mechType, CK_FLAGS flags,
04598               CK_BBOOL check_sizes, CK_ULONG minkeysize, CK_ULONG maxkeysize)
04599 {
04600     CK_SESSION_INFO         sess_info;
04601     CK_MECHANISM_INFO       mech_info;
04602     CK_RV                   crv;
04603 
04604     NUMTESTS++; /* increment NUMTESTS */
04605 
04606     if ((crv = pFunctionList->C_GetSessionInfo(hSession, &sess_info))
04607         != CKR_OK) {
04608         PKM_Error( "C_GetSessionInfo failed with 0x%08X, %-26s\n", crv, 
04609                    PKM_CK_RVtoStr(crv));
04610         return (CKR_FUNCTION_FAILED);
04611     }
04612 
04613     crv = pFunctionList->C_GetMechanismInfo(0, mechType,
04614                                             &mech_info);
04615 
04616 
04617     crv = pFunctionList->C_GetMechanismInfo(sess_info.slotID, mechType,
04618                                             &mech_info);
04619 
04620     if (crv != CKR_OK) {
04621         PKM_Error( "C_GetMechanismInfo failed with 0x%08X, %-26s\n", crv, 
04622                    PKM_CK_RVtoStr(crv));
04623         return (CKR_FUNCTION_FAILED);
04624     }
04625 
04626     if ((mech_info.flags & flags) == 0) {
04627         PKM_Error("0x%x flag missing from mech\n", flags);
04628         return (CKR_MECHANISM_INVALID);
04629     }
04630     if (!check_sizes)
04631         return (CKR_OK);
04632 
04633     if (mech_info.ulMinKeySize != minkeysize) {
04634         PKM_Error("Bad MinKeySize %d expected %d\n", mech_info.ulMinKeySize,
04635                   minkeysize);
04636         return (CKR_MECHANISM_INVALID);
04637     }
04638     if (mech_info.ulMaxKeySize != maxkeysize) {
04639         PKM_Error("Bad MaxKeySize %d expected %d\n", mech_info.ulMaxKeySize,
04640                   maxkeysize);
04641         return (CKR_MECHANISM_INVALID);
04642     }
04643     return (CKR_OK);
04644 }
04645 
04646 
04647 
04648 
04649 
04650 /*
04651  * Can be called with a non-null premaster_key_len for the
04652  * *_DH mechanisms. In that case, no checking for the matching of
04653  * the expected results is done.
04654  * The rnd argument tells which correct/bogus randomInfo to use.
04655  */
04656 CK_RV
04657 PKM_TLSMasterKeyDerive( CK_FUNCTION_LIST_PTR pFunctionList,
04658                         CK_SLOT_ID * pSlotList, CK_ULONG slotID,
04659                         CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
04660                         CK_MECHANISM_TYPE mechType,
04661                         enum_random_t rnd)  {
04662     CK_SESSION_HANDLE hSession;
04663     CK_RV crv;
04664     CK_MECHANISM            mk_mech;
04665     CK_VERSION              expected_version, version;
04666     CK_OBJECT_CLASS         class = CKO_SECRET_KEY;
04667     CK_KEY_TYPE             type = CKK_GENERIC_SECRET;
04668     CK_BBOOL                derive_bool = true;
04669     CK_ATTRIBUTE            attrs[4];
04670     CK_ULONG                attrs_count = 4;
04671     CK_OBJECT_HANDLE        pmk_obj = CK_INVALID_HANDLE;
04672     CK_OBJECT_HANDLE        mk_obj = CK_INVALID_HANDLE;
04673     CK_SSL3_MASTER_KEY_DERIVE_PARAMS mkd_params;
04674     CK_MECHANISM            skmd_mech;
04675 
04676     CK_BBOOL isDH = false;
04677  
04678     NUMTESTS++; /* increment NUMTESTS */
04679 
04680     attrs[0].type       = CKA_CLASS; 
04681     attrs[0].pValue     = &class; 
04682     attrs[0].ulValueLen = sizeof (class);
04683     attrs[1].type       = CKA_KEY_TYPE; 
04684     attrs[1].pValue     = &type; 
04685     attrs[1].ulValueLen = sizeof (type);
04686     attrs[2].type       = CKA_DERIVE; 
04687     attrs[2].pValue     = &derive_bool;
04688     attrs[2].ulValueLen = sizeof (derive_bool);
04689     attrs[3].type       = CKA_VALUE; 
04690     attrs[3].pValue     = NULL; 
04691     attrs[3].ulValueLen = 0;
04692     
04693 
04694     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
04695                                        NULL, NULL, &hSession);
04696     if (crv != CKR_OK) {
04697         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
04698                    PKM_CK_RVtoStr(crv));
04699         return crv;
04700     }
04701     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
04702     if (crv == CKR_OK) {
04703         PKM_LogIt("C_Login with correct password succeeded\n");
04704     } else {
04705         PKM_Error( "C_Login with correct password failed "
04706                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04707         return crv;
04708     }
04709 
04710     /* Before all, check if the mechanism is supported correctly */
04711     if (MODE == FIPSMODE) {
04712     crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE, false,
04713                         0, 0);
04714     if (crv != CKR_OK) {
04715         PKM_Error( "PKM_MechCheck failed with 0x%08X, %-26s\n", crv, 
04716                    PKM_CK_RVtoStr(crv));
04717         return (crv);
04718     }
04719     }
04720 
04721     mk_mech.mechanism = mechType;
04722     mk_mech.pParameter = &mkd_params;
04723     mk_mech.ulParameterLen = sizeof (mkd_params);
04724 
04725     switch (mechType) {
04726     case CKM_TLS_MASTER_KEY_DERIVE_DH:
04727         isDH = true;
04728         /* FALLTHRU */
04729     case CKM_TLS_MASTER_KEY_DERIVE:
04730         attrs[3].pValue = NULL;
04731         attrs[3].ulValueLen = 0;
04732         expected_version.major = 3;
04733         expected_version.minor = 1;
04734 
04735         mkd_params.RandomInfo.pClientRandom = (unsigned char * ) TLSClientRandom;
04736         mkd_params.RandomInfo.ulClientRandomLen =
04737         sizeof (TLSClientRandom);
04738         mkd_params.RandomInfo.pServerRandom = (unsigned char * ) TLSServerRandom;
04739         mkd_params.RandomInfo.ulServerRandomLen =
04740         sizeof (TLSServerRandom);
04741         break;
04742     }
04743     mkd_params.pVersion = (!isDH) ? &version : NULL;
04744 
04745     /* First create the pre-master secret key */
04746 
04747     skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
04748     skmd_mech.pParameter = &mkd_params;
04749     skmd_mech.ulParameterLen = sizeof (mkd_params);
04750 
04751 
04752     crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech,
04753                                        attrs,
04754                                        attrs_count,
04755                                        &pmk_obj);
04756     if (crv == CKR_OK) {
04757         PKM_LogIt("C_GenerateKey succeeded\n");
04758     } else {
04759         PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv, 
04760                    PKM_CK_RVtoStr(crv));
04761         return crv;
04762 
04763     }
04764     /* Test the bad cases */
04765     switch (rnd) {
04766     case CORRECT:
04767         goto correct;
04768 
04769     case BOGUS_CLIENT_RANDOM:
04770         mkd_params.RandomInfo.pClientRandom = NULL;
04771         break;
04772 
04773     case BOGUS_CLIENT_RANDOM_LEN:
04774         mkd_params.RandomInfo.ulClientRandomLen = 0;
04775         break;
04776 
04777     case BOGUS_SERVER_RANDOM:
04778         mkd_params.RandomInfo.pServerRandom = NULL;
04779         break;
04780 
04781     case BOGUS_SERVER_RANDOM_LEN:
04782         mkd_params.RandomInfo.ulServerRandomLen = 0;
04783         break;
04784     }
04785     crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0,
04786                                      &mk_obj);
04787     if (crv != CKR_MECHANISM_PARAM_INVALID) {
04788         PKM_LogIt( "C_DeriveKey returned as EXPECTED with 0x%08X, %-26s\n", crv, 
04789                    PKM_CK_RVtoStr(crv));
04790     } else {
04791         PKM_Error( "C_DeriveKey did not fail  with  bad data \n" );
04792     }
04793     goto out;
04794 
04795 
04796     correct:
04797     /* Now derive the master secret key */
04798     crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0,
04799                                      &mk_obj);
04800     if (crv == CKR_OK) {
04801         PKM_LogIt("C_DeriveKey succeeded\n");
04802     } else {
04803         PKM_Error( "C_DeriveKey failed with 0x%08X, %-26s\n", crv, 
04804                    PKM_CK_RVtoStr(crv));
04805         return crv;
04806 
04807     }
04808 
04809     out:
04810     if (pmk_obj != CK_INVALID_HANDLE)
04811         (void) pFunctionList->C_DestroyObject(hSession, pmk_obj);
04812     if (mk_obj != CK_INVALID_HANDLE)
04813         (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
04814     crv = pFunctionList->C_Logout(hSession);
04815 
04816     if (crv == CKR_OK) {
04817         PKM_LogIt("C_Logout succeeded\n");
04818     } else {
04819         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
04820                    PKM_CK_RVtoStr(crv));
04821         return crv;
04822     }
04823 
04824     crv = pFunctionList->C_CloseSession(hSession);
04825     if (crv != CKR_OK) {
04826         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
04827                    PKM_CK_RVtoStr(crv));
04828         return crv;
04829     }
04830     return (crv);
04831 }
04832 
04833 
04834 CK_RV
04835 PKM_TLSKeyAndMacDerive( CK_FUNCTION_LIST_PTR pFunctionList,
04836                         CK_SLOT_ID * pSlotList, CK_ULONG slotID,
04837                         CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
04838                         CK_MECHANISM_TYPE mechType, enum_random_t rnd)
04839 {
04840     CK_SESSION_HANDLE hSession;
04841     CK_RV crv;
04842     CK_MECHANISM            kmd_mech;
04843     CK_MECHANISM            skmd_mech;
04844     CK_OBJECT_CLASS         class = CKO_SECRET_KEY;
04845     CK_KEY_TYPE             type = CKK_GENERIC_SECRET;
04846     CK_BBOOL                derive_bool = true;
04847     CK_BBOOL                sign_bool = true, verify_bool = true;
04848     CK_BBOOL                encrypt_bool = true, decrypt_bool = true;
04849     CK_ULONG                value_len;
04850 
04851     /*
04852      * We arrange this template so that:
04853      * . Attributes 0-6 are good for a MAC key comparison template.
04854      * . Attributes 2-5 are good for the master key creation template.
04855      * . Attributes 3-8 are good for a cipher key comparison template.
04856      */
04857     CK_ATTRIBUTE            attrs[9]; 
04858 
04859     CK_OBJECT_HANDLE        mk_obj = CK_INVALID_HANDLE;
04860     CK_SSL3_KEY_MAT_PARAMS km_params;
04861     CK_SSL3_KEY_MAT_OUT kmo;
04862     CK_BYTE         IVClient[8];
04863     CK_BYTE         IVServer[8];
04864 
04865     NUMTESTS++; /* increment NUMTESTS */
04866 
04867     attrs[0].type       = CKA_SIGN;
04868     attrs[0].pValue     = &sign_bool; 
04869     attrs[0].ulValueLen = sizeof (sign_bool);
04870     attrs[1].type       = CKA_VERIFY; 
04871     attrs[1].pValue     = &verify_bool; 
04872     attrs[1].ulValueLen = sizeof (verify_bool);
04873     attrs[2].type       = CKA_KEY_TYPE; 
04874     attrs[2].pValue     = &type; 
04875     attrs[2].ulValueLen = sizeof (type);
04876     attrs[3].type       = CKA_CLASS; 
04877     attrs[3].pValue     = &class; 
04878     attrs[3].ulValueLen = sizeof (class);
04879     attrs[4].type       = CKA_DERIVE; 
04880     attrs[4].pValue     = &derive_bool; 
04881     attrs[4].ulValueLen = sizeof (derive_bool);
04882     attrs[5].type       = CKA_VALUE; 
04883     attrs[5].pValue     = NULL; 
04884     attrs[5].ulValueLen = 0;
04885     attrs[6].type       = CKA_VALUE_LEN; 
04886     attrs[6].pValue     = &value_len; 
04887     attrs[6].ulValueLen = sizeof (value_len);
04888     attrs[7].type       = CKA_ENCRYPT; 
04889     attrs[7].pValue     = &encrypt_bool; 
04890     attrs[7].ulValueLen = sizeof (encrypt_bool);
04891     attrs[8].type       = CKA_DECRYPT; 
04892     attrs[8].pValue     = &decrypt_bool; 
04893     attrs[8].ulValueLen = sizeof (decrypt_bool);
04894 
04895     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
04896                                        NULL, NULL, &hSession);
04897     if (crv != CKR_OK) {
04898         PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv, 
04899                    PKM_CK_RVtoStr(crv));
04900         return crv;
04901     }
04902     crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
04903     if (crv == CKR_OK) {
04904         PKM_LogIt("C_Login with correct password succeeded\n");
04905     } else {
04906         PKM_Error( "C_Login with correct password failed "
04907                    "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04908         return crv;
04909     }
04910 
04911 
04912     /* Before all, check if the mechanism is supported correctly */
04913     if (MODE == FIPSMODE) {
04914         crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE,
04915                             CK_TRUE, 48, 48);
04916 
04917         if (crv != CKR_OK) {
04918             PKM_Error( "PKM_MechCheck failed with 0x%08X, %-26s\n", crv, 
04919                        PKM_CK_RVtoStr(crv));
04920             return (crv);
04921         }
04922     }
04923     kmd_mech.mechanism = mechType;
04924     kmd_mech.pParameter = &km_params;
04925     kmd_mech.ulParameterLen = sizeof (km_params);
04926 
04927     km_params.ulMacSizeInBits = 128;        /* an MD5 based MAC */
04928     km_params.ulKeySizeInBits = 192;        /* 3DES key size */
04929     km_params.ulIVSizeInBits = 64;          /* 3DES block size */
04930     km_params.pReturnedKeyMaterial = &kmo;
04931     km_params.bIsExport = false;
04932     kmo.hClientMacSecret = CK_INVALID_HANDLE;
04933     kmo.hServerMacSecret = CK_INVALID_HANDLE;
04934     kmo.hClientKey = CK_INVALID_HANDLE;
04935     kmo.hServerKey = CK_INVALID_HANDLE;
04936     kmo.pIVClient = IVClient;
04937     kmo.pIVServer = IVServer;
04938 
04939     skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
04940     skmd_mech.pParameter = &km_params;
04941     skmd_mech.ulParameterLen = sizeof (km_params);
04942 
04943 
04944     crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech,
04945                                        &attrs[2],
04946                                        4,
04947                                        &mk_obj);
04948     if (crv == CKR_OK) {
04949         PKM_LogIt("C_GenerateKey succeeded\n");
04950     } else {
04951         PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv, 
04952                    PKM_CK_RVtoStr(crv));
04953         return crv;
04954     }
04955 
04956         attrs[5].pValue = NULL;
04957         attrs[5].ulValueLen = 0;
04958 
04959     km_params.RandomInfo.pClientRandom = (unsigned char *) TLSClientRandom;
04960     km_params.RandomInfo.ulClientRandomLen =
04961     sizeof (TLSClientRandom);
04962     km_params.RandomInfo.pServerRandom = (unsigned char *) TLSServerRandom;
04963     km_params.RandomInfo.ulServerRandomLen =
04964     sizeof (TLSServerRandom);
04965 
04966     /* Test the bad cases */
04967     switch (rnd) {
04968     case CORRECT:
04969         goto correct;
04970 
04971     case BOGUS_CLIENT_RANDOM:
04972         km_params.RandomInfo.pClientRandom = NULL;
04973         break;
04974 
04975     case BOGUS_CLIENT_RANDOM_LEN:
04976         km_params.RandomInfo.ulClientRandomLen = 0;
04977         break;
04978 
04979     case BOGUS_SERVER_RANDOM:
04980         km_params.RandomInfo.pServerRandom = NULL;
04981         break;
04982 
04983     case BOGUS_SERVER_RANDOM_LEN:
04984         km_params.RandomInfo.ulServerRandomLen = 0;
04985         break;
04986     }
04987     crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0,
04988                                      NULL);
04989     if (crv != CKR_MECHANISM_PARAM_INVALID) {
04990         PKM_Error( "key materials derivation returned unexpected "
04991                    "error 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
04992         (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
04993         return (CKR_FUNCTION_FAILED);
04994 
04995     }
04996     return (CKR_OK);
04997 
04998     correct:
04999     /*
05000      * Then use the master key and the client 'n server random data to
05001      * derive the key materials
05002      */
05003     crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0,
05004                                      NULL);
05005     if (crv != CKR_OK) {
05006         PKM_Error( "Cannot derive the key materials, crv 0x%08X, %-26s\n", 
05007                    crv, PKM_CK_RVtoStr(crv));
05008         (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
05009         return (crv);
05010     }
05011 
05012     if (mk_obj != CK_INVALID_HANDLE)
05013         (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
05014     if (kmo.hClientMacSecret != CK_INVALID_HANDLE)
05015         (void) pFunctionList->C_DestroyObject(hSession, kmo.hClientMacSecret);
05016     if (kmo.hServerMacSecret != CK_INVALID_HANDLE)
05017         (void) pFunctionList->C_DestroyObject(hSession, kmo.hServerMacSecret);
05018     if (kmo.hClientKey != CK_INVALID_HANDLE);
05019         (void) pFunctionList->C_DestroyObject(hSession, kmo.hClientKey);
05020     if (kmo.hServerKey != CK_INVALID_HANDLE)
05021         (void) pFunctionList->C_DestroyObject(hSession, kmo.hServerKey);
05022     crv = pFunctionList->C_Logout(hSession);
05023     if (crv == CKR_OK) {
05024         PKM_LogIt("C_Logout succeeded\n");
05025     } else {
05026         PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv, 
05027                    PKM_CK_RVtoStr(crv));
05028         return crv;
05029     }
05030     crv = pFunctionList->C_CloseSession(hSession);
05031     if (crv != CKR_OK) {
05032         PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv, 
05033                    PKM_CK_RVtoStr(crv));
05034         return crv;
05035     }
05036 
05037 
05038     return (crv);
05039 }
05040 
05041 
05042 
05043 CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,
05044                        CK_SESSION_HANDLE hRwSession,
05045                        CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey,
05046                        CK_MECHANISM *sigMech,
05047                        CK_OBJECT_HANDLE secretKey, CK_MECHANISM *cryptMech,
05048                        const CK_BYTE *  pData, CK_ULONG pDataLen) {
05049 
05050     CK_RV crv = CKR_OK;
05051     CK_BYTE encryptedData[MAX_CIPHER_SZ];
05052     CK_ULONG ulEncryptedDataLen = 0;
05053     CK_ULONG ulLastUpdateSize = 0 ;
05054     CK_BYTE sig[MAX_SIG_SZ];
05055     CK_ULONG ulSigLen = 0;
05056     CK_BYTE data[MAX_DATA_SZ];
05057     CK_ULONG ulDataLen = 0;
05058 
05059     memset(encryptedData, 0, sizeof(encryptedData));
05060     memset(sig, 0, sizeof(sig));
05061     memset(data, 0, sizeof(data));
05062 
05063     NUMTESTS++; /* increment NUMTESTS */
05064 
05065     /* Check that the mechanism is Multi-part */
05066     if (sigMech->mechanism == CKM_DSA || sigMech->mechanism == CKM_RSA_PKCS) {
05067         PKM_Error( "PKM_DualFuncSign must be called with a Multi-part "
05068                    "operation mechanism\n");        
05069         return CKR_DEVICE_ERROR;
05070     }
05071 
05072     /* Sign and Encrypt */
05073     if (privateKey == 0 && publicKey == 0) {
05074         crv = pFunctionList->C_SignInit(hRwSession, sigMech, secretKey);
05075         if (crv != CKR_OK) {
05076             PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, 
05077                        PKM_CK_RVtoStr(crv));
05078             return crv;
05079         }
05080     } else {
05081         crv = pFunctionList->C_SignInit(hRwSession, sigMech, privateKey);
05082         if (crv != CKR_OK) {
05083             PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, 
05084                        PKM_CK_RVtoStr(crv));
05085             return crv;
05086         }
05087      }
05088     crv = pFunctionList->C_EncryptInit(hRwSession, cryptMech, secretKey);
05089     if (crv != CKR_OK) {
05090         PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv, 
05091                    PKM_CK_RVtoStr(crv));
05092         return crv;
05093     }
05094 
05095 
05096     ulEncryptedDataLen = sizeof(encryptedData);
05097     crv = pFunctionList->C_SignEncryptUpdate(hRwSession, (CK_BYTE * ) pData,
05098                                              pDataLen,
05099                                              encryptedData,
05100                                              &ulEncryptedDataLen);
05101     if (crv != CKR_OK) {
05102         PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, 
05103                    PKM_CK_RVtoStr(crv));
05104         return crv;
05105     }
05106 
05107     ulLastUpdateSize = sizeof(encryptedData) - ulEncryptedDataLen;
05108     crv = pFunctionList->C_EncryptFinal(hRwSession,
05109          (CK_BYTE * )&encryptedData[ulEncryptedDataLen], &ulLastUpdateSize);
05110     if (crv != CKR_OK) {
05111         PKM_Error( "C_EncryptFinal failed with 0x%08X, %-26s\n", crv,
05112                     PKM_CK_RVtoStr(crv));
05113         return crv;
05114     }
05115     ulEncryptedDataLen = ulEncryptedDataLen + ulLastUpdateSize; 
05116     ulSigLen = sizeof(sig);
05117     crv = pFunctionList->C_SignFinal(hRwSession, sig, &ulSigLen);
05118     if (crv != CKR_OK) {
05119         PKM_Error( "C_SignFinal failed with 0x%08X, %-26s\n", crv, 
05120                    PKM_CK_RVtoStr(crv));
05121         return crv;
05122     }
05123 
05124     /* Decrypt and Verify */
05125 
05126     crv = pFunctionList->C_DecryptInit(hRwSession, cryptMech, secretKey);
05127     if (crv != CKR_OK) {
05128         PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv, 
05129                    PKM_CK_RVtoStr(crv));
05130         return crv;
05131     }
05132     crv = pFunctionList->C_VerifyInit(hRwSession, sigMech,
05133                                       publicKey);
05134     if (crv != CKR_OK) {
05135         PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv, 
05136                    PKM_CK_RVtoStr(crv));
05137         return crv;
05138     }
05139 
05140     ulDataLen = sizeof(data);
05141     crv = pFunctionList->C_DecryptVerifyUpdate(hRwSession,
05142                                                encryptedData,
05143                                                ulEncryptedDataLen,
05144                                                data, &ulDataLen);
05145     if (crv != CKR_OK) {
05146         PKM_Error( "C_DecryptVerifyUpdate failed with 0x%08X, %-26s\n", crv, 
05147                    PKM_CK_RVtoStr(crv));
05148         return crv;
05149     }
05150     ulLastUpdateSize = sizeof(data) - ulDataLen;
05151     /* Get last little piece of plaintext.  Should have length 0 */
05152     crv = pFunctionList->C_DecryptFinal(hRwSession, &data[ulDataLen],
05153                                         &ulLastUpdateSize);
05154     if (crv != CKR_OK) {
05155         PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, 
05156                    PKM_CK_RVtoStr(crv));
05157         return crv;
05158     }
05159     
05160     if (ulLastUpdateSize != 0) {
05161         crv = pFunctionList->C_VerifyUpdate(hRwSession, &data[ulDataLen],
05162                                         ulLastUpdateSize);
05163         if (crv != CKR_OK) {
05164             PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv, 
05165                        PKM_CK_RVtoStr(crv));
05166             return crv;
05167         }
05168     }
05169     ulDataLen = ulDataLen + ulLastUpdateSize; 
05170 
05171     /* input for the verify operation is the decrypted data */
05172     crv = pFunctionList->C_VerifyFinal(hRwSession, sig, ulSigLen);
05173     if (crv == CKR_OK) {
05174         PKM_LogIt("C_VerifyFinal succeeded\n");
05175     } else {
05176         PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv, 
05177                    PKM_CK_RVtoStr(crv));
05178         return crv;
05179     }
05180 
05181     /* Comparison of Decrypted data with inputed data */
05182     if ( (ulDataLen == pDataLen) && 
05183          (memcmp(data, pData, pDataLen) == 0) ) {
05184         PKM_LogIt("PKM_DualFuncSign decrypt test case passed\n");
05185     } else {
05186         PKM_Error( "PKM_DualFuncSign derypt test case failed\n");
05187     }
05188 
05189     return crv;
05190 
05191 }
05192 
05193 CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList, 
05194                  CK_SESSION_HANDLE hSession,
05195                  CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey,
05196                  const CK_BYTE *  pData, CK_ULONG pDataLen) {
05197     CK_RV crv = CKR_OK;
05198     CK_BYTE digest1[MAX_DIGEST_SZ];
05199     CK_ULONG digest1Len = 0 ;
05200     CK_BYTE digest2[MAX_DIGEST_SZ];
05201     CK_ULONG digest2Len = 0;
05202 
05203     /* Tested with CKM_SHA_1, CKM_SHA256, CKM_SHA384, CKM_SHA512 */
05204 
05205     memset(digest1, 0, sizeof(digest1));
05206     memset(digest2, 0, sizeof(digest2));
05207     
05208     NUMTESTS++; /* increment NUMTESTS */
05209 
05210     crv = pFunctionList->C_DigestInit(hSession, digestMech);
05211     if (crv != CKR_OK) {
05212         PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv, 
05213             PKM_CK_RVtoStr(crv));
05214         return crv;
05215     }
05216     digest1Len = sizeof(digest1);
05217     crv = pFunctionList->C_Digest(hSession, (CK_BYTE * ) pData, pDataLen, 
05218         digest1, &digest1Len);
05219     if (crv != CKR_OK) {
05220         PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv, 
05221             PKM_CK_RVtoStr(crv));
05222         return crv;
05223     }
05224 
05225 
05226     crv = pFunctionList->C_DigestInit(hSession, digestMech);
05227     if (crv != CKR_OK) {
05228         PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv, 
05229             PKM_CK_RVtoStr(crv));
05230         return crv;
05231     }
05232 
05233     crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE * ) pData, pDataLen);
05234     if (crv != CKR_OK) {
05235         PKM_Error( "C_DigestUpdate failed with 0x%08X, %-26s\n", crv, 
05236             PKM_CK_RVtoStr(crv));
05237         return crv;
05238     }
05239        
05240     /* C_DigestKey continues a multiple-part message-digesting operation by*/
05241     /* digesting the value of a secret key. (only used with C_DigestUpdate)*/
05242     if (hSecretKey != 0) {
05243         crv = pFunctionList->C_DigestKey(hSession, hSecretKey);
05244         if (crv != CKR_OK) {
05245             PKM_Error( "C_DigestKey failed with 0x%08X, %-26s\n", crv, 
05246                 PKM_CK_RVtoStr(crv));
05247             return crv;
05248         }
05249     }
05250 
05251     digest2Len = sizeof(digest2);
05252     crv = pFunctionList->C_DigestFinal(hSession, digest2, &digest2Len);
05253     if (crv != CKR_OK) {
05254         PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv, 
05255             PKM_CK_RVtoStr(crv));
05256         return crv;
05257     }
05258 
05259     if (hSecretKey == 0){
05260         /* did not digest a secret key so digests should equal */ 
05261         if  ( (digest1Len == digest2Len) 
05262             && (memcmp(digest1, digest2, digest1Len) == 0) ) {
05263                 PKM_LogIt("Single and Multiple-part message digest "
05264                     "operations succesful\n");
05265             } else {
05266                 PKM_Error("Single and Multiple-part message digest "
05267                     "operations failed\n");
05268             }
05269     } else {
05270         if  (digest1Len == digest2Len) { 
05271             PKM_LogIt("PKM_Digest Single and Multiple-part message digest "
05272                 "operations succesful\n");
05273         } else {
05274             PKM_Error("PKM_Digest Single and Multiple-part message digest "
05275                 "operations failed\n");
05276         }
05277 
05278     }
05279 
05280     return crv;
05281 
05282 }
05283 
05284 char * PKM_FilePasswd(char *pwFile)
05285 {
05286     unsigned char phrase[200];
05287     PRFileDesc *fd;
05288     PRInt32 nb;
05289     int i;
05290 
05291     if (!pwFile)
05292         return 0;
05293 
05294     fd = PR_Open(pwFile, PR_RDONLY, 0);
05295     if (!fd) {
05296         fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
05297         return NULL;
05298     }
05299 
05300     nb = PR_Read(fd, phrase, sizeof(phrase));
05301  
05302     PR_Close(fd);
05303     /* handle the Windows EOL case */
05304     i = 0;
05305     while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++;
05306     phrase[i] = '\0';
05307     if (nb == 0) {
05308         fprintf(stderr,"password file contains no data\n");
05309         return NULL;
05310     }
05311     return (char*) strdup((char*)phrase);
05312 }
05313 
05314 void PKM_Help() 
05315 {
05316     PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError);
05317     PR_fprintf(debug_out, "pk11mode test program usage:\n");
05318     PR_fprintf(debug_out, "\t-f <file>   Password File : echo pw > file \n");
05319     PR_fprintf(debug_out, "\t-n          Non Fips Mode \n");
05320     PR_fprintf(debug_out, "\t-d <path>   Database path location)\n");
05321     PR_fprintf(debug_out, "\t-p <prefix> DataBase prefix)\n");
05322     PR_fprintf(debug_out, "\t-h          this help message\n");
05323     exit(1);
05324 }
05325 
05326 void PKM_CheckPath(char *string)
05327 {
05328    char *src;
05329    char *dest;
05330 
05331    /*
05332    * windows support convert any back slashes to
05333    * forward slashes.
05334    */
05335    for (src=string, dest=string; *src; src++,dest++) {
05336        if (*src == '\\') {
05337            *dest = '/';
05338        }
05339    }
05340    dest--;
05341    /* if the last char is a / set it to 0 */
05342    if (*dest == '/')
05343        *dest = 0;
05344 
05345 }