summaryrefslogtreecommitdiff
path: root/usr/src/lib/libkmf
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libkmf')
-rw-r--r--usr/src/lib/libkmf/include/kmfapiP.h3
-rw-r--r--usr/src/lib/libkmf/libkmf/Makefile.com6
-rw-r--r--usr/src/lib/libkmf/libkmf/common/certop.c88
-rw-r--r--usr/src/lib/libkmf/libkmf/common/generalop.c75
-rw-r--r--usr/src/lib/libkmf/libkmf/common/mapfile-vers1
-rw-r--r--usr/src/lib/libkmf/libkmf/common/pk11keys.c52
-rw-r--r--usr/src/lib/libkmf/libkmf/common/pk11tokens.c5
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c5
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com4
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c13
10 files changed, 125 insertions, 127 deletions
diff --git a/usr/src/lib/libkmf/include/kmfapiP.h b/usr/src/lib/libkmf/include/kmfapiP.h
index e20df89348..715abfaf31 100644
--- a/usr/src/lib/libkmf/include/kmfapiP.h
+++ b/usr/src/lib/libkmf/include/kmfapiP.h
@@ -259,7 +259,6 @@ KMF_RETURN PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession,
KMF_BOOL *);
KMF_RETURN GetIDFromSPKI(KMF_X509_SPKI *, KMF_DATA *);
-CK_RV DigestData(CK_SESSION_HANDLE, KMF_DATA *, KMF_DATA *);
KMF_RETURN KMF_SetAltName(KMF_X509_EXTENSIONS *,
KMF_OID *, int, KMF_GENERALNAMECHOICES, char *);
@@ -275,7 +274,7 @@ void free_dp_name(KMF_CRL_DIST_POINT *);
void free_dp(KMF_CRL_DIST_POINT *);
KMF_RETURN set_key_usage_extension(KMF_X509_EXTENSIONS *,
int, uint32_t);
-int is_pk11_ready();
+KMF_RETURN init_pk11();
KMF_RETURN KMF_SelectToken(KMF_HANDLE_T, char *, int);
diff --git a/usr/src/lib/libkmf/libkmf/Makefile.com b/usr/src/lib/libkmf/libkmf/Makefile.com
index fc951c006b..fd5162c59c 100644
--- a/usr/src/lib/libkmf/libkmf/Makefile.com
+++ b/usr/src/lib/libkmf/libkmf/Makefile.com
@@ -18,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -58,8 +58,8 @@ LIBS= $(DYNLIB) $(LINTLIB)
$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
-LDLIBS += $(BERDERLIB) $(CRYPTOUTILLIB) -lpkcs11 -lnsl -lsocket -lc
-LDLIBS64 += $(BERDERLIB64) $(CRYPTOUTILLIB64) -lpkcs11 -lnsl -lsocket -lc
+LDLIBS += $(BERDERLIB) $(CRYPTOUTILLIB) -lmd -lpkcs11 -lnsl -lsocket -lc
+LDLIBS64 += $(BERDERLIB64) $(CRYPTOUTILLIB64) -lmd -lpkcs11 -lnsl -lsocket -lc
# DYNLIB libraries do not have lint libs and are not linted
$(DYNLIB) := LDLIBS += -lxml2
diff --git a/usr/src/lib/libkmf/libkmf/common/certop.c b/usr/src/lib/libkmf/libkmf/common/certop.c
index 508293785f..2feffd8218 100644
--- a/usr/src/lib/libkmf/libkmf/common/certop.c
+++ b/usr/src/lib/libkmf/libkmf/common/certop.c
@@ -618,6 +618,40 @@ KMF_VerifyCertWithCert(KMF_HANDLE_T handle,
return (ret);
}
+static KMF_RETURN
+plugin_verify_data_with_cert(KMF_HANDLE_T handle,
+ KMF_KEYSTORE_TYPE kstype,
+ KMF_ALGORITHM_INDEX algid,
+ KMF_DATA *indata,
+ KMF_DATA *insig,
+ const KMF_DATA *SignerCert)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN ret = KMF_OK;
+
+ /*
+ * If NSS, use PKCS#11, we are not accessing the database(s),
+ * we just prefer the "verify" operation from the crypto framework.
+ * The OpenSSL version is unique in order to avoid a dependency loop
+ * with the kcfd(1M) process.
+ */
+ if (kstype == KMF_KEYSTORE_NSS)
+ kstype = KMF_KEYSTORE_PK11TOKEN;
+
+ plugin = FindPlugin(handle, kstype);
+ if (plugin == NULL)
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+
+ if (plugin->funclist->VerifyDataWithCert == NULL)
+ return (KMF_ERR_FUNCTION_NOT_FOUND);
+
+ CLEAR_ERROR(handle, ret);
+ ret = (plugin->funclist->VerifyDataWithCert(handle,
+ algid, indata, insig, (KMF_DATA *)SignerCert));
+
+ return (ret);
+}
+
/*
*
* Name: KMF_VerifyDataWithCert
@@ -649,7 +683,6 @@ KMF_VerifyDataWithCert(KMF_HANDLE_T handle,
const KMF_DATA *SignerCert)
{
KMF_RETURN ret;
- KMF_PLUGIN *plugin;
CLEAR_ERROR(handle, ret);
if (ret != KMF_OK)
@@ -664,25 +697,8 @@ KMF_VerifyDataWithCert(KMF_HANDLE_T handle,
if (ret != KMF_OK)
return (ret);
- /*
- * If NSS, use PKCS#11, we are not accessing the database(s),
- * we just prefer the "verify" operation from the crypto framework.
- * The OpenSSL version is unique in order to avoid a dependency loop
- * with the kcfd(1M) process.
- */
- if (kstype == KMF_KEYSTORE_NSS)
- kstype = KMF_KEYSTORE_PK11TOKEN;
-
- plugin = FindPlugin(handle, kstype);
- if (plugin == NULL)
- return (KMF_ERR_PLUGIN_NOTFOUND);
-
- if (plugin->funclist->VerifyDataWithCert == NULL)
- return (KMF_ERR_FUNCTION_NOT_FOUND);
-
- CLEAR_ERROR(handle, ret);
- ret = (plugin->funclist->VerifyDataWithCert(handle,
- algid, indata, insig, (KMF_DATA *)SignerCert));
+ ret = plugin_verify_data_with_cert(handle, kstype,
+ algid, indata, insig, SignerCert);
return (ret);
}
@@ -2622,7 +2638,6 @@ VerifyCertWithCert(KMF_HANDLE_T handle,
KMF_RETURN ret = KMF_OK;
KMF_X509_CERTIFICATE *SignerCert = NULL;
KMF_X509_CERTIFICATE *ToBeVerifiedCert = NULL;
- KMF_X509_SPKI *pubkey;
KMF_DATA data_to_verify = {0, NULL};
KMF_DATA signed_data = {0, NULL};
KMF_DATA signature;
@@ -2644,21 +2659,6 @@ VerifyCertWithCert(KMF_HANDLE_T handle,
if (ret != KMF_OK)
goto cleanup;
- /* Decode the signer cert so we can get the SPKI data */
- ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert);
- if (ret != KMF_OK)
- goto cleanup;
-
- /*
- * TODO ! Validate the SignerCert to make sure it is OK to be
- * used to verify other certs. Or - should this be done the calling
- * application?
- */
- /* ValidateCert(SignerCert); */
-
- /* Get the public key info from the signer certificate */
- pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
-
/* Decode the to-be-verified cert so we know what algorithm to use */
ret = DerDecodeSignedCertificate(CertToBeVerifiedData,
&ToBeVerifiedCert);
@@ -2677,8 +2677,20 @@ VerifyCertWithCert(KMF_HANDLE_T handle,
signature.Length = signed_data.Length;
}
- ret = PKCS_VerifyData(handle, algid, pubkey,
- &data_to_verify, &signature);
+ /* Make sure the signer has proper key usage bits */
+ ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT);
+ if (ret != KMF_OK)
+ return (ret);
+
+ /*
+ * To avoid recursion with kcfd consumer and libpkcs11,
+ * do the data verification using the OpenSSL
+ * plugin algorithms instead of the crypto framework.
+ */
+ ret = plugin_verify_data_with_cert(handle,
+ KMF_KEYSTORE_OPENSSL,
+ algid, &data_to_verify, &signature,
+ SignerCertData);
cleanup:
KMF_FreeData(&data_to_verify);
diff --git a/usr/src/lib/libkmf/libkmf/common/generalop.c b/usr/src/lib/libkmf/libkmf/common/generalop.c
index a9bf418ed3..52b4ff0a06 100644
--- a/usr/src/lib/libkmf/libkmf/common/generalop.c
+++ b/usr/src/lib/libkmf/libkmf/common/generalop.c
@@ -143,10 +143,22 @@ static kmf_error_map kmf_errcodes[] = {
static void free_extensions(KMF_X509_EXTENSIONS *extns);
-int
-is_pk11_ready()
+KMF_RETURN
+init_pk11()
{
- return (pkcs11_initialized);
+ (void) mutex_lock(&init_lock);
+ if (!pkcs11_initialized) {
+ CK_RV rv = C_Initialize(NULL);
+ if ((rv != CKR_OK) &&
+ (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
+ (void) mutex_unlock(&init_lock);
+ return (KMF_ERR_UNINITIALIZED);
+ } else {
+ pkcs11_initialized = 1;
+ }
+ }
+ (void) mutex_unlock(&init_lock);
+ return (KMF_OK);
}
/*
@@ -311,19 +323,6 @@ KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname)
(void) memset(handle, 0, sizeof (KMF_HANDLE));
handle->plugins = NULL;
- (void) mutex_lock(&init_lock);
- if (!pkcs11_initialized) {
- CK_RV rv = C_Initialize(NULL);
- if ((rv != CKR_OK) &&
- (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
- ret = KMF_ERR_UNINITIALIZED;
- (void) mutex_unlock(&init_lock);
- goto errout;
- } else {
- pkcs11_initialized = 1;
- }
- }
- (void) mutex_unlock(&init_lock);
/* Initialize the handle with the policy */
ret = KMF_SetPolicy((void *)handle,
@@ -498,7 +497,10 @@ KMF_DN2Der(KMF_X509_NAME *dn, KMF_DATA *der)
return (rv);
}
-#define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
+#define SET_SYS_ERROR(h, c) if (h) {\
+ h->lasterr.kstype = -1;\
+ h->lasterr.errcode = c;\
+}
KMF_RETURN
KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata)
@@ -509,10 +511,11 @@ KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata)
unsigned char *buf = NULL;
KMF_RETURN ret;
- CLEAR_ERROR(handle, ret);
- if (ret != KMF_OK)
- return (ret);
-
+ if (handle) {
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+ }
if (filename == NULL || pdata == NULL) {
return (KMF_ERR_BAD_PARAMETER);
@@ -690,28 +693,24 @@ KMF_OID2String(KMF_OID *oid)
static boolean_t
check_for_pem(char *filename)
{
- char buf[BUFSIZ];
- int len, f;
+ KMF_DATA filebuf;
+ KMF_RETURN rv;
+ char *p;
- if ((f = open(filename, O_RDONLY | O_NONBLOCK)) < 0)
+ rv = KMF_ReadInputFile(NULL, filename, &filebuf);
+ if (rv != KMF_OK)
return (FALSE);
- while ((len = read(f, buf, sizeof (buf))) > 0) {
- /* Look for "-----BEGIN" right after a newline */
- char *p;
-
- p = strtok(buf, "\n");
- while (p != NULL) {
- if (p < (buf + len)) {
- if (strstr(p, "-----BEGIN") != NULL) {
- (void) close(f);
- return (TRUE);
- }
- }
- p = strtok(NULL, "\n");
+ /* Look for "-----BEGIN" right after a newline */
+ p = strtok((char *)filebuf.Data, "\n");
+ while (p != NULL) {
+ if (strstr(p, "-----BEGIN") != NULL) {
+ free(filebuf.Data);
+ return (TRUE);
}
+ p = strtok(NULL, "\n");
}
- (void) close(f);
+ free(filebuf.Data);
return (FALSE);
}
diff --git a/usr/src/lib/libkmf/libkmf/common/mapfile-vers b/usr/src/lib/libkmf/libkmf/common/mapfile-vers
index fec0c2cee7..85424328bd 100644
--- a/usr/src/lib/libkmf/libkmf/common/mapfile-vers
+++ b/usr/src/lib/libkmf/libkmf/common/mapfile-vers
@@ -26,7 +26,6 @@
SUNWprivate_1.1 {
global:
- DigestData;
GetIDFromSPKI;
KMF_AddCertEKU;
KMF_AddPolicyToDB;
diff --git a/usr/src/lib/libkmf/libkmf/common/pk11keys.c b/usr/src/lib/libkmf/libkmf/common/pk11keys.c
index 05dded86ea..66d328968b 100644
--- a/usr/src/lib/libkmf/libkmf/common/pk11keys.c
+++ b/usr/src/lib/libkmf/libkmf/common/pk11keys.c
@@ -9,6 +9,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <kmfapiP.h>
+#include <sha1.h>
#include <security/cryptoki.h>
#include <algorithm.h>
@@ -23,20 +24,17 @@ create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech,
CK_FLAGS wanted_flags)
{
CK_RV rv;
+ KMF_RETURN ret;
KMF_RETURN kmf_rv = KMF_OK;
CK_SLOT_ID_PTR pSlotList;
CK_ULONG pulCount;
CK_MECHANISM_INFO info;
int i;
- if (!is_pk11_ready()) {
- rv = C_Initialize(NULL);
- if ((rv != CKR_OK) &&
- (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
- kmf_rv = KMF_ERR_UNINITIALIZED;
- goto out;
- }
- }
+ ret = init_pk11();
+
+ if (ret != KMF_OK)
+ return (ret);
rv = C_GetSlotList(0, NULL, &pulCount);
if (rv != CKR_OK) {
@@ -633,33 +631,25 @@ PKCS_EncryptData(KMF_HANDLE_T kmfh,
}
-CK_RV
-DigestData(CK_SESSION_HANDLE hSession,
- KMF_DATA *IDInput, KMF_DATA *IDOutput)
+static void
+DigestData(KMF_DATA *IDInput, KMF_DATA *IDOutput)
{
- CK_RV rv = KMF_OK;
- CK_MECHANISM mechanism = {CKM_SHA_1, NULL, 0};
-
- rv = C_DigestInit(hSession, &mechanism);
- if (rv != CKR_OK)
- return (rv);
+ SHA1_CTX ctx;
- rv = C_Digest(hSession,
- IDInput->Data, IDInput->Length,
- IDOutput->Data, (CK_ULONG *)&IDOutput->Length);
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, IDInput->Data, IDInput->Length);
+ SHA1Final(IDOutput->Data, &ctx);
- return (rv);
+ IDOutput->Length = SHA1_DIGEST_LENGTH;
}
KMF_RETURN
-GetIDFromSPKI(KMF_X509_SPKI *spki,
- KMF_DATA *ID)
+GetIDFromSPKI(KMF_X509_SPKI *spki, KMF_DATA *ID)
{
KMF_RETURN rv = KMF_OK;
KMF_DATA KeyParts[KMF_MAX_PUBLIC_KEY_PARTS];
uint32_t uNumKeyParts = KMF_MAX_PUBLIC_KEY_PARTS;
KMF_ALGORITHM_INDEX algId;
- CK_SESSION_HANDLE hSession = NULL;
int i;
if (ID == NULL || spki == NULL)
@@ -677,20 +667,11 @@ GetIDFromSPKI(KMF_X509_SPKI *spki,
if (rv != KMF_OK)
return (rv);
- rv = create_pk11_session(&hSession, CKM_SHA_1, CKF_DIGEST);
-
- if (rv != KMF_OK)
- return (rv);
-
/* Check the KEY algorithm */
if (algId == KMF_ALGID_RSA) {
- rv = DigestData(hSession,
- &KeyParts[KMF_RSA_MODULUS],
- ID);
+ DigestData(&KeyParts[KMF_RSA_MODULUS], ID);
} else if (algId == KMF_ALGID_DSA) {
- rv = DigestData(hSession,
- &KeyParts[KMF_DSA_PUBLIC_VALUE],
- ID);
+ DigestData(&KeyParts[KMF_DSA_PUBLIC_VALUE], ID);
} else {
/* We only support RSA and DSA keys for now */
rv = KMF_ERR_BAD_ALGORITHM;
@@ -708,6 +689,5 @@ GetIDFromSPKI(KMF_X509_SPKI *spki,
ID->Length = 0;
}
- (void) C_CloseSession(hSession);
return (rv);
}
diff --git a/usr/src/lib/libkmf/libkmf/common/pk11tokens.c b/usr/src/lib/libkmf/libkmf/common/pk11tokens.c
index 20f8c2db13..80909114e2 100644
--- a/usr/src/lib/libkmf/libkmf/common/pk11tokens.c
+++ b/usr/src/lib/libkmf/libkmf/common/pk11tokens.c
@@ -497,8 +497,9 @@ KMF_SelectToken(KMF_HANDLE_T handle, char *label,
return (KMF_ERR_BAD_PARAMETER);
}
- if (!is_pk11_ready()) {
- return (KMF_ERR_UNINITIALIZED);
+ kmf_rv = init_pk11();
+ if (kmf_rv != KMF_OK) {
+ return (kmf_rv);
}
/* Only one token can be active per thread */
diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
index 7edbcc58dd..01ee7d7909 100644
--- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
+++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
@@ -4379,6 +4379,7 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params,
rkey->keydata.val = (uchar_t *)des3key;
rkey->keydata.len = DES3_KEY_SIZE;
symkey->keyalg = KMF_DES3;
+
} else if (params->keytype == KMF_AES || params->keytype == KMF_RC4 ||
params->keytype == KMF_GENERIC_SECRET) {
int bytes;
@@ -4845,7 +4846,8 @@ OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle,
goto cleanup;
}
}
- switch (EVP_MD_type(md)) {
+ if (md != NULL) {
+ switch (EVP_MD_type(md)) {
case NID_md2:
case NID_md2WithRSAEncryption:
pfxlen = ASN1_MD2_OID_PREFIX_LEN;
@@ -4865,6 +4867,7 @@ OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle,
pfxlen = 0;
pfx = NULL;
break;
+ }
}
/* RSA with no hash is a special case */
diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com
index f2a715de92..fd46f0e5f8 100644
--- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com
+++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -36,7 +36,7 @@ include $(SRC)/lib/Makefile.lib
LIBLINKS= $(DYNLIB:.so.1=.so)
KMFINC= -I../../../include -I../../../ber_der/inc
-PKCS11LIBS= -lkmf -lkmfberder -lpkcs11 -lcryptoutil -lc
+PKCS11LIBS= -lkmf -lkmfberder -lmd -lpkcs11 -lcryptoutil -lc
SRCDIR= ../common
INCDIR= ../../include
diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c
index 902a45cd4e..f000c5eadd 100644
--- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c
+++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c
@@ -30,11 +30,12 @@
#include <stdio.h> /* debugging only */
#include <errno.h>
#include <values.h>
-#include <fcntl.h>
#include <kmfapiP.h>
#include <ber_der.h>
#include <algorithm.h>
+#include <fcntl.h>
+#include <sha1.h>
#include <cryptoutil.h>
#include <security/cryptoki.h>
@@ -1379,6 +1380,7 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params,
CK_ATTRIBUTE idattr[1];
char IDHashData[SHA1_HASH_LENGTH];
KMF_DATA IDInput, IDOutput;
+ SHA1_CTX ctx;
#define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
sizeof (CK_ATTRIBUTE))
@@ -1607,7 +1609,12 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params,
IDOutput.Data = (uchar_t *)IDHashData;
IDOutput.Length = sizeof (IDHashData);
- rv = DigestData(hSession, &IDInput, &IDOutput);
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, IDInput.Data, IDInput.Length);
+ SHA1Final(IDOutput.Data, &ctx);
+
+ IDOutput.Length = SHA1_DIGEST_LENGTH;
+
free(IDInput.Data);
if (rv != CKR_OK) {
@@ -2488,7 +2495,6 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms,
/* "numkeys" indicates the number that were actually found */
*numkeys = n;
}
-
if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
if (parms->format == KMF_FORMAT_RAWKEY) {
/* Convert keys to "rawkey" format */
@@ -2798,7 +2804,6 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params,
if (params == NULL)
return (KMF_ERR_BAD_PARAMETER);
-
/*
* For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
*