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