diff -rcP openssl-engine-0.9.6b.pristine/apps/gendsa.c openssl-engine-0.9.6b/apps/gendsa.c *** openssl-engine-0.9.6b.pristine/apps/gendsa.c Thu Sep 21 00:44:19 2000 --- openssl-engine-0.9.6b/apps/gendsa.c Tue Jul 31 11:05:16 2001 *************** *** 87,92 **** --- 87,93 ---- BIO *out=NULL,*in=NULL; EVP_CIPHER *enc=NULL; char *engine=NULL; + char *hwkey=NULL; apps_startup(); *************** *** 114,119 **** --- 115,125 ---- if (--argc < 1) goto bad; engine= *(++argv); } + else if (strcmp(*argv,"-hwkey") == 0) + { + if (--argc < 1 ) goto bad; + hwkey= *(++argv); + } else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) goto bad; *************** *** 141,146 **** --- 147,161 ---- argc--; } + /* engine must be specfied it hwkey is used */ + if(hwkey != NULL) { + if(engine == NULL) { + goto bad; + }else{ + BIO_printf(bio_err,"This key will be linked to key %s stored on %s hardware \n", hwkey, engine); + } + } + if (dsaparams == NULL) { bad: *************** *** 154,159 **** --- 169,175 ---- BIO_printf(bio_err," -idea - encrypt the generated key with IDEA in cbc mode\n"); #endif BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n"); + BIO_printf(bio_err," -hwkey keyname - real key is stored on engine hardware device.\n"); BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err," - load the file (or the files in the directory) into\n"); BIO_printf(bio_err," the random number generator\n"); *************** *** 231,239 **** BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); ! BIO_printf(bio_err,"Generating DSA key, %d bits\n", BN_num_bits(dsa->p)); ! if (!DSA_generate_key(dsa)) goto end; app_RAND_write_file(NULL, bio_err); --- 247,278 ---- BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); ! ! /* load the key from the hardware */ ! if ( hwkey != NULL ) { ! EVP_PKEY *pkey; ! ! if((e = ENGINE_by_id(engine)) == NULL) ! { ! BIO_printf(bio_err,"invalid engine \"%s\"\n", ! engine); ! goto end; ! } ! ! pkey = ENGINE_load_private_key(e, hwkey, NULL); ! if ( pkey ) { ! dsa = EVP_PKEY_get1_DSA(pkey); ! EVP_PKEY_free(pkey); ! } ! ! /* Free our "structural" reference. */ ! ENGINE_free(e); ! } ! else { ! BIO_printf(bio_err,"Generating DSA key, %d bits\n", BN_num_bits(dsa->p)); ! if (!DSA_generate_key(dsa)) goto end; ! } app_RAND_write_file(NULL, bio_err); diff -rcP openssl-engine-0.9.6b.pristine/apps/genrsa.c openssl-engine-0.9.6b/apps/genrsa.c *** openssl-engine-0.9.6b.pristine/apps/genrsa.c Thu Sep 21 00:44:18 2000 --- openssl-engine-0.9.6b/apps/genrsa.c Tue Jul 31 11:05:16 2001 *************** *** 92,97 **** --- 92,98 ---- char *passargout = NULL, *passout = NULL; char *engine=NULL; char *inrand=NULL; + char *hwkey=NULL; BIO *out=NULL; apps_startup(); *************** *** 124,129 **** --- 125,135 ---- if (--argc < 1) goto bad; engine= *(++argv); } + else if (strcmp(*argv,"-hwkey") == 0) + { + if (--argc < 1 ) goto bad; + hwkey= *(++argv); + } else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) goto bad; *************** *** 149,154 **** --- 155,170 ---- argv++; argc--; } + + /* engine must be specfied it hwkey is used */ + if(hwkey != NULL) { + if(engine == NULL) { + goto bad; + }else{ + BIO_printf(bio_err,"This key will be linked to key %s stored on %s hardware \n", hwkey, engine); + } + } + if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0))) { bad: *************** *** 163,168 **** --- 179,185 ---- BIO_printf(bio_err," -f4 use F4 (0x10001) for the E value\n"); BIO_printf(bio_err," -3 use 3 for the E value\n"); BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); + BIO_printf(bio_err," -hwkey keyname real key is stored on engine hardware device.\n"); BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err," load the file (or the files in the directory) into\n"); BIO_printf(bio_err," the random number generator\n"); *************** *** 222,231 **** BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); ! BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n", ! num); ! rsa=RSA_generate_key(num,f4,genrsa_cb,bio_err); ! app_RAND_write_file(NULL, bio_err); if (rsa == NULL) goto err; --- 239,270 ---- BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); ! /* load the key from the hardware */ ! if ( hwkey != NULL ) { ! EVP_PKEY *pkey; ! ! if((e = ENGINE_by_id(engine)) == NULL) ! { ! BIO_printf(bio_err,"invalid engine \"%s\"\n", ! engine); ! goto err; ! } ! ! pkey = ENGINE_load_private_key(e, hwkey, NULL); ! if ( pkey ) { ! rsa = EVP_PKEY_get1_RSA(pkey); ! EVP_PKEY_free(pkey); ! } ! ! /* Free our "structural" reference. */ ! ENGINE_free(e); ! } ! else { ! BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n", ! num); ! rsa=RSA_generate_key(num,f4,genrsa_cb,bio_err); ! } ! app_RAND_write_file(NULL, bio_err); if (rsa == NULL) goto err; diff -rcP openssl-engine-0.9.6b.pristine/crypto/engine/Makefile openssl-engine-0.9.6b/crypto/engine/Makefile *** openssl-engine-0.9.6b.pristine/crypto/engine/Makefile Thu Sep 7 20:57:29 2000 --- openssl-engine-0.9.6b/crypto/engine/Makefile Tue Jul 31 11:05:15 2001 *************** *** 23,31 **** LIB=$(TOP)/libcrypto.a LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ ! hw_atalla.c hw_cswift.c hw_ncipher.c LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ ! hw_atalla.o hw_cswift.o hw_ncipher.o SRC= $(LIBSRC) --- 23,31 ---- LIB=$(TOP)/libcrypto.a LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ ! hw_atalla.c hw_cswift.c hw_ncipher.c hw_eracom.c LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ ! hw_atalla.o hw_cswift.o hw_ncipher.o hw_eracom.o SRC= $(LIBSRC) diff -rcP openssl-engine-0.9.6b.pristine/crypto/engine/Makefile.ssl openssl-engine-0.9.6b/crypto/engine/Makefile.ssl *** openssl-engine-0.9.6b.pristine/crypto/engine/Makefile.ssl Thu Sep 7 20:57:29 2000 --- openssl-engine-0.9.6b/crypto/engine/Makefile.ssl Tue Jul 31 11:05:15 2001 *************** *** 23,31 **** LIB=$(TOP)/libcrypto.a LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ ! hw_atalla.c hw_cswift.c hw_ncipher.c LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ ! hw_atalla.o hw_cswift.o hw_ncipher.o SRC= $(LIBSRC) --- 23,31 ---- LIB=$(TOP)/libcrypto.a LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ ! hw_atalla.c hw_cswift.c hw_ncipher.c hw_eracom.c LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ ! hw_atalla.o hw_cswift.o hw_ncipher.o hw_eracom.o SRC= $(LIBSRC) diff -rcP openssl-engine-0.9.6b.pristine/crypto/engine/engine_int.h openssl-engine-0.9.6b/crypto/engine/engine_int.h *** openssl-engine-0.9.6b.pristine/crypto/engine/engine_int.h Fri Jul 7 04:39:27 2000 --- openssl-engine-0.9.6b/crypto/engine/engine_int.h Tue Jul 31 11:05:15 2001 *************** *** 151,156 **** --- 151,160 ---- ENGINE *ENGINE_atalla(); #endif /* !NO_HW_ATALLA */ + #ifndef NO_HW_ERACOM + ENGINE *ENGINE_eracom(); + #endif /* !NO_HW_ERACOM */ + #endif /* !NO_HW */ #ifdef __cplusplus diff -rcP openssl-engine-0.9.6b.pristine/crypto/engine/engine_list.c openssl-engine-0.9.6b/crypto/engine/engine_list.c *** openssl-engine-0.9.6b.pristine/crypto/engine/engine_list.c Fri Jun 30 21:01:56 2000 --- openssl-engine-0.9.6b/crypto/engine/engine_list.c Tue Jul 31 11:05:15 2001 *************** *** 198,203 **** --- 198,207 ---- if(!engine_list_add(ENGINE_atalla())) return 0; #endif /* !NO_HW_ATALLA */ + #ifndef NO_HW_ERACOM + if(!engine_list_add(ENGINE_eracom())) + return 0; + #endif /* !NO_HW_ERACOM */ #endif /* !NO_HW */ engine_list_flag = 1; return 1; diff -rcP openssl-engine-0.9.6b.pristine/crypto/engine/hw_eracom.c openssl-engine-0.9.6b/crypto/engine/hw_eracom.c *** openssl-engine-0.9.6b.pristine/crypto/engine/hw_eracom.c Thu Jan 1 10:00:00 1970 --- openssl-engine-0.9.6b/crypto/engine/hw_eracom.c Tue Jul 31 11:05:15 2001 *************** *** 0 **** --- 1,1731 ---- + /* + * $Id: hw_eracom.c,v 1.16 2001/07/25 05:31:23 zoran Exp $ + * $Author: zoran $ + * + * Copyright (c) 2001 ERACOM Pty. Ltd. + * All Rights Reserved - Proprietary Information of ERACOM Pty. Ltd. + * Not to be Construed as a Published Work. + * + * $Source: /eracom/cvs/prod/cprov/apps/openssl/hw_eracom.c,v $ + * $Revision: 1.16 $ + * $Date: 2001/07/25 05:31:23 $ + */ + + /* Written by Bernard Leach (bernard.leach@eracom-tech.com) + * and Zoran.Radenkovic (zoran.radenkovic@eracom-tech.com) + */ + + #include + #include + #include + + #include "engine_int.h" + #include + #include + #include + #include + + #ifndef NO_HW + #ifndef NO_HW_PKCS11 + + /* Attribution notice: + * Eracom-Techologies header files included: + * cryptoki.h, & pkcs11f.h + * blah, blah ... + * + */ + #ifdef FLAT_INC + #include "cryptoki.h" + #else + #include "vendor_defns/cryptoki.h" + #endif + + /* + * TODO: this library should come from (int this order) + * runtime configuration, environment variable, this value + * only enviroment variable and this value is implemented + */ + #define VAR_LIBNAME "PKCS11_LIB" + #define VAR_SLOTPIN_HEAD "PKCS_SLOT_" + #define VAR_SLOTPIN_TAIL "_PIN" + #define PK11_LIBNAME "cryptoki" + #define KEYID "ERACOM/" + #define KEYSEP '/' + + /* + * TODO: current the user PIN supplied only as enviroment variable "PKCS_SLOT__PIN" + * or with load_pubkey call + */ + #define USER_PIN "0000" + #define USER_PIN_SIZE 50 + #define MAX_SLOT 20 + + #define PK11_GET_F_LIST "C_GetFunctionList" + + #define SSL_SIG_LENGTH 36 + + #if 0 + #define ERACOM_PKCS11 + #endif + + static DSO *eracom_dso = NULL; + static CK_FUNCTION_LIST_PTR pFunctionList = NULL; + + /* TODO: This global session is used for the random generation function */ + static CK_SESSION_HANDLE hSes = CK_INVALID_HANDLE; + + static int rsaindex = -1; + static int dsaindex = -1; + static int dhindex = -1; + + static CK_BBOOL True = 1; + static CK_OBJECT_CLASS ClassPrivate = CKO_PRIVATE_KEY; + static CK_OBJECT_CLASS ClassPublic = CKO_PUBLIC_KEY; + static CK_OBJECT_CLASS ClassGeneric = CKO_SECRET_KEY; + static CK_KEY_TYPE KeyTypeRSA = CKK_RSA; + static CK_KEY_TYPE KeyTypeDSA = CKK_DSA; + static CK_KEY_TYPE KeyTypeDH = CKK_DH; + static CK_KEY_TYPE KeyTypeGeneric = CKK_GENERIC_SECRET; + + /* A key consists of a session and a object handle */ + typedef struct { + CK_SESSION_HANDLE hSes; + CK_OBJECT_HANDLE hObjPri; + CK_OBJECT_HANDLE hObjPub; + /* members below are used only for key stored in hw */ + CK_CHAR_PTR key_name; + CK_SLOT_ID slotId; + } KeyHandle; + + /* structure for user's PINs */ + typedef struct { + CK_SLOT_ID slotId; + CK_CHAR_PTR pin; + } UserPin; + + /* staticly allocate memeory for maxumum nuber of slots */ + static UserPin UserPIN[MAX_SLOT]; + + /* + * convert a OpenSSL BN to a PKCS#11 BigInteger attribute + * note, the result must be OPENSSL_free'ed + */ + #define BN_TO_P11(a, bn) { \ + a.valueLen = BN_num_bytes(bn); \ + a.pValue = OPENSSL_malloc(a.valueLen); \ + BN_bn2bin(bn, a.pValue); } + /* + * Get user's PINs from enviroment + */ + void + GetUserPINEnv(void) + { + extern char **environ; + char *p0, *p1, *p2, slot[5]; + int i = 0, ord = 0; + + for(ord=0; ord < MAX_SLOT; ord++) { + UserPIN[ord].pin = NULL; + } + ord = 0; + + while(environ[i]) { + if(strncmp(environ[i], VAR_SLOTPIN_HEAD, strlen(VAR_SLOTPIN_HEAD)) == 0) { + /* TODO: this parse is not perfect, but this is not final solution for PIN */ + p0 = &environ[i][sizeof(VAR_SLOTPIN_HEAD) - 1]; + if((p1 = strstr(p0,VAR_SLOTPIN_TAIL)) == NULL) continue; + if((p2 = strchr(p1,'=')) == NULL) continue; + strncpy(slot,p0,(int)(p1-p0)); + UserPIN[ord].slotId = (CK_SLOT_ID)strtol(slot, (char **)NULL, 10); + UserPIN[ord].pin = OPENSSL_malloc(strlen(++p2)+1); + strcpy(UserPIN[ord].pin,p2); + ord++; + } + i++; + } + } + /* + * Get user PIN + */ + CK_RV + GetUserPIN(KeyHandle *obj, char *user_pin) + { + char *prompt; + int i = 0; + + /* check first do we already have PIN fro the slot */ + while(UserPIN[i].pin != NULL) { + if(UserPIN[i].slotId == obj->slotId) { + strcpy(user_pin, UserPIN[i].pin); + return(CKR_OK); + } + i++; + } + + /* this is last resort which doesn't work if application detach from terminal like Apache */ + prompt = "Enter User's PIN:"; + for (;;) { + if ((i = EVP_read_pw_string(user_pin, USER_PIN_SIZE, prompt, FALSE)) != 0) { + ENGINEerr(ENGINE_F_PKC11_LOAD_PIN, ENGINE_R_INVALID_INPUT); + memset(user_pin, 0, (unsigned int)USER_PIN_SIZE); + return(!CKR_OK); + } + if (strlen(user_pin) < 1) { + prompt = "Invalid User's PIN, try again:"; + continue; + } + else + break; + } + return(CKR_OK); + } + /* + * SetUserPIN + */ + void + SetUserPIN(CK_SLOT_ID slotId, const char *passphrase) + { + int i = 0; + + while(UserPIN[i].pin != NULL) { + if(UserPIN[i].slotId == slotId) { + if(strlen(UserPIN[i].pin) < strlen(passphrase)) { + OPENSSL_free(UserPIN[i].pin); + UserPIN[i].pin = OPENSSL_malloc(strlen(passphrase)+1); + } + strcpy(UserPIN[i].pin,passphrase); + return; + } + i++; + } + + UserPIN[i].slotId = slotId; + UserPIN[i].pin = OPENSSL_malloc(strlen(passphrase)+1); + strcpy(UserPIN[i].pin,passphrase); + + return; + } + + /* + * Free user PIN memory + */ + void + FreeUserPINs(void) + { + int i = 0; + + while(UserPIN[i].pin != NULL) { + OPENSSL_free(UserPIN[i++].pin); + } + } + /* DEBUG */ + void PrintBin(const char *key, CK_ULONG len) + { + int i = 0; + + while(ihObjPri = CK_INVALID_HANDLE; + obj->hObjPub = CK_INVALID_HANDLE; + obj->key_name = NULL; + obj->slotId = slotId; + + /* find out is the key stored in h/w */ + if ( rsa != NULL ) { + buf = OPENSSL_malloc(BN_num_bytes(rsa->iqmp)); + if ( buf == NULL ) { + ENGINEerr(ENGINE_F_PKC11_KEY_HANDLE, ERR_R_MALLOC_FAILURE); + OPENSSL_free(obj); + return NULL; + } + + len = BN_bn2bin(rsa->iqmp, (unsigned char *)buf); + } + else if (dsa != NULL) { + buf = OPENSSL_malloc(BN_num_bytes(dsa->priv_key)); + if ( buf == NULL ) { + ENGINEerr(ENGINE_F_PKC11_KEY_HANDLE, ERR_R_MALLOC_FAILURE); + OPENSSL_free(obj); + return NULL; + } + + len = BN_bn2bin(dsa->priv_key, (unsigned char *)buf); + } + else if (dh != NULL) { + buf = OPENSSL_malloc(BN_num_bytes(dh->priv_key)); + if ( buf == NULL ) { + ENGINEerr(ENGINE_F_PKC11_KEY_HANDLE, ERR_R_MALLOC_FAILURE); + OPENSSL_free(obj); + return NULL; + } + + len = BN_bn2bin(dh->priv_key, (unsigned char *)buf); + } + + + /* + * check if rsa->iqmp/dsa->priv_key matches key-identifier form: + * ERACOM/[slot/]key-name + */ + if ( buf != NULL && strncmp(buf,KEYID, 7) == 0 ) { + /* extract key name, and find it */ + obj->key_name = OPENSSL_malloc(len - 6); + if ( obj->key_name == NULL ) { + ENGINEerr(ENGINE_F_PKC11_KEY_HANDLE, ERR_R_MALLOC_FAILURE); + OPENSSL_free(buf); + OPENSSL_free(obj); + + return NULL; + } + + /* check for optional slot identifier */ + pdel = strchr(&buf[7],KEYSEP); + if ( pdel == NULL ) { + strcpy((char *)obj->key_name, &buf[7]); + } + else { + slotId = (CK_SLOT_ID)strtol(&buf[7], (char **)NULL, 10); + obj->slotId = slotId; + strcpy((char *)obj->key_name, pdel + 1); + } + } + + + if (buf) OPENSSL_free(buf); /* free buf */ + + rv = pFunctionList->C_OpenSession(slotId, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &obj->hSes); + if ( rv == CKR_CRYPTOKI_NOT_INITIALIZED ) { + rv = pFunctionList->C_Initialize(NULL_PTR); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_KEY_HANDLE, ENGINE_R_UNIT_FAILURE); + } + else { + rv = pFunctionList->C_OpenSession(slotId, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &obj->hSes); + } + } + + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_KEY_HANDLE, ENGINE_R_NO_SESSION); + ENGINEerr(ENGINE_F_PKC11_KEY_HANDLE, rv); + + OPENSSL_free(obj); + obj = NULL; + } + + return obj; + } + + static CK_RV + FindObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_CLASS cl, + CK_CHAR_PTR name, + CK_OBJECT_HANDLE_PTR phObj) + { + CK_RV rv; + CK_COUNT objectCount = 0; + + CK_ATTRIBUTE tplate[] = { + {CKA_CLASS, NULL, 0}, + {CKA_LABEL, NULL, 0} + }; + + tplate[0].pValue = &cl; + tplate[0].valueLen = sizeof(cl); + + tplate[1].pValue = name; + tplate[1].valueLen = (CK_SIZE)strlen((char *)name); + + rv = pFunctionList->C_FindObjectsInit(hSession, tplate, 2); + if ( rv ) return rv; + rv = pFunctionList->C_FindObjects(hSession, phObj, 1, &objectCount); + if ( rv ) return rv; + #ifndef V1COMPLIANT + rv = pFunctionList->C_FindObjectsFinal(hSession); + if ( rv ) return rv; + #endif + + if ( objectCount != 1 ) return CKR_GENERAL_ERROR; + + return CKR_OK; + } + + CK_RV + CreateRSAPrivateKey(KeyHandle *obj, RSA *rsa) + { + CK_RV rv; + char user_pin[USER_PIN_SIZE]; + + if ( obj->key_name != NULL ) { + if(GetUserPIN(obj, user_pin) != CKR_OK) { + return !CKR_OK; + } + rv = pFunctionList->C_Login(obj->hSes, CKU_USER, (CK_CHAR_PTR)user_pin, strlen(user_pin)); + if ( rv && rv != CKR_USER_ALREADY_LOGGED_IN ) { + ENGINEerr(ENGINE_F_PKC11_RSA_PRIVKEY, ENGINE_R_LOGIN_INVALID); + } + else { + rv = FindObject(obj->hSes, CKO_PRIVATE_KEY, obj->key_name, &obj->hObjPri); + } + } + else { + CK_ATTRIBUTE temp[] = { + { CKA_CLASS, &ClassPrivate, sizeof(ClassPrivate) }, + { CKA_KEY_TYPE, &KeyTypeRSA, sizeof(KeyTypeRSA) }, + { CKA_SIGN, &True, sizeof(True) }, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 }, + { CKA_PRIVATE_EXPONENT, NULL, 0 }, + { CKA_PRIME_1, NULL, 0 }, + { CKA_PRIME_2, NULL, 0 }, + { CKA_EXPONENT_1, NULL, 0 }, + { CKA_EXPONENT_2, NULL, 0 }, + { CKA_COEFFICIENT, NULL, 0 }, + }; + + /* not, create new one */ + BN_TO_P11(temp[3], rsa->n); + BN_TO_P11(temp[4], rsa->e); + BN_TO_P11(temp[5], rsa->d); + BN_TO_P11(temp[6], rsa->p); + BN_TO_P11(temp[7], rsa->q); + BN_TO_P11(temp[8], rsa->dmp1); + BN_TO_P11(temp[9], rsa->dmq1); + BN_TO_P11(temp[10], rsa->iqmp); + + rv = pFunctionList->C_CreateObject(obj->hSes, temp, 11, &obj->hObjPri); + + OPENSSL_free(temp[3].pValue); + OPENSSL_free(temp[4].pValue); + OPENSSL_free(temp[5].pValue); + OPENSSL_free(temp[6].pValue); + OPENSSL_free(temp[7].pValue); + OPENSSL_free(temp[8].pValue); + OPENSSL_free(temp[9].pValue); + OPENSSL_free(temp[10].pValue); + } + + return rv; + } + + CK_RV + CreateRSAPublicKey(KeyHandle *obj, RSA *rsa) + { + CK_RV rv; + + /* TODO: this probably isnt quite right, the key name is stored in private + key file */ + if ( obj->key_name != NULL ) { + rv = FindObject(obj->hSes, CKO_PUBLIC_KEY, obj->key_name, &obj->hObjPri); + } + else { + CK_ATTRIBUTE temp[] = { + { CKA_CLASS, &ClassPublic, sizeof(ClassPublic) }, + { CKA_KEY_TYPE, &KeyTypeRSA, sizeof(KeyTypeRSA) }, + { CKA_VERIFY, &True, sizeof(True) }, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 }, + }; + + /* key is in memory, make up one */ + BN_TO_P11(temp[3], rsa->n); + BN_TO_P11(temp[4], rsa->e); + + rv = pFunctionList->C_CreateObject(obj->hSes, temp, 5, &obj->hObjPub); + + OPENSSL_free(temp[3].pValue); + OPENSSL_free(temp[4].pValue); + } + + return rv; + } + + CK_RV + CreateDSAPrivateKey(KeyHandle *obj, DSA *dsa) + { + CK_RV rv; + char user_pin[USER_PIN_SIZE]; + + if ( obj->key_name != NULL ) { + if(GetUserPIN(obj, user_pin) != CKR_OK) { + return !CKR_OK; + } + rv = pFunctionList->C_Login(obj->hSes, CKU_USER, (CK_CHAR_PTR)user_pin, strlen(user_pin)); + if ( rv && rv != CKR_USER_ALREADY_LOGGED_IN ) { + ENGINEerr(ENGINE_F_PKC11_RSA_PRIVKEY, ENGINE_R_LOGIN_INVALID); + } + else { + rv = FindObject(obj->hSes, CKO_PRIVATE_KEY, obj->key_name, &obj->hObjPri); + } + } + else { + CK_ATTRIBUTE temp[] = { + { CKA_CLASS, &ClassPrivate, sizeof(ClassPrivate) }, + { CKA_KEY_TYPE, &KeyTypeDSA, sizeof(KeyTypeDSA) }, + { CKA_VERIFY, &True, sizeof(True) }, + { CKA_PRIME, NULL, 0 }, + { CKA_SUBPRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + { CKA_VALUE, NULL, 0 }, + }; + + BN_TO_P11(temp[3], dsa->p); + BN_TO_P11(temp[4], dsa->q); + BN_TO_P11(temp[5], dsa->g); + BN_TO_P11(temp[6], dsa->priv_key); + + rv = pFunctionList->C_CreateObject(obj->hSes, temp, 7, &obj->hObjPri); + + OPENSSL_free(temp[3].pValue); + OPENSSL_free(temp[4].pValue); + OPENSSL_free(temp[5].pValue); + OPENSSL_free(temp[6].pValue); + } + + return rv; + } + + CK_RV + CreateDSAPublicKey(KeyHandle *obj, DSA *dsa) + { + CK_RV rv; + + /* TODO: this probably isnt quite right, the key name is stored in private + key file */ + if ( obj->key_name != NULL ) { + rv = FindObject(obj->hSes, CKO_PUBLIC_KEY, obj->key_name, &obj->hObjPri); + } + else { + CK_ATTRIBUTE temp[] = { + { CKA_CLASS, &ClassPublic, sizeof(ClassPublic) }, + { CKA_KEY_TYPE, &KeyTypeDSA, sizeof(KeyTypeDSA) }, + { CKA_VERIFY, &True, sizeof(True) }, + { CKA_PRIME, NULL, 0 }, + { CKA_SUBPRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + { CKA_VALUE, NULL, 0 }, + }; + + BN_TO_P11(temp[3], dsa->p); + BN_TO_P11(temp[4], dsa->q); + BN_TO_P11(temp[5], dsa->g); + BN_TO_P11(temp[6], dsa->pub_key); + + rv = pFunctionList->C_CreateObject(obj->hSes, temp, 7, &obj->hObjPub); + + OPENSSL_free(temp[3].pValue); + OPENSSL_free(temp[4].pValue); + OPENSSL_free(temp[5].pValue); + OPENSSL_free(temp[6].pValue); + } + + return rv; + } + + CK_RV + CreateDHPrivateKey(KeyHandle *obj, DH *dh) + { + CK_RV rv; + char user_pin[USER_PIN_SIZE]; + + if ( obj->key_name != NULL ) { + if(GetUserPIN(obj, user_pin) != CKR_OK) { + return !CKR_OK; + } + rv = pFunctionList->C_Login(obj->hSes, CKU_USER, (CK_CHAR_PTR)user_pin, strlen(user_pin)); + if ( rv && rv != CKR_USER_ALREADY_LOGGED_IN ) { + ENGINEerr(ENGINE_F_PKC11_RSA_PRIVKEY, ENGINE_R_LOGIN_INVALID); + } + else { + rv = FindObject(obj->hSes, CKO_PRIVATE_KEY, obj->key_name, &obj->hObjPri); + } + } + else { + CK_USHORT nbits; + CK_ATTRIBUTE temp[] = { + { CKA_CLASS, &ClassPrivate, sizeof(ClassPrivate) }, + { CKA_KEY_TYPE, &KeyTypeDH, sizeof(KeyTypeDH) }, + { CKA_DERIVE, &True, sizeof(True) }, + { CKA_PRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + { CKA_VALUE, NULL, 0 }, + { CKA_VALUE_BITS, &nbits, sizeof(nbits) }, + }; + + BN_TO_P11(temp[3], dh->p); + BN_TO_P11(temp[4], dh->g); + BN_TO_P11(temp[5], dh->priv_key); + nbits = BN_num_bytes(dh->priv_key) * 8; + + rv = pFunctionList->C_CreateObject(obj->hSes, temp, 7, &obj->hObjPri); + + OPENSSL_free(temp[3].pValue); + OPENSSL_free(temp[4].pValue); + OPENSSL_free(temp[5].pValue); + + } + + return rv; + } + + int + GetRSAKeySize(KeyHandle *obj, RSA *rsa) + { + CK_RV rv; + CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; + CK_ULONG cka_modulus_bits; + CK_ATTRIBUTE temp[] = { + { CKA_MODULUS_BITS, NULL_PTR , sizeof(CK_ULONG) }, + { CKA_MODULUS, NULL_PTR , 0 }, + }; + int key_size; + + temp[0].pValue = &cka_modulus_bits; + + if ( obj->key_name == NULL ) { + /* get key size from rsa struture */ + key_size = RSA_size(rsa); + } + else { + /* get key size from hwkey attributes */ + + if ( obj->hObjPri != CK_INVALID_HANDLE ) { + /* get it from private key */ + hKey = obj->hObjPri; + } + else if( obj->hObjPub != CK_INVALID_HANDLE ) { + /* get it from public key */ + hKey = obj->hObjPub; + } + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, hKey, temp, 1); + if ( rv && rv != CKR_ATTRIBUTE_TYPE_INVALID ) { + /* stick to key size from rsa struture */ + key_size = RSA_size(rsa); + ENGINEerr(ENGINE_F_PKC11_RSA_KEYSIZE, ENGINE_R_CANT_GET_KEYSIZE); + } + else { + if ( temp[0].valueLen ) { + key_size = (int)cka_modulus_bits; + } + else { + /* can't get CKA_MODULUS_BITS, use length of CKA_MODULUS */ + key_size = temp->valueLen * 8; + } + } + } + + return key_size; + } + + /* + * RSA method functions + */ + + static int + eracom_rsa_priv_enc( + int flen, + unsigned char *from, + unsigned char *to, + RSA *rsa, + int padding) + { + KeyHandle *obj; + CK_MECHANISM mech; + CK_RV rv; + CK_SIZE len; + + obj = (KeyHandle *)RSA_get_ex_data(rsa, rsaindex); + if ( !obj ) { + obj = CreateKeyHandle(0, rsa, NULL, NULL); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_RSA_ENCRYPT, ENGINE_R_NO_KEY_HANDLE); + return -1; + } + } + + /* this KeyHandle may have a public key but no private key */ + if ( obj->hObjPri == CK_INVALID_HANDLE ) { + rv = CreateRSAPrivateKey(obj, rsa); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_ENCRYPT, ENGINE_R_REQUEST_FALLBACK); + OPENSSL_free(obj); + return -1; + } + + RSA_set_ex_data(rsa, rsaindex, (char *)obj); + + memset(&mech, 0, sizeof(mech)); + + switch (padding) { + case RSA_PKCS1_PADDING: + mech.mechanism = CKM_RSA_PKCS; + break; + + case RSA_NO_PADDING: + mech.mechanism = CKM_RSA_X_509; + break; + + case RSA_PKCS1_OAEP_PADDING: + mech.mechanism = CKM_RSA_PKCS_OAEP; + case RSA_SSLV23_PADDING: + /* fall through */ + default: + ENGINEerr(ENGINE_F_PKC11_RSA_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + return -1; + } + + rv = pFunctionList->C_EncryptInit(obj->hSes, &mech, obj->hObjPri); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + return 0; + } + } + + /* TODO: to may need leading zero padding */ + len = 128; + rv = pFunctionList->C_Encrypt(obj->hSes, from, flen, to, &len); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + return -1; + } + + return len; + } + + static int + eracom_rsa_priv_dec( + int flen, + unsigned char *from, + unsigned char *to, + RSA *rsa, + int padding) + { + KeyHandle *obj; + CK_MECHANISM mech; + CK_RV rv; + CK_SIZE len; + + obj = (KeyHandle *)RSA_get_ex_data(rsa, rsaindex); + if ( !obj ) { + obj = CreateKeyHandle(0, rsa, NULL, NULL); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_RSA_DECRYPT, ENGINE_R_NO_KEY_HANDLE); + return -1; + } + } + + /* this KeyHandle may have a public key but no private key */ + if ( obj->hObjPri == CK_INVALID_HANDLE ) { + rv = CreateRSAPrivateKey(obj, rsa); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_DECRYPT, ENGINE_R_REQUEST_FALLBACK); + OPENSSL_free(obj); + return -1; + } + + RSA_set_ex_data(rsa, rsaindex, (char *)obj); + + memset(&mech, 0, sizeof(mech)); + + switch (padding) { + case RSA_PKCS1_PADDING: + mech.mechanism = CKM_RSA_PKCS; + break; + + case RSA_NO_PADDING: + mech.mechanism = CKM_RSA_X_509; + break; + + case RSA_PKCS1_OAEP_PADDING: + mech.mechanism = CKM_RSA_PKCS_OAEP; + case RSA_SSLV23_PADDING: + /* fall through */ + default: + ENGINEerr(ENGINE_F_PKC11_RSA_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + return -1; + } + + rv = pFunctionList->C_DecryptInit(obj->hSes, &mech, obj->hObjPri); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + return -1; + } + } + + /* TODO: need to work out the length properly */ + len = 128; + rv = pFunctionList->C_Decrypt(obj->hSes, from, flen, to, &len); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + return -1; + } + + return len; + } + + static CK_RV + DER_encode( + int dtype, + unsigned char *m, + unsigned int m_len, + unsigned char *s, + unsigned int *s_length, + int key_size) + { + X509_SIG sig; + X509_ALGOR algor; + ASN1_TYPE parameter; + ASN1_OCTET_STRING digest; + int s_len; + unsigned char *p; + + /* inititiate sig fields */ + sig.algor = &algor; + sig.algor->algorithm = OBJ_nid2obj(dtype); + if (sig.algor->algorithm == NULL) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return !CKR_OK; + } + + if (sig.algor->algorithm->length == 0) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + return !CKR_OK; + } + + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + sig.algor->parameter = ¶meter; + + sig.digest= &digest; + sig.digest->data = m; + sig.digest->length = m_len; + + /* find length for buffer allocation */ + s_len = i2d_X509_SIG(&sig, NULL); + + if ( (s_len - RSA_PKCS1_PADDING) > key_size ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return !CKR_OK; + } + + /* do the encoding */ + p = s; + i2d_X509_SIG(&sig, &p); + *s_length = s_len; + + return CKR_OK; + } + + static int + eracom_rsa_sign( + int dtype, + unsigned char *m, + unsigned int m_len, + unsigned char *sigret, + unsigned int *siglen, + RSA *rsa) + { + KeyHandle *obj; + CK_RV rv; + CK_MECHANISM mech; + CK_SIZE len; + int key_size; + unsigned int s_len; + unsigned char *s = NULL; + + obj = (KeyHandle *)RSA_get_ex_data(rsa, rsaindex); + if ( !obj ) { + obj = CreateKeyHandle(0, rsa, NULL, NULL); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, ENGINE_R_NO_KEY_HANDLE); + return 0; + } + } + + /* this KeyHandle may have a public key but no private key */ + if ( obj->hObjPri == CK_INVALID_HANDLE ) { + rv = CreateRSAPrivateKey(obj, rsa); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, ENGINE_R_REQUEST_FALLBACK); + OPENSSL_free(obj); + return 0; + } + + RSA_set_ex_data(rsa, rsaindex, (char *)obj); + + #ifdef ERACOM_PKCS11 + /* only for ERACOM's PKCS#11 implementation */ + memset(&mech, 0, sizeof(mech)); + mech.mechanism = CKM_RSA_PKCS; /* mechanisam is always the same */ + + rv = pFunctionList->C_SignInit(obj->hSes, &mech, obj->hObjPri); + if ( rv ) { + if( rv == CKR_KEY_FUNCTION_NOT_PERMITTED) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, ENGINE_R_KEY_FUNCTION_NOT_PERMITTED); + } + else { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_UNKNOWN_PADDING_TYPE); + } + return 0; + } + #endif + } + + key_size = GetRSAKeySize(obj, rsa); + + /* check length only for this one */ + if ( dtype == NID_md5_sha1 ) { + if (m_len != SSL_SIG_LENGTH ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + s = m; + s_len = m_len; + } + else { + /* DER encode digest */ + + /* allocate buffer and do padding */ + s = OPENSSL_malloc(key_size + 1); + if ( s == NULL ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, ERR_R_MALLOC_FAILURE); + return 0; + } + + rv = DER_encode(dtype, m, m_len, s, &s_len, key_size); + if (rv) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_DER_PADDING_FAILED); + return 0; + } + } + + #ifndef ERACOM_PKCS11 + /* strict PKCS#11 implementation */ + memset(&mech, 0, sizeof(mech)); + mech.mechanism = CKM_RSA_PKCS; /* mechanisam is always the same */ + + rv = pFunctionList->C_SignInit(obj->hSes, &mech, obj->hObjPri); + if ( rv ) { + if( rv == CKR_KEY_FUNCTION_NOT_PERMITTED) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, ENGINE_R_KEY_FUNCTION_NOT_PERMITTED); + } + else { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_UNKNOWN_PADDING_TYPE); + } + return 0; + } + #endif + + len = key_size; + rv = pFunctionList->C_Sign(obj->hSes, s, s_len, sigret, &len); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_UNKNOWN_PADDING_TYPE); + return 0; + } + *siglen = len; + + return 1; + } + + static int + eracom_rsa_verify( + int dtype, + unsigned char *m, + unsigned int m_len, + unsigned char *sigbuf, + unsigned int siglen, + RSA *rsa) + { + KeyHandle *obj; + CK_RV rv; + CK_MECHANISM mech; + unsigned int s_len; + unsigned char *s = NULL; + + obj = (KeyHandle *)RSA_get_ex_data(rsa, rsaindex); + if ( !obj ) { + obj = CreateKeyHandle(0, rsa, NULL, NULL); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, ENGINE_R_NO_KEY_HANDLE); + return 0; + } + } + + /* this KeyHandle may have a private key but no public key */ + if ( obj->hObjPub == CK_INVALID_HANDLE ) { + rv = CreateRSAPublicKey(obj, rsa); + + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, ENGINE_R_REQUEST_FALLBACK); + return 0; + } + + RSA_set_ex_data(rsa, rsaindex, (char *)obj); + + #ifdef ERACOM_PKCS11 + /* only for ERACOM's PKCS#11 implementation */ + memset(&mech, 0, sizeof(mech)); + mech.mechanism = CKM_RSA_PKCS; /* mechanisam is always the same */ + + rv = pFunctionList->C_VerifyInit(obj->hSes, &mech, obj->hObjPub); + if ( rv ) { + if( rv == CKR_KEY_FUNCTION_NOT_PERMITTED) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, ENGINE_R_KEY_FUNCTION_NOT_PERMITTED); + } + else { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, RSA_R_UNKNOWN_PADDING_TYPE); + } + return 0; + } + #endif + } + + /* check length only for this one */ + if (dtype == NID_md5_sha1 ) { + if ( m_len != SSL_SIG_LENGTH ) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + s = m; + s_len = m_len; + } + else { + /* DER encode digest */ + + int key_size = GetRSAKeySize(obj, rsa); /* get key size */ + + /* allocate buffer and do padding */ + s = OPENSSL_malloc(key_size + 1); + if ( s == NULL ) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, ERR_R_MALLOC_FAILURE); + return 0; + } + + rv = DER_encode(dtype, m, m_len, s, &s_len, key_size); + if (rv) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, RSA_R_DER_PADDING_FAILED); + return 0; + } + } + + #ifndef ERACOM_PKCS11 + /* strict PKCS#11 implementation */ + memset(&mech, 0, sizeof(mech)); + mech.mechanism = CKM_RSA_PKCS; /* mechanisam is always the same */ + + rv = pFunctionList->C_VerifyInit(obj->hSes, &mech, obj->hObjPub); + if ( rv ) { + if( rv == CKR_KEY_FUNCTION_NOT_PERMITTED) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, ENGINE_R_KEY_FUNCTION_NOT_PERMITTED); + } + else { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, RSA_R_UNKNOWN_PADDING_TYPE); + } + + return 0; + } + #endif + + rv = pFunctionList->C_Verify(obj->hSes, s, s_len, sigbuf, siglen); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_VERIFY, RSA_R_UNKNOWN_PADDING_TYPE); + + return 0; + } + + return 1; + } + + static RSA_METHOD eracom_rsa = { + "PKCS11 RSA", + NULL, + NULL, + eracom_rsa_priv_enc, + eracom_rsa_priv_dec, + NULL, + NULL, + NULL, + NULL, + RSA_FLAG_EXT_PKEY|RSA_FLAG_SIGN_VER, + NULL, + eracom_rsa_sign, + eracom_rsa_verify + }; + + DSA_SIG * + eracom_dsa_sign(const unsigned char *dgst, int dgst_len, DSA *dsa) + { + KeyHandle *obj; + CK_RV rv; + CK_MECHANISM mech; + CK_SIZE len; + unsigned char sigbytes[40]; + DSA_SIG *sig; + + obj = (KeyHandle *)DSA_get_ex_data(dsa, dsaindex); + if ( !obj ) { + obj = CreateKeyHandle(0, NULL, dsa, NULL); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, ENGINE_R_NO_KEY_HANDLE); + return NULL; + } + } + + /* this KeyHandle may have a public key but no private key */ + if ( obj->hObjPri == CK_INVALID_HANDLE ) { + rv = CreateDSAPrivateKey(obj, dsa); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, ENGINE_R_REQUEST_FALLBACK); + OPENSSL_free(obj); + return NULL; + } + + DSA_set_ex_data(dsa, dsaindex, (char *)obj); + + memset(&mech, 0, sizeof(mech)); + mech.mechanism = CKM_DSA; + + rv = pFunctionList->C_SignInit(obj->hSes, &mech, obj->hObjPri); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_UNKNOWN_PADDING_TYPE); + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, rv); + return NULL; + } + } + + len = sizeof(sigbytes); + rv = pFunctionList->C_Sign(obj->hSes, (CK_BYTE_PTR)dgst, dgst_len, sigbytes, &len); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_RSA_SIGN, RSA_R_UNKNOWN_PADDING_TYPE); + return NULL; + } + + sig = DSA_SIG_new(); + if ( sig ) { + sig->r = BN_bin2bn(sigbytes, 20, NULL); + sig->s = BN_bin2bn(sigbytes + 20, 20, NULL); + } + + return sig; + } + + int + eracom_dsa_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) + { + KeyHandle *obj; + CK_RV rv; + CK_MECHANISM mech; + unsigned char sigbytes[40]; + int i; + + obj = (KeyHandle *)DSA_get_ex_data(dsa, dsaindex); + if ( !obj ) { + obj = CreateKeyHandle(0, NULL, dsa, NULL); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_DSA_VERIFY, ENGINE_R_NO_KEY_HANDLE); + return 0; + } + } + + /* this KeyHandle may have a private key but no public key */ + if ( obj->hObjPub == CK_INVALID_HANDLE ) { + rv = CreateDSAPublicKey(obj, dsa); + + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_DSA_VERIFY, ENGINE_R_REQUEST_FALLBACK); + return 0; + } + + DSA_set_ex_data(dsa, dsaindex, (char *)obj); + + memset(&mech, 0, sizeof(mech)); + mech.mechanism = CKM_DSA; /* in this case digest already done */ + + rv = pFunctionList->C_VerifyInit(obj->hSes, &mech, obj->hObjPub); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_DSA_VERIFY, RSA_R_UNKNOWN_PADDING_TYPE); + return 0; + } + } + + /* + * create a single byte array with r and s right justitified + * in their 20 byte fields + */ + memset(sigbytes, 0x0, sizeof(sigbytes)); + i = BN_num_bytes(sig->r); + BN_bn2bin(sig->r, &sigbytes[20-i]); + i = BN_num_bytes(sig->s); + BN_bn2bin(sig->s, &sigbytes[20+20-i]); + + rv = pFunctionList->C_Verify(obj->hSes, (CK_BYTE_PTR)dgst, dgst_len, sigbytes, sizeof(sigbytes)); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_DSA_VERIFY, RSA_R_UNKNOWN_PADDING_TYPE); + return 0; + } + + return 1; + } + + + static DSA_METHOD eracom_dsa = { + "PKCS11 DSA method", + eracom_dsa_sign, + NULL, + eracom_dsa_verify, + NULL, + NULL, + NULL, + NULL, + 0, + NULL + }; + + + int + eracom_dh_compute(unsigned char *key, BIGNUM *pub_key, DH *dh) + { + KeyHandle *obj; + CK_OBJECT_HANDLE hKey; + CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0}; + CK_RV rv; + CK_SIZE len; + CK_ATTRIBUTE temp1[] = { + { CKA_TOKEN, &True, 1 }, + { CKA_CLASS, &ClassGeneric, sizeof(ClassGeneric) }, + { CKA_KEY_TYPE, &KeyTypeGeneric, sizeof(KeyTypeGeneric) }, + { CKA_ENCRYPT, &True, 1}, + { CKA_DECRYPT, &True, 1}, + { CKA_VALUE_LEN, &len, sizeof(CK_SIZE)} + }; + /* assuming that key is big enough */ + CK_ATTRIBUTE temp2[] = { + { CKA_VALUE, NULL, 0 }, + }; + + obj = (KeyHandle *)DH_get_ex_data(dh, dhindex); + if ( !obj ) { + obj = CreateKeyHandle(0, NULL, NULL, dh); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_DH_COMPUTE, ENGINE_R_NO_KEY_HANDLE); + goto err; + } + } + + /* this KeyHandle may have a public key but no private key */ + if ( obj->hObjPri == CK_INVALID_HANDLE ) { + rv = CreateDHPrivateKey(obj, dh); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_DH_COMPUTE, ENGINE_R_REQUEST_FALLBACK); + OPENSSL_free(obj); + goto err; + } + + DH_set_ex_data(dh, dhindex, (char *)obj); + } + + mech.parameterLen = BN_num_bytes(pub_key); + if((mech.pParameter = OPENSSL_malloc(mech.parameterLen)) == NULL) { + ENGINEerr(ENGINE_F_PKC11_DH_COMPUTE, RSA_R_NO_MEMORY); + goto err; + } + len = BN_bn2bin(pub_key, mech.pParameter); + + rv = pFunctionList->C_DeriveKey(obj->hSes, &mech, obj->hObjPri, temp1, 6, &hKey); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_DH_COMPUTE, RSA_R_DERIVATE_KEY); + goto err; + } + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, hKey, temp2, 1); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_DH_COMPUTE, RSA_R_GET_ATTRIBUTE); + goto err; + } + len = temp2[0].valueLen; + temp2[0].pValue = OPENSSL_malloc(len); + rv = pFunctionList->C_GetAttributeValue(obj->hSes, hKey, temp2, 1); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_DH_COMPUTE, RSA_R_GET_ATTRIBUTE); + goto err; + } + + memcpy(key,temp2[0].pValue,len); + + OPENSSL_free(mech.pParameter); + OPENSSL_free(temp2[0].pValue); + + return (len); + err: + if(mech.pParameter) OPENSSL_free(mech.pParameter); + if(temp2[0].pValue) OPENSSL_free(temp2[0].pValue); + return 0; + } + + static DH_METHOD eracom_dh = { + "PKCS11 DH method", + NULL, + eracom_dh_compute, + NULL, + NULL, + NULL, + 0, + NULL + }; + + /* + * This function is called when our key is freed + */ + static void + eracom_ex_free( + void *obj, + void *item, + CRYPTO_EX_DATA *ad, + int index, + long argl, + void *argp) + { + KeyHandle *kh = (KeyHandle *)item; + + if ( !kh ) return; + + if ( kh->hSes != CK_INVALID_HANDLE ) { + #if 0 + /* TODO this is not working, still deletes token objects */ + if ( kh->key_name == NULL ) { /* destroy only non session keys */ + pFunctionList->C_DestroyObject(kh->hSes, kh->hObjPri); + pFunctionList->C_DestroyObject(kh->hSes, kh->hObjPub); + } + #endif + #if 0 + /*** TODO fix multiple logout - maybe we dopn't need to do that - only close the session instead */ + pFunctionList->C_Logout(kh->hSes); + #endif + pFunctionList->C_CloseSession(kh->hSes); + } + + OPENSSL_free(kh->key_name); + OPENSSL_free(kh); + } + + static void + eracom_seed(const void *buf, int num) + { + CK_RV rv; + + rv = pFunctionList->C_SeedRandom(hSes, (CK_BYTE_PTR)buf, num); + if ( rv == CKR_CRYPTOKI_NOT_INITIALIZED ) { + rv = pFunctionList->C_Initialize(NULL_PTR); + if ( rv ) { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES, ENGINE_R_UNIT_FAILURE); + return; + } + rv = pFunctionList->C_OpenSession(0, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &hSes); + if ( rv ) { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES, ENGINE_R_NO_SESSION); + return; + } + rv = pFunctionList->C_SeedRandom(hSes, (CK_BYTE_PTR)buf, num); + } + if ( rv ) { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES, ENGINE_R_REQUEST_FAILED); + } + } + + static int + eracom_bytes(unsigned char *buf, int num) + { + CK_RV rv; + + rv = pFunctionList->C_GenerateRandom(hSes, buf, num); + /* if cryptoki is not initalized for global session, reinit it and try again */ + if ( rv == CKR_CRYPTOKI_NOT_INITIALIZED ) { + rv = pFunctionList->C_Initialize(NULL_PTR); + if ( rv ) { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES, ENGINE_R_UNIT_FAILURE); + return 0; + } + + rv = pFunctionList->C_OpenSession(0, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &hSes); + if ( rv ) { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES, ENGINE_R_NO_SESSION); + return 0; + } + + rv = pFunctionList->C_GenerateRandom(hSes, buf, num); + } + + if ( rv ) { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES, ENGINE_R_REQUEST_FAILED ); + return 0; + } + + return 1; + } + + static int + eracom_status(void) + { + return 1; + } + + static RAND_METHOD eracom_rand = { + /* "PKCS11 RAND method", */ + eracom_seed, + eracom_bytes, + NULL, + NULL, + eracom_bytes /* pseudorand */, + eracom_status, + }; + + static int + eracom_init(void) + { + CK_C_GetFunctionList p; + CK_RV rv; + char *pk11_libname; + + if ( eracom_dso != NULL ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_ALREADY_LOADED); + goto err; + } + + /* Attempt to load PKCS#11 library */ + if((pk11_libname = getenv(VAR_LIBNAME)) == NULL) { + /* use default library name */ + eracom_dso = DSO_load(NULL, PK11_LIBNAME, NULL, DSO_FLAG_NAME_TRANSLATION); + } + else { + /* use enviroment variable */ + eracom_dso = DSO_load(NULL, pk11_libname, NULL, DSO_FLAG_NAME_TRANSLATION); + } + + if ( eracom_dso == NULL ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_DSO_FAILURE); + goto err; + } + + /* get the C_GetFunctionList function from the loaded library */ + p = (CK_C_GetFunctionList)DSO_bind_func(eracom_dso, PK11_GET_F_LIST); + if ( !p ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_DSO_FAILURE); + goto err; + } + + /* get the full function list from the loaded library */ + rv = p(&pFunctionList); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_DSO_FAILURE); + goto err; + } + + /* now initalise the library */ + rv = pFunctionList->C_Initialize(NULL_PTR); /* FIXME: mutex */ + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_UNIT_FAILURE); + goto err; + } + + /* TODO global session used for random */ + rv = pFunctionList->C_OpenSession(0, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &hSes); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_UNIT_FAILURE); + goto err; + } + + GetUserPINEnv(); + + if ( rsaindex == -1 ) { + rsaindex = RSA_get_ex_new_index(0, "PKCS11 RSA Key handle", NULL, NULL, eracom_ex_free); + } + if ( dsaindex == -1 ) { + dsaindex = DSA_get_ex_new_index(0, "PKCS11 DSA Key handle", NULL, NULL, eracom_ex_free); + } + if ( dhindex == -1 ) { + dhindex = DH_get_ex_new_index(0, "PKCS11 DH Key handle", NULL, NULL, eracom_ex_free); + } + + return 1; + + err: + if (eracom_dso) { + DSO_free(eracom_dso); + eracom_dso = NULL; + } + + return 0; + } + + static int + eracom_finish(void) + { + FreeUserPINs(); + + + if ( eracom_dso == NULL ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_NOT_LOADED); + goto err; + } + + assert(pFunctionList != NULL); + + pFunctionList->C_Finalize(NULL); + + if ( !DSO_free(eracom_dso) ) { + ENGINEerr(ENGINE_F_PKC11_FINISH, ENGINE_R_DSO_FAILURE); + goto err; + } + + eracom_dso = NULL; + pFunctionList = NULL; + + return 1; + + err: + return 0; + } + + static int + eracom_ctrl(int cmd, long i, void *p, void (*f)()) + { + SetUserPIN(0,"0000"); + ENGINEerr(ENGINE_F_PKC11_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 1; + } + + /* forward reference */ + static ENGINE eracom_engine; + + /* + * Load a key based on the supplied reference. + */ + static EVP_PKEY * + eracom_load_privkey(const char *key_id, const char *passphrase) + { + EVP_PKEY *key = NULL; + RSA *rsa_key = NULL; + DSA *dsa_key = NULL; + CK_RV rv; + CK_KEY_TYPE type; + KeyHandle *obj = NULL; + CK_SLOT_ID slotId = 0; + char *pdel, *key_name = (char *)key_id; + char user_pin[USER_PIN_SIZE]; + + /* extract slot id from key_id */ + pdel = strchr(key_id, KEYSEP); + if ( pdel != NULL ) { + slotId = (CK_SLOT_ID)strtol(key_id, (char **)NULL, 10); + key_name = pdel + 1; + } + + if(passphrase != NULL) { + SetUserPIN(slotId,passphrase); + } + + obj = CreateKeyHandle(slotId, NULL, NULL, NULL); + if ( !obj ) { + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_NO_KEY_HANDLE); + return 0; + } + + if(GetUserPIN(obj, user_pin) != CKR_OK) { + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_USER_PIN); + goto err; + } + + rv = pFunctionList->C_Login(obj->hSes, CKU_USER, (CK_CHAR_PTR)user_pin, strlen(user_pin)); + if ( rv && rv != CKR_USER_ALREADY_LOGGED_IN ) { + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_LOGIN_INVALID); + return 0; + } + + rv = FindObject(obj->hSes, CKO_PRIVATE_KEY, (CK_CHAR_PTR)key_name, &obj->hObjPri); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_NO_KEY); + goto err; + } + + { /* get key type */ + CK_ATTRIBUTE temp[] = { + { CKA_KEY_TYPE, &type, sizeof(CK_KEY_TYPE) }, + }; + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, obj->hObjPri, temp, 1); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_NO_KEY); + goto err; + } + + } + + switch(type) { + case CKK_RSA: + { + CK_ATTRIBUTE temp[] = { + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 }, + }; + char buf[256]; + + rsa_key = RSA_new_method(&eracom_engine); + RSA_set_ex_data(rsa_key, rsaindex, (char *)obj); + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, obj->hObjPri, temp, 2); + + temp[0].pValue = OPENSSL_malloc(temp[0].valueLen); + temp[1].pValue = OPENSSL_malloc(temp[1].valueLen); + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, obj->hObjPri, temp, 2); + + sprintf(buf, "ERACOM/%s", key_id); + + rsa_key->n = BN_bin2bn(temp[0].pValue, temp[0].valueLen, NULL); + rsa_key->e = BN_bin2bn(temp[1].pValue, temp[1].valueLen, NULL); + rsa_key->d = BN_new(); BN_one(rsa_key->d); + rsa_key->p = BN_new(); BN_one(rsa_key->p); + rsa_key->q = BN_new(); BN_one(rsa_key->q); + rsa_key->dmp1 = BN_new(); BN_one(rsa_key->dmp1); + rsa_key->dmq1 = BN_new(); BN_one(rsa_key->dmq1); + rsa_key->iqmp = BN_bin2bn((unsigned char *)buf, strlen(buf)+1, NULL); + + OPENSSL_free(temp[0].pValue); + OPENSSL_free(temp[1].pValue); + + key = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(key, rsa_key); + + break; + } + case CKK_DSA: + { + CK_ATTRIBUTE temp[] = { + { CKA_PRIME, NULL, 0 }, + { CKA_SUBPRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + }; + CK_ATTRIBUTE temp1[] = { + { CKA_VALUE, NULL, 0 }, + }; + char buf[256]; + + dsa_key = DSA_new_method(&eracom_engine); + DSA_set_ex_data(dsa_key, dsaindex, (char *)obj); + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, obj->hObjPri, temp, 3); + temp[0].pValue = OPENSSL_malloc(temp[0].valueLen); + temp[1].pValue = OPENSSL_malloc(temp[1].valueLen); + temp[2].pValue = OPENSSL_malloc(temp[2].valueLen); + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, obj->hObjPri, temp, 3); + + sprintf(buf, "ERACOM/%s", key_id); + + dsa_key->p = BN_bin2bn(temp[0].pValue, temp[0].valueLen, NULL); + dsa_key->q = BN_bin2bn(temp[1].pValue, temp[1].valueLen, NULL); + dsa_key->g = BN_bin2bn(temp[2].pValue, temp[2].valueLen, NULL); + + dsa_key->priv_key = BN_bin2bn((unsigned char *)buf, strlen(buf)+1, NULL); + + OPENSSL_free(temp[0].pValue); + OPENSSL_free(temp[1].pValue); + OPENSSL_free(temp[2].pValue); + + /* retrive public key for getting value y */ + rv = FindObject(obj->hSes, CKO_PUBLIC_KEY, (CK_CHAR_PTR)key_name, &obj->hObjPub); + if ( rv ) { + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_NO_KEY); + goto err; + } + + rv = pFunctionList->C_GetAttributeValue(obj->hSes, obj->hObjPub, temp1, 1); + temp1[0].pValue = OPENSSL_malloc(temp1[0].valueLen); + rv = pFunctionList->C_GetAttributeValue(obj->hSes, obj->hObjPub, temp1, 1); + + dsa_key->pub_key = BN_bin2bn(temp1[0].pValue, temp1[0].valueLen, NULL); + + key = EVP_PKEY_new(); + EVP_PKEY_assign_DSA(key, dsa_key); + + break; + } + case CKK_DH: + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_NOT_IMPLEMENTED); + default: + ENGINEerr(ENGINE_F_PKC11_LOAD_PRIVKEY, ENGINE_R_UNKNOW_KEYTYPE); + } + + return key; + + err: + if ( obj ) { + if ( obj->hSes != CK_INVALID_HANDLE ) pFunctionList->C_CloseSession(obj->hSes); + OPENSSL_free(obj); + } + if ( rsa_key ) RSA_free(rsa_key); + if ( dsa_key ) DSA_free(dsa_key); + if ( key ) EVP_PKEY_free(key); + return NULL; + } + + #if 0 + static EVP_PKEY * + eracom_load_pubkey(const char *key_id, const char *passphrase) + { + } + #endif + + + static ENGINE eracom_engine = { + "ERACOM", + "ERACOM", + &eracom_rsa, + &eracom_dsa, + &eracom_dh, + &eracom_rand, + NULL, + NULL, + eracom_init, + eracom_finish, + eracom_ctrl, + eracom_load_privkey, + NULL /* eracom_load_pubkey */, + ENGINE_METHOD_RSA|ENGINE_METHOD_DSA|ENGINE_METHOD_DH|ENGINE_METHOD_RAND, /* flags */ + 0, 0, + NULL, + NULL + }; + + ENGINE *ENGINE_eracom() + { + return &eracom_engine; + } + + #endif + #endif + diff -rcP openssl-engine-0.9.6b.pristine/crypto/engine/vendor_defns/cryptoki.h openssl-engine-0.9.6b/crypto/engine/vendor_defns/cryptoki.h *** openssl-engine-0.9.6b.pristine/crypto/engine/vendor_defns/cryptoki.h Thu Jan 1 10:00:00 1970 --- openssl-engine-0.9.6b/crypto/engine/vendor_defns/cryptoki.h Tue Jul 31 11:05:16 2001 *************** *** 0 **** --- 1,1197 ---- + This file is Copyright 2001 Eracom Technologies Australia Ltd. + + This file is provided for your information and assistance. You are permitted to copy it, to use it to create compatible software, and for review and comment. However, you may not distribute changed versions or other derivative works. All other rights are reserved. + + IN NO EVENT SHALL Eracom Technologies (`ERACOM`) BE LIABLE for any damages arising directly or indirectly from this file, its use or this licence. Without prejudice to the generality of the foregoing: all liability shall be excluded for direct, indirect, special, incidental, consequential or other damages or any loss of profits, business, revenue goodwill or anticipated savings; liability shall be excluded even if ERACOM or anyone else has been advised of the possibility of damage. + In any case the liability of ERACOM shall be reduced to the minimum legally possible under any applicable legislation. + + ERACOM SPECIFICALLY DISCLAIM ALL AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not limited to, any implied warranties of merchantability, fitness for a particular purpose, satisfactory quality, and/or non-infringement of any third party rights. + In any case the warranty of ERACOM shall be reduced to the minimum legally possible under any applicable legislation. + + By using or distributing this file you will be accepting these terms and conditions, including the limitation of liability and lack of warranty. If you do not wish to accept these terms and conditions, DO NOT USE THE FILE. + + /* + * $Id: cryptoki.h,v 1.13 2001/04/30 01:01:08 simon Exp $ + * $Author: simon $ + * + * Copyright (c) 1997-2000 ERACOM Pty. Ltd. + * All Rights Reserved - Proprietary Information of ERACOM Pty. Ltd. + * Not to be Construed as a Published Work. + * + * $Source: /eracom/cvs/prod/include/cryptoki.h,v $ + * $Revision: 1.13 $ + * $Date: 2001/04/30 01:01:08 $ + */ + + /* + * CRYPTOKI.H + * Derived from + * PKCS-11 (CRYPTOKI) V 1.0 and V 2.01 specifications. + */ + + #ifndef CRYPTOKI_INCLUDED + #define CRYPTOKI_INCLUDED + + + #if defined(_WINDOWS) + # if defined(WIN32) + # define CK_CALLBACK __stdcall + # define CK_ENTRY __declspec( dllexport ) + # define CK_PTR * /* definition for Win32 */ + # else /* win16 */ + # define CK_ENTRY _export _far _pascal + # define CK_PTR far * /* definition for Win16 */ + # endif + # pragma pack(push,cryptoki,1) + #elif defined (INSAM) /* SAMs */ + # define CK_ENTRY _loadds far + # define CK_PTR * + # define CK_CALLBACK + # pragma pack(1) + #else /* not INSAM or Windows */ + # define CK_ENTRY + # define CK_PTR * /* definition for UNIX */ + # define CK_CALLBACK + #if !defined(sun) && !defined(__arm) + # pragma pack(1) + #endif + #endif + + #ifndef FALSE + #define FALSE 0 + #endif + + #ifndef TRUE + #define TRUE (!FALSE) + #endif + + /* an unsigned 8-bit value */ + typedef unsigned char CK_BYTE; + + /* an unsigned 8-bit character */ + typedef CK_BYTE CK_CHAR; + + /* a BYTE-sized Boolean flag */ + typedef CK_BYTE CK_BBOOL; + + /* an unsigned value, at least 16 bits long */ + typedef unsigned short int CK_USHORT; + + /* an unsigned value, at least 32 bits long */ + typedef unsigned long int CK_ULONG; + + typedef void CK_VOID; + + /* at least 32 bits, each bit is a Boolean flag */ + typedef CK_ULONG CK_FLAGS; + + typedef CK_BYTE * CK_BYTE_PTR; + typedef CK_CHAR * CK_CHAR_PTR; + typedef CK_USHORT * CK_USHORT_PTR; + typedef CK_ULONG * CK_ULONG_PTR; + typedef CK_BBOOL * CK_BBOOL_PTR; + typedef CK_VOID * CK_VOID_PTR; + typedef CK_VOID_PTR * CK_VOID_PTR_PTR; + + /* Additional definitions to avoid problems when changing to V 2.0 */ + #ifdef V1COMPLIANT + + typedef CK_USHORT CK_SIZE; + typedef CK_USHORT CK_COUNT; + typedef CK_USHORT CK_NUMERIC; + #define CK_VENDOR_DEFINED 0x8000 + #undef V2COMPLIANT + + #else + + typedef CK_ULONG CK_SIZE; + typedef CK_ULONG CK_COUNT; + typedef CK_ULONG CK_NUMERIC; + #define CK_VENDOR_DEFINED 0x80000000 + #ifndef V2COMPLIANT + #define V2COMPLIANT + #endif + + #endif + + #define CK_VENDOR_DEFINED_V1 0x8000 + #define CK_VENDOR_DEFINED_V2 0x80000000 + + typedef CK_SIZE * CK_SIZE_PTR; + typedef CK_COUNT * CK_COUNT_PTR; + + #define NULL_PTR ((CK_VOID_PTR)0) + typedef CK_ULONG CK_AUTH_TYPE; + #define CKT_PIN 0x00000000 + + typedef CK_ULONG CK_PIN_CHAR_SET; + #define CKP_NUMERIC 0x00000000 + #define CKP_UTF8 0x00000001 + #define CKP_BINARY 0x00000002 + + #ifdef __arm + #define PACKED __packed + #else + #define PACKED + #endif + + typedef PACKED struct CK_VERSION { + CK_BYTE major; + CK_BYTE minor; + } CK_VERSION; + typedef CK_VERSION * CK_VERSION_PTR; + + /* Non standard definitions */ + #define CK_MANUFACTURER_SIZE 32 + #define CK_SERIAL_NUMBER_SIZE 16 + #define CK_TIME_SIZE 16 + #define CK_LIB_DESC_SIZE 32 + #define CK_SLOT_DESCRIPTION_SIZE 64 + #define CK_SLOT_MANUFACTURER_SIZE 32 + #define CK_MAX_PIN_LEN 32 + #define CK_TOKEN_LABEL_SIZE 32 + #define CK_TOKEN_MANUFACTURER_SIZE 32 + #define CK_TOKEN_MODEL_SIZE 16 + #define CK_TOKEN_SERIAL_NUMBER_SIZE 16 + #define CK_TOKEN_TIME_SIZE 16 + #define CK_MAX_PBE_IV_SIZE 8 + /* AES is the largest with a 16 byte block size */ + #define CK_MAX_PAD_SIZE 16 + /* end Non standard definitions */ + + typedef struct CK_INFO { + #ifdef V1COMPLIANT + CK_VERSION version; + #else + CK_VERSION cryptokiVersion; + #endif + CK_CHAR manufacturerID[CK_MANUFACTURER_SIZE]; + CK_FLAGS flags; + #ifndef V1COMPLIANT + CK_CHAR libraryDescription[CK_LIB_DESC_SIZE]; + CK_VERSION libraryVersion; + #endif + } CK_INFO; + typedef CK_INFO * CK_INFO_PTR; + + typedef CK_NUMERIC CK_NOTIFICATION; + #define CKN_SURRENDER 0 + #ifdef V1COMPLIANT + #define CKN_COMPLETE 1 + #define CKN_DEVICE_REMOVED 2 + #endif + + typedef CK_ULONG CK_SLOT_ID; + typedef CK_SLOT_ID * CK_SLOT_ID_PTR; + + typedef struct CK_SLOT_INFO { + CK_CHAR slotDescription[CK_SLOT_DESCRIPTION_SIZE]; + CK_CHAR manufacturerID[CK_SLOT_MANUFACTURER_SIZE]; + CK_FLAGS flags; + #ifndef V1COMPLIANT + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; + #endif + } CK_SLOT_INFO; + typedef CK_SLOT_INFO * CK_SLOT_INFO_PTR; + + typedef struct CK_TOKEN_INFO { + CK_CHAR label[CK_TOKEN_LABEL_SIZE]; + CK_CHAR manufacturerID[CK_TOKEN_MANUFACTURER_SIZE]; + CK_CHAR model[CK_TOKEN_MODEL_SIZE]; + CK_CHAR serialNumber[CK_TOKEN_SERIAL_NUMBER_SIZE]; + CK_FLAGS flags; + CK_COUNT maxSessionCount; + CK_COUNT sessionCount; + CK_COUNT maxRwSessionCount; + CK_COUNT rwSessionCount; + CK_SIZE maxPinLen; + CK_SIZE minPinLen; + CK_ULONG totalPublicMemory; + CK_ULONG freePublicMemory; + CK_ULONG totalPrivateMemory; + CK_ULONG freePrivateMemory; + #ifndef V1COMPLIANT + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; + CK_CHAR utcTime[CK_TOKEN_TIME_SIZE]; + #endif + } CK_TOKEN_INFO; + typedef CK_TOKEN_INFO * CK_TOKEN_INFO_PTR; + + #define CK_UNAVAILABLE_INFORMATION (~0UL) + #define CK_EFFECTIVELY_INFINITE 0 + + typedef CK_ULONG CK_SESSION_HANDLE; + typedef CK_SESSION_HANDLE * CK_SESSION_HANDLE_PTR; + + #define CKU_SO 0 /* Security Officer */ + #define CKU_USER 1 /* Normal user */ + + typedef CK_NUMERIC CK_USER_TYPE; + typedef CK_USER_TYPE * CK_USER_TYPE_PTR; + + #define CKS_RO_PUBLIC_SESSION 0 + #define CKS_RO_USER_FUNCTIONS 1 + #define CKS_RW_PUBLIC_SESSION 2 + #define CKS_RW_USER_FUNCTIONS 3 + #define CKS_RW_SO_FUNCTIONS 4 + typedef CK_NUMERIC CK_STATE; + typedef CK_STATE * CK_STATE_PTR; + + typedef struct CK_SESSION_INFO { + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; + CK_NUMERIC deviceError; + } CK_SESSION_INFO; + typedef CK_SESSION_INFO * CK_SESSION_INFO_PTR; + + typedef CK_ULONG CK_OBJECT_HANDLE; + typedef CK_OBJECT_HANDLE * CK_OBJECT_HANDLE_PTR; + + #define CK_INVALID_HANDLE 0 + + /* slot info flags */ + #define CKF_TOKEN_PRESENT 0x0001 + #define CKF_REMOVABLE_DEVICE 0x0002 + #define CKF_HW_SLOT 0x0004 + + /* token info flags */ + #define CKF_RNG 0x0001 + #define CKF_WRITE_PROTECTED 0x0002 + #define CKF_LOGIN_REQUIRED 0x0004 + #define CKF_USER_PIN_INITIALIZED 0x0008 + #define CKF_EXCLUSIVE_EXISTS 0x0010 + #define CKF_RESTORE_KEY_NOT_NEEDED 0x0020 + #define CKF_CLOCK_ON_TOKEN 0x0040 + #ifdef NAME32 + #define CKF_PROTECTED_AUTHENTICATION_PA 0x0100 + #else + #define CKF_PROTECTED_AUTHENTICATION_PATH 0x0100 + #endif + #define CKF_TOKEN_INITIALIZED 0x00000400 + #define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200 + #define CKF_SECONDARY_AUTHENTICATION 0x00000800 + #define CKF_USER_PIN_COUNT_LOW 0x00010000 + #define CKF_USER_PIN_FINAL_TRY 0x00020000 + #define CKF_USER_PIN_LOCKED 0x00040000 + #define CKF_USER_PIN_TO_BE_CHANGED 0x00080000 + #define CKF_SO_PIN_COUNT_LOW 0x00100000 + #define CKF_SO_PIN_FINAL_TRY 0x00200000 + #define CKF_SO_PIN_LOCKED 0x00400000 + #define CKF_SO_PIN_TO_BE_CHANGED 0x00800000 + + #define CKF_EXCLUSIVE_SESSION 0x0001 + #define CKF_RW_SESSION 0x0002 + #define CKF_SERIAL_SESSION 0x0004 + + /* Mechanism information flags */ + #define CKF_HW 0x00000001 + + #define CKF_EXTENSION CK_VENDOR_DEFINED + + #define CKF_ENCRYPT 0x00000100 + #define CKF_DECRYPT 0x00000200 + #define CKF_DIGEST 0x00000400 + #define CKF_SIGN 0x00000800 + #define CKF_SIGN_RECOVER 0x00001000 + #define CKF_VERIFY 0x00002000 + #define CKF_VERIFY_RECOVER 0x00004000 + #define CKF_GENERATE 0x00008000 + #define CKF_GENERATE_KEY_PAIR 0x00010000 + #define CKF_WRAP 0x00020000 + #define CKF_UNWRAP 0x00040000 + #define CKF_DERIVE 0x00080000 + + typedef CK_NUMERIC CK_OBJECT_CLASS; + + #define CKO_DATA 0x0000 + #define CKO_CERTIFICATE 0x0001 + #define CKO_PUBLIC_KEY 0x0002 + #define CKO_PRIVATE_KEY 0x0003 + #define CKO_SECRET_KEY 0x0004 + #define CKO_HW_FEATURE 0x00000005 + #define CKO_DOMAIN_PARAMETERS 0x00000006 + + #define CKO_VENDOR_DEFINED CK_VENDOR_DEFINED + #define CKO_VENDOR_DEFINED_V1 CK_VENDOR_DEFINED_V1 + + typedef CK_ULONG CK_HW_FEATURE_TYPE; + + #define CKH_MONOTONIC_COUNTER 0x00000001 + #define CKH_CLOCK 0x00000002 + #define CKH_VENDOR_DEFINED 0x80000000 + + typedef CK_NUMERIC CK_KEY_TYPE; + + #define CKK_RSA 0x0000 + #define CKK_DSA 0x0001 + #define CKK_DH 0x0002 + /* CKK_ECDSA is deprecated in v2.11 */ + #define CKK_ECDSA 0x0003 + #define CKK_EC 0x0003 + #define CKK_X9_42_DH 0x00000004 + #define CKK_KEA 0x0005 + #define CKK_GENERIC_SECRET 0x0010 + #define CKK_RC2 0x0011 + #define CKK_RC4 0x0012 + #define CKK_RC5 0x0019 + #define CKK_DES 0x0013 + #define CKK_DES2 0x0014 + #define CKK_DES3 0x0015 + #define CKK_CAST 0x0016 + #define CKK_CAST3 0x0017 + /* CKK_CSA5 is deprecated in v2.11 */ + #define CKK_CAST5 0x0018 + #define CKK_CAST128 0x0018 + #define CKK_IDEA 0x001a + #define CKK_SKIPJACK 0x001b + #define CKK_BATON 0x001c + #define CKK_JUNIPER 0x001d + #define CKK_CDMF 0x001e + #define CKK_AES 0x001f + #define CKK_VENDOR_DEFINED CK_VENDOR_DEFINED + + typedef CK_NUMERIC CK_CERTIFICATE_TYPE; + + #define CKC_X_509 0x0000 + #define CKC_X_509_ATTR_CERT 0x00000001 + + #define CKC_VENDOR_DEFINED CK_VENDOR_DEFINED + + typedef CK_NUMERIC CK_ATTRIBUTE_TYPE; + typedef CK_ATTRIBUTE_TYPE * CK_ATTRIBUTE_TYPE_PTR; + + #define CKA_CLASS 0x0000 + #define CKA_TOKEN 0x0001 + #define CKA_PRIVATE 0x0002 + #define CKA_LABEL 0x0003 + #define CKA_APPLICATION 0x0010 + #define CKA_VALUE 0x0011 + #define CKA_OBJECT_ID 0x00000012 + #define CKA_CERTIFICATE_TYPE 0x0080 + #define CKA_ISSUER 0x0081 + #define CKA_SERIAL_NUMBER 0x0082 + #define CKA_AC_ISSUER 0x00000083 + #define CKA_OWNER 0x00000084 + #define CKA_ATTR_TYPES 0x00000085 + #define CKA_TRUSTED 0x00000086 + #define CKA_KEY_TYPE 0x0100 + #define CKA_SUBJECT 0x0101 + #define CKA_ID 0x0102 + #define CKA_SENSITIVE 0x0103 + #define CKA_ENCRYPT 0x0104 + #define CKA_DECRYPT 0x0105 + #define CKA_WRAP 0x0106 + #define CKA_UNWRAP 0x0107 + #define CKA_SIGN 0x0108 + #define CKA_SIGN_RECOVER 0x0109 + #define CKA_VERIFY 0x010A + #define CKA_VERIFY_RECOVER 0x010B + #define CKA_DERIVE 0x010C + #define CKA_START_DATE 0x0110 + #define CKA_END_DATE 0x0111 + #define CKA_MODULUS 0x0120 + #define CKA_MODULUS_BITS 0x0121 + #define CKA_PUBLIC_EXPONENT 0x0122 + #define CKA_PRIVATE_EXPONENT 0x0123 + #define CKA_PRIME_1 0x0124 + #define CKA_PRIME_2 0x0125 + #define CKA_EXPONENT_1 0x0126 + #define CKA_EXPONENT_2 0x0127 + #define CKA_COEFFICIENT 0x0128 + #define CKA_PRIME 0x0130 + #define CKA_SUBPRIME 0x0131 + #define CKA_BASE 0x0132 + #define CKA_PRIME_BITS 0x00000133 + #define CKA_SUB_PRIME_BITS 0x00000134 + #define CKA_VALUE_BITS 0x0160 + #define CKA_VALUE_LEN 0x0161 + #define CKA_EXTRACTABLE 0x0162 + #define CKA_LOCAL 0x0163 + #define CKA_NEVER_EXTRACTABLE 0x0164 + #define CKA_ALWAYS_SENSITIVE 0x0165 + #define CKA_KEY_GEN_MECHANISM 0x0166 + #define CKA_MODIFIABLE 0x0170 + /* CKA_ECDSA_PARAMS is deprecated in v2.11 */ + #define CKA_ECDSA_PARAMS 0x0180 + #define CKA_EC_PARAMS 0x00000180 + #define CKA_EC_POINT 0x0181 + #define CKA_SECONDARY_AUTH 0x00000200 + #define CKA_AUTH_PIN_FLAGS 0x00000201 + #define CKA_HW_FEATURE_TYPE 0x00000300 + #define CKA_RESET_ON_INIT 0x00000301 + #define CKA_HAS_RESET 0x00000302 + + #define CKA_VENDOR_DEFINED CK_VENDOR_DEFINED + #define CKA_VENDOR_DEFINED_V1 CK_VENDOR_DEFINED_V1 + + typedef struct CK_ATTRIBUTE { + CK_ATTRIBUTE_TYPE type; + CK_VOID_PTR pValue; + CK_COUNT valueLen; + } CK_ATTRIBUTE; + typedef CK_ATTRIBUTE * CK_ATTRIBUTE_PTR; + + typedef struct CK_DATE{ + CK_CHAR year[4]; + CK_CHAR month[2]; + CK_CHAR day[2]; + } CK_DATE; + typedef CK_DATE * CK_DATE_PTR; + + typedef CK_NUMERIC CK_MECHANISM_TYPE; + typedef CK_MECHANISM_TYPE * CK_MECHANISM_TYPE_PTR; + + /* Mechanism definitions with some version 2.x methods */ + + #define CKM_RSA_PKCS_KEY_PAIR_GEN 0x0000 + #define CKM_RSA_PKCS 0x0001 + #define CKM_RSA_9796 0x0002 + #define CKM_RSA_X_509 0x0003 + #define CKM_MD2_RSA_PKCS 0x0004 + #define CKM_MD5_RSA_PKCS 0x0005 + #define CKM_SHA1_RSA_PKCS 0x0006 + #define CKM_RIPEMD128_RSA_PKCS 0x00000007 + #define CKM_RIPEMD160_RSA_PKCS 0x00000008 + #define CKM_RSA_PKCS_OAEP 0x00000009 + #define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A + #define CKM_RSA_X9_31 0x0000000B + #define CKM_SHA1_RSA_X9_31 0x0000000C + #define CKM_DSA_KEY_PAIR_GEN 0x0010 + #define CKM_DSA 0x0011 + #define CKM_DSA_SHA1 0x0012 + #define CKM_DH_PKCS_KEY_PAIR_GEN 0x0020 + #define CKM_DH_PKCS_DERIVE 0x0021 + #define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030 + #define CKM_X9_42_DH_DERIVE 0x00000031 + #define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032 + #define CKM_X9_42_MQV_DERIVE 0x00000033 + #define CKM_RC2_KEY_GEN 0x0100 + #define CKM_RC2_ECB 0x0101 + #define CKM_RC2_CBC 0x0102 + #define CKM_RC2_MAC 0x0103 + #define CKM_RC2_MAC_GENERAL 0x0104 + #define CKM_RC2_CBC_PAD 0x00000105 + #define CKM_RC4_KEY_GEN 0x0110 + #define CKM_RC4 0x0111 + #define CKM_DES_KEY_GEN 0x0120 + #define CKM_DES_ECB 0x0121 + #define CKM_DES_CBC 0x0122 + #define CKM_DES_MAC 0x0123 + #define CKM_DES_MAC_GENERAL 0x00000124 + #define CKM_DES_CBC_PAD 0x00000125 + #define CKM_DES2_KEY_GEN 0x0130 + #define CKM_DES3_KEY_GEN 0x0131 + #define CKM_DES3_ECB 0x0132 + #define CKM_DES3_CBC 0x0133 + #define CKM_DES3_MAC 0x0134 + #define CKM_DES3_MAC_GENERAL 0x00000135 + #define CKM_DES3_CBC_PAD 0x00000136 + #define CKM_CDMF_KEY_GEN 0x00000140 + #define CKM_CDMF_ECB 0x00000141 + #define CKM_CDMF_CBC 0x00000142 + #define CKM_CDMF_MAC 0x00000143 + #define CKM_CDMF_MAC_GENERAL 0x00000144 + #define CKM_CDMF_CBC_PAD 0x00000145 + #define CKM_MD2 0x0200 + #define CKM_MD2_HMAC 0x0201 + #define CKM_MD2_HMAC_GENERAL 0x0202 + #define CKM_MD5 0x0210 + #define CKM_MD5_HMAC 0x0211 + #define CKM_MD5_HMAC_GENERAL 0x0212 + #define CKM_SHA_1 0x0220 + #define CKM_SHA_1_HMAC 0x0221 + #define CKM_SHA_1_HMAC_GENERAL 0x0222 + #define CKM_RIPEMD128 0x00000230 + #define CKM_RIPEMD128_HMAC 0x00000231 + #define CKM_RIPEMD128_HMAC_GENERAL 0x00000232 + #define CKM_RIPEMD160 0x00000240 + #define CKM_RIPEMD160_HMAC 0x00000241 + #define CKM_RIPEMD160_HMAC_GENERAL 0x00000242 + #define CKM_CAST_KEY_GEN 0x0300 + #define CKM_CAST_ECB 0x0301 + #define CKM_CAST_CBC 0x0302 + #define CKM_CAST_MAC 0x0303 + #define CKM_CAST_MAC_GENERAL 0x00000304 + #define CKM_CAST_CBC_PAD 0x00000305 + #define CKM_CAST3_KEY_GEN 0x0310 + #define CKM_CAST3_ECB 0x0311 + #define CKM_CAST3_CBC 0x0312 + #define CKM_CAST3_MAC 0x0313 + #define CKM_CAST3_MAC_GENERAL 0x00000314 + #define CKM_CAST3_CBC_PAD 0x00000315 + #define CKM_CAST5_KEY_GEN 0x0320 + #define CKM_CAST5_ECB 0x0321 + #define CKM_CAST5_CBC 0x0322 + #define CKM_CAST5_MAC 0x0323 + #define CKM_CAST5_MAC_GENERAL 0x00000324 + #define CKM_CAST5_CBC_PAD 0x00000325 + #define CKM_CAST128_KEY_GEN 0x0320 + #define CKM_CAST128_ECB 0x0321 + #define CKM_CAST128_CBC 0x0322 + #define CKM_CAST128_MAC 0x0323 + #define CKM_CAST128_MAC_GENERAL 0x00000324 + #define CKM_CAST128_CBC_PAD 0x00000325 + #define CKM_RC5_KEY_GEN 0x0330 + #define CKM_RC5_ECB 0x0331 + #define CKM_RC5_CBC 0x0332 + #define CKM_RC5_MAC 0x0333 + #define CKM_RC5_MAC_GENERAL 0x00000334 + #define CKM_RC5_CBC_PAD 0x00000335 + #define CKM_IDEA_KEY_GEN 0x0340 + #define CKM_IDEA_ECB 0x0341 + #define CKM_IDEA_CBC 0x0342 + #define CKM_IDEA_MAC 0x0343 + #define CKM_IDEA_MAC_GENERAL 0x0344 + #define CKM_IDEA_CBC_PAD 0x00000345 + #define CKM_GENERIC_SECRET_KEY_GEN 0x00000350 + #define CKM_CONCATENATE_BASE_AND_KEY 0x00000360 + #define CKM_CONCATENATE_BASE_AND_DATA 0x00000362 + #define CKM_CONCATENATE_DATA_AND_BASE 0x00000363 + #define CKM_XOR_BASE_AND_DATA 0x00000364 + #define CKM_EXTRACT_KEY_FROM_KEY 0x00000365 + #define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370 + #define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371 + #define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372 + #define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373 + #define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374 + #define CKM_TLS_MASTER_KEY_DERIVE 0x00000375 + #define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376 + #define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377 + #define CKM_SSL3_MD5_MAC 0x00000380 + #define CKM_SSL3_SHA1_MAC 0x00000381 + #define CKM_MD5_KEY_DERIVATION 0x00000390 + #define CKM_MD2_KEY_DERIVATION 0x00000391 + #define CKM_SHA1_KEY_DERIVATION 0x00000392 + #define CKM_PBE_MD2_DES_CBC 0x000003A0 + #define CKM_PBE_MD5_DES_CBC 0x000003A1 + #define CKM_PBE_MD5_CAST_CBC 0x000003A2 + #define CKM_PBE_MD5_CAST3_CBC 0x000003A3 + #define CKM_PBE_MD5_CAST5_CBC 0x000003A4 + #define CKM_PBE_MD5_CAST128_CBC 0x000003A4 + #define CKM_PBE_SHA1_CAST5_CBC 0x000003A5 + #define CKM_PBE_SHA1_CAST128_CBC 0x000003A5 + #define CKM_PBE_SHA1_RC4_128 0x000003A6 + #define CKM_PBE_SHA1_RC4_40 0x000003A7 + #define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8 + #define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9 + #define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA + #define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB + #define CKM_PKCS5_PBKD2 0x000003B0 + #define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0 + #define CKM_KEY_WRAP_LYNKS 0x00000400 + #define CKM_KEY_WRAP_SET_OAEP 0x00000401 + #define CKM_SKIPJACK_KEY_GEN 0x00001000 + #define CKM_SKIPJACK_ECB64 0x00001001 + #define CKM_SKIPJACK_CBC64 0x00001002 + #define CKM_SKIPJACK_OFB64 0x00001003 + #define CKM_SKIPJACK_CFB64 0x00001004 + #define CKM_SKIPJACK_CFB32 0x00001005 + #define CKM_SKIPJACK_CFB16 0x00001006 + #define CKM_SKIPJACK_CFB8 0x00001007 + #define CKM_SKIPJACK_WRAP 0x00001008 + #define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009 + #define CKM_SKIPJACK_RELAYX 0x0000100a + #define CKM_KEA_KEY_PAIR_GEN 0x00001010 + #define CKM_KEA_KEY_DERIVE 0x00001011 + #define CKM_FORTEZZA_TIMESTAMP 0x00001020 + #define CKM_BATON_KEY_GEN 0x00001030 + #define CKM_BATON_ECB128 0x00001031 + #define CKM_BATON_ECB96 0x00001032 + #define CKM_BATON_CBC128 0x00001033 + #define CKM_BATON_COUNTER 0x00001034 + #define CKM_BATON_SHUFFLE 0x00001035 + #define CKM_BATON_WRAP 0x00001036 + /* CKM_ECDSA_KEY_PARI_GEN is deprecated in v2.11 */ + #define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 + #define CKM_EC_KEY_PAIR_GEN 0x00001040 + #define CKM_ECDSA 0x00001041 + #define CKM_ECDSA_SHA1 0x00001042 + #define CKM_ECDH1_DERIVE 0x00001043 + #define CKM_ECDH1_COFACTOR_DERIVE 0x00001044 + #define CKM_ECMQV_DERIVE 0x00001045 + #define CKM_JUNIPER_KEY_GEN 0x00001060 + #define CKM_JUNIPER_ECB128 0x00001061 + #define CKM_JUNIPER_CBC128 0x00001062 + #define CKM_JUNIPER_COUNTER 0x00001063 + #define CKM_JUNIPER_SHUFFLE 0x00001064 + #define CKM_JUNIPER_WRAP 0x00001065 + #define CKM_FASTHASH 0x00001070 + #define CKM_AES_KEY_GEN 0x00001080 + #define CKM_AES_ECB 0x00001081 + #define CKM_AES_CBC 0x00001082 + #define CKM_AES_MAC 0x00001083 + #define CKM_AES_MAC_GENERAL 0x00001084 + #define CKM_AES_CBC_PAD 0x00001085 + #define CKM_DSA_PARAMETER_GEN 0x00002000 + #define CKM_DH_PKCS_PARAMETER_GEN 0x00002001 + #define CKM_X9_42_DH_PKCS_PARAMETER_GEN 0x00002001 + + #define CKM_VENDOR_DEFINED CK_VENDOR_DEFINED + #define CKM_VENDOR_DEFINED_V1 CK_VENDOR_DEFINED_V1 + + typedef struct CK_MECHANISM { + CK_MECHANISM_TYPE mechanism; + CK_VOID_PTR pParameter; + CK_SIZE parameterLen; + } CK_MECHANISM; + typedef CK_MECHANISM * CK_MECHANISM_PTR; + + typedef struct CK_MECHANISM_INFO { + CK_ULONG minKeySize; + CK_ULONG maxKeySize; + CK_FLAGS flags; + } CK_MECHANISM_INFO; + typedef CK_MECHANISM_INFO * CK_MECHANISM_INFO_PTR; + + /* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and + * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just + * holds the effective keysize */ + typedef CK_ULONG CK_RC2_PARAMS; + + typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; + + typedef struct CK_RC2_CBC_PARAMS { + CK_SIZE effectiveBits; + CK_BYTE iv[8]; + } CK_RC2_CBC_PARAMS; + typedef CK_RC2_CBC_PARAMS * CK_RC2_CBC_PARAMS_PTR; + + typedef struct CK_PBE_PARAMS { + CK_CHAR_PTR pInitVector; + CK_CHAR_PTR pPassword; + CK_SIZE passwordLen; + CK_CHAR_PTR pSalt; + CK_SIZE saltLen; + CK_SIZE iteration; + } CK_PBE_PARAMS; + + typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; + + /* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the + * CKM_KEY_WRAP_SET_OAEP mechanism */ + /* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */ + typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { + CK_BYTE bBC; /* block contents byte */ + CK_BYTE_PTR pX; /* extra data */ + CK_ULONG XLen; /* length of extra data in bytes */ + } CK_KEY_WRAP_SET_OAEP_PARAMS; + + typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \ + CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; + + #define CKG_MGF1_SHA1 0x00000001 + #define CKZ_DATA_SPECIFIED 0x00000001 + + typedef CK_ULONG CK_RSA_PKCS_OAEP_MGF_TYPE; + typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; + + typedef struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_OAEP_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + CK_VOID_PTR pSourceData; + CK_ULONG sourceDataLen; + } CK_RSA_PKCS_OAEP_PARAMS; + + typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR \ + CK_RSA_PKCS_OAEP_PARAMS_PTR; + + typedef struct CK_SSL3_RANDOM_DATA { + CK_BYTE_PTR pClientRandom; + CK_ULONG clientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG serverRandomLen; + } CK_SSL3_RANDOM_DATA; + + #ifndef NAME32 + typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; + } CK_SSL3_MASTER_KEY_DERIVE_PARAMS; + + typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ + CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; + #else + typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAM { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; + } CK_SSL3_MASTER_KEY_DERIVE_PARAM; + #endif + + typedef struct CK_SSL3_KEY_MAT_OUT { + CK_OBJECT_HANDLE hClientMacSecret; + CK_OBJECT_HANDLE hServerMacSecret; + CK_OBJECT_HANDLE hClientKey; + CK_OBJECT_HANDLE hServerKey; + CK_BYTE_PTR pIVClient; + CK_BYTE_PTR pIVServer; + } CK_SSL3_KEY_MAT_OUT; + + typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; + + + typedef struct CK_SSL3_KEY_MAT_PARAMS { + CK_ULONG macSizeInBits; + CK_ULONG keySizeInBits; + CK_ULONG IVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; + } CK_SSL3_KEY_MAT_PARAMS; + + typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; + + + typedef struct CK_KEY_DERIVATION_STRING_DATA { + CK_BYTE_PTR pData; + CK_ULONG len; + } CK_KEY_DERIVATION_STRING_DATA; + + #ifdef NAME32 + typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ + CK_KEY_DERIVATION_STRING_DATA_P; + #else + typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ + CK_KEY_DERIVATION_STRING_DATA_PTR; + #endif + + + /* The CK_EXTRACT_PARAMS is used for the + * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit + * of the base key should be used as the first bit of the + * derived key */ + /* CK_EXTRACT_PARAMS is new for v2.0 */ + typedef CK_ULONG CK_EXTRACT_PARAMS; + + typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; + + + /* return codes */ + + typedef CK_NUMERIC CK_RV; + + #define CKR_OK 0x0000 + #define CKR_CANCEL 0x0001 + #define CKR_HOST_MEMORY 0x0002 + #define CKR_SLOT_ID_INVALID 0x0003 + #ifdef V1COMPLIANT + #define CKR_FLAGS_INVALID 0x0004 + #endif + #define CKR_GENERAL_ERROR 0x0005 + #define CKR_FUNCTION_FAILED 0x0006 + #define CKR_ARGUMENTS_BAD 0x0007 + #define CKR_NO_EVENT 0x0008 + #define CKR_NEED_TO_CREATE_THREADS 0x0009 + #define CKR_CANT_LOCK 0x000A + #define CKR_ATTRIBUTE_READ_ONLY 0x0010 + #define CKR_ATTRIBUTE_SENSITIVE 0x0011 + #define CKR_ATTRIBUTE_TYPE_INVALID 0x0012 + #define CKR_ATTRIBUTE_VALUE_INVALID 0x0013 + #define CKR_DATA_INVALID 0x0020 + #define CKR_DATA_LEN_RANGE 0x0021 + #define CKR_DEVICE_ERROR 0x0030 + #define CKR_DEVICE_MEMORY 0x0031 + #define CKR_DEVICE_REMOVED 0x0032 + #define CKR_ENCRYPTED_DATA_INVALID 0x0040 + #define CKR_ENCRYPTED_DATA_LEN_RANGE 0x0041 + #define CKR_FUNCTION_CANCELED 0x0050 + #define CKR_FUNCTION_NOT_PARALLEL 0x0051 + #ifdef V1COMPLIANT + #define CKR_FUNCTION_PARALLEL 0x0052 + #endif + #define CKR_FUNCTION_NOT_SUPPORTED 0x0054 + #define CKR_KEY_HANDLE_INVALID 0x0060 + #ifdef V1COMPLIANT + #define CKR_KEY_SENSITIVE 0x0061 + #endif + #define CKR_KEY_SIZE_RANGE 0x0062 + #define CKR_KEY_TYPE_INCONSISTENT 0x0063 + #define CKR_KEY_NOT_NEEDED 0x0064 + #define CKR_KEY_CHANGED 0x0065 + #define CKR_KEY_NEEDED 0x0066 + #define CKR_KEY_INDIGESTABLE 0x0067 + #define CKR_KEY_FUNCTION_NOT_PERMITTED 0x0068 + #define CKR_KEY_NOT_WRAPPABLE 0x0069 + #define CKR_KEY_UNEXTRACTABLE 0x006A + #define CKR_KEY_PARAMS_INVALID 0x0000006B + #define CKR_MECHANISM_INVALID 0x0070 + #define CKR_MECHANISM_PARAM_INVALID 0x0071 + #ifdef V1COMPLIANT + #define CKR_OBJECT_CLASS_INCONSISTENT 0x0080 + #define CKR_OBJECT_CLASS_INVALID 0x0081 + #endif + #define CKR_OBJECT_HANDLE_INVALID 0x0082 + #define CKR_OPERATION_ACTIVE 0x0090 + #define CKR_OPERATION_NOT_INITIALIZED 0x0091 + #define CKR_PIN_INCORRECT 0x00A0 + #define CKR_PIN_INVALID 0x00A1 + #define CKR_PIN_LEN_RANGE 0x00A2 + #define CKR_PIN_EXPIRED 0x00A3 + #define CKR_PIN_LOCKED 0x00A4 + #define CKR_SESSION_CLOSED 0x00B0 + #define CKR_SESSION_COUNT 0x00B1 + /* V1COMPLIANT */ + #define CKR_SESSION_EXCLUSIVE_EXISTS 0x00B2 + #define CKR_SESSION_HANDLE_INVALID 0x00B3 + #ifdef NAME32 + #define CKR_SESSION_PARALLEL_NOT_SUPPOR 0x00B4 + #else + #define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x00B4 + #endif + #define CKR_SESSION_READ_ONLY 0x00B5 + #define CKR_SESSION_EXISTS 0x00B6 + #define CKR_SESSION_READ_ONLY_EXISTS 0x00B7 + #ifdef NAME32 + #define CKR_SESSION_READ_WRITE_SO_EXIST 0x00B8 + #else + #define CKR_SESSION_READ_WRITE_SO_EXISTS 0x00B8 + #endif + #define CKR_SIGNATURE_INVALID 0x00C0 + #define CKR_SIGNATURE_LEN_RANGE 0x00C1 + #define CKR_TEMPLATE_INCOMPLETE 0x00D0 + #define CKR_TEMPLATE_INCONSISTENT 0x00D1 + #define CKR_TOKEN_NOT_PRESENT 0x00E0 + #define CKR_TOKEN_NOT_RECOGNIZED 0x00E1 + #define CKR_TOKEN_WRITE_PROTECTED 0x00E2 + #ifdef NAME32 + #define CKR_UNWRAPPING_KEY_HANDLE_INVAL 0x00F0 + #define CKR_UNWRAPPING_KEY_TYPE_INCONSI 0x00F2 + #else + #define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x00F0 + #define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x00F2 + #endif + #define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x00F1 + #ifdef NAME32 + #else + #endif + #define CKR_USER_ALREADY_LOGGED_IN 0x0100 + #define CKR_USER_NOT_LOGGED_IN 0x0101 + #define CKR_USER_PIN_NOT_INITIALIZED 0x0102 + #define CKR_USER_TYPE_INVALID 0x0103 + #ifdef NAME32 + #define CKR_USER_ANOTHER_ALREADY_LOGGED 0x0104 + #else + #define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x0104 + #endif + #define CKR_USER_TOO_MANY_TYPES 0x0105 + #define CKR_WRAPPED_KEY_INVALID 0x0110 + #define CKR_WRAPPED_KEY_LEN_RANGE 0x0112 + #define CKR_WRAPPING_KEY_HANDLE_INVALID 0x0113 + #define CKR_WRAPPING_KEY_SIZE_RANGE 0x0114 + #ifdef NAME32 + #define CKR_WRAPPING_KEY_TYPE_INCONSIST 0x0115 + #define CKR_CRYPTOKI_ALREADY_INITIALIZE 0x0191 + #else + #define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x0115 + #define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x0191 + #endif + #define CKR_RANDOM_SEED_NOT_SUPPORTED 0x0120 + #define CKR_RANDOM_NO_RNG 0x0121 + #define CKR_DOMAIN_PARAMS_INVALID 0x0130 + #define CKR_BUFFER_TOO_SMALL 0x0150 + #define CKR_SAVED_STATE_INVALID 0x0160 + #define CKR_INFORMATION_SENSITIVE 0x0170 + #define CKR_STATE_UNSAVEABLE 0x0180 + #define CKR_CRYPTOKI_NOT_INITIALIZED 0x0190 + #define CKR_MUTEX_BAD 0x01A0 + #define CKR_MUTEX_NOT_LOCKED 0x01A1 + + #define CKR_VENDOR_DEFINED CK_VENDOR_DEFINED + + /* CK_FUNCTION_LIST is a structure holding a Cryptoki spec + * version and pointers of appropriate types to all the + * Cryptoki functions */ + /* CK_FUNCTION_LIST is new for v2.0 */ + typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; + + typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; + + typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; + + #define CK_CALLBACK_FUNCTION(returnType, name) returnType(* name) + + /* CK_NOTIFY is an application callback that processes events */ + typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_NOTIFICATION event, + CK_VOID_PTR pApplication /* passed to C_OpenSession */ + ); + + /* CK_CREATEMUTEX is an application callback for creating a + * mutex object */ + typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( + CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ + ); + + /* CK_DESTROYMUTEX is an application callback for destroying a + * mutex object */ + typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ + ); + + /* CK_LOCKMUTEX is an application callback for locking a mutex */ + typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ + ); + + /* CK_UNLOCKMUTEX is an application callback for unlocking a + * mutex */ + typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ + ); + + /* CK_C_INITIALIZE_ARGS provides the optional arguments to + * C_Initialize */ + typedef struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + CK_VOID_PTR pReserved; + } CK_C_INITIALIZE_ARGS; + + /* flags: bit flags that provide capabilities of the slot + * Bit Flag Mask Meaning + */ + #ifdef NAME32 + #define CKF_LIBRARY_CANT_CREATE_OS_THRE 0x00000001 + #else + #define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001 + #endif + #define CKF_OS_LOCKING_OK 0x00000002 + + typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; + + /* additional flags for parameters to functions */ + + /* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ + #define CKF_DONT_BLOCK 1 + + + /* CK_KEA_DERIVE_PARAMS provides the parameters to the + * CKM_KEA_DERIVE mechanism */ + /* CK_KEA_DERIVE_PARAMS is new for v2.0 */ + typedef struct CK_KEA_DERIVE_PARAMS { + CK_BBOOL isSender; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pRandomB; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + } CK_KEA_DERIVE_PARAMS; + + typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; + + /* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the + * CKM_RC2_MAC_GENERAL mechanism */ + /* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */ + typedef struct CK_RC2_MAC_GENERAL_PARAMS { + CK_ULONG effectiveBits; /* effective bits (1-1024) */ + CK_ULONG macLength; /* Length of MAC in bytes */ + } CK_RC2_MAC_GENERAL_PARAMS; + + typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ + CK_RC2_MAC_GENERAL_PARAMS_PTR; + + + /* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and + * CKM_RC5_MAC mechanisms */ + /* CK_RC5_PARAMS is new for v2.0 */ + typedef struct CK_RC5_PARAMS { + CK_ULONG wordsize; /* wordsize in bits */ + CK_ULONG rounds; /* number of rounds */ + } CK_RC5_PARAMS; + + typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; + + + /* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC + * mechanism */ + /* CK_RC5_CBC_PARAMS is new for v2.0 */ + typedef struct CK_RC5_CBC_PARAMS { + CK_ULONG wordsize; /* wordsize in bits */ + CK_ULONG rounds; /* number of rounds */ + CK_BYTE_PTR pIv; /* pointer to IV */ + CK_ULONG ivLen; /* length of IV in bytes */ + } CK_RC5_CBC_PARAMS; + + typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; + + + /* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the + * CKM_RC5_MAC_GENERAL mechanism */ + /* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */ + typedef struct CK_RC5_MAC_GENERAL_PARAMS { + CK_ULONG wordsize; /* wordsize in bits */ + CK_ULONG rounds; /* number of rounds */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ + } CK_RC5_MAC_GENERAL_PARAMS; + + typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ + CK_RC5_MAC_GENERAL_PARAMS_PTR; + + + /* CK_MAC_GENERAL_PARAMS provides the parameters to most block + * ciphers' MAC_GENERAL mechanisms. Its value is the length of + * the MAC */ + /* CK_MAC_GENERAL_PARAMS is new for v2.0 */ + typedef CK_ULONG CK_MAC_GENERAL_PARAMS; + + typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; + + + /* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ + /* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */ + typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pPassword; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPAndGLen; + CK_ULONG ulQLen; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pPrimeP; + CK_BYTE_PTR pBaseG; + CK_BYTE_PTR pSubprimeQ; + } CK_SKIPJACK_PRIVATE_WRAP_PARAMS; + + typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ + CK_SKIPJACK_PRIVATE_WRAP_PTR; + + + /* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the + * CKM_SKIPJACK_RELAYX mechanism */ + /* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */ + typedef struct CK_SKIPJACK_RELAYX_PARAMS { + CK_ULONG ulOldWrappedXLen; + CK_BYTE_PTR pOldWrappedX; + CK_ULONG ulOldPasswordLen; + CK_BYTE_PTR pOldPassword; + CK_ULONG ulOldPublicDataLen; + CK_BYTE_PTR pOldPublicData; + CK_ULONG ulOldRandomLen; + CK_BYTE_PTR pOldRandomA; + CK_ULONG ulNewPasswordLen; + CK_BYTE_PTR pNewPassword; + CK_ULONG ulNewPublicDataLen; + CK_BYTE_PTR pNewPublicData; + CK_ULONG ulNewRandomLen; + CK_BYTE_PTR pNewRandomA; + } CK_SKIPJACK_RELAYX_PARAMS; + + typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ + CK_SKIPJACK_RELAYX_PARAMS_PTR; + + #ifdef __cplusplus + extern "C" { /* define as 'C' functions to prevent mangling */ + #endif + + #ifdef V1COMPLIANT + + /* V1 definitions */ + #include "pkcs11f1.h" + + #else + + /* V2 definitions */ + + #define CK_DEFINE_FUNCTION(returnType, name) \ + returnType CK_ENTRY name + #define CK_DECLARE_FUNCTION(returnType, name) \ + returnType CK_ENTRY name + #if defined (INSAM) /* SAMs */ + #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + returnType ( CK_ENTRY * name) + #else + #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + returnType CK_ENTRY (* name) + #endif + + #define __PASTE(x,y) x##y + + + /* ============================================================== + * Define the "extern" form of all the entry points. + * ============================================================== + */ + + #define CK_NEED_ARG_LIST 1 + #define CK_PKCS11_FUNCTION_INFO(name) \ + extern CK_DECLARE_FUNCTION(CK_RV, name) + + /* pkcs11f.h has all the information about the Cryptoki + * function prototypes. */ + #include "pkcs11f.h" + + #undef CK_NEED_ARG_LIST + #undef CK_PKCS11_FUNCTION_INFO + + + /* ============================================================== + * Define the typedef form of all the entry points. That is, for + * each Cryptoki function C_XXX, define a type CK_C_XXX which is + * a pointer to that kind of function. + * ============================================================== + */ + + #define CK_NEED_ARG_LIST 1 + #define CK_PKCS11_FUNCTION_INFO(name) \ + typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) + + /* pkcs11f.h has all the information about the Cryptoki + * function prototypes. */ + #include "pkcs11f.h" + + #undef CK_NEED_ARG_LIST + #undef CK_PKCS11_FUNCTION_INFO + + + /* ============================================================== + * Define structed vector of entry points. A CK_FUNCTION_LIST + * contains a CK_VERSION indicating a library's Cryptoki version + * and then a whole slew of function pointers to the routines in + * the library. This type was declared, but not defined, in + * pkcs11t.h. + * ============================================================== + */ + + #define CK_PKCS11_FUNCTION_INFO(name) \ + __PASTE(CK_,name) name; + + struct CK_FUNCTION_LIST { + + CK_VERSION version; /* Cryptoki version */ + + /* Pile all the function pointers into the CK_FUNCTION_LIST. */ + /* pkcs11f.h has all the information about the Cryptoki + * function prototypes. */ + #include "pkcs11f.h" + + }; + + #undef CK_PKCS11_FUNCTION_INFO + + + #undef __PASTE + + #endif + + #ifdef __cplusplus + } + #endif + + #if defined(_WINDOWS) + # pragma pack(pop,cryptoki) + #else + #if !defined(sun) && !defined(__arm) + # pragma pack() + #endif + #endif + + #endif diff -rcP openssl-engine-0.9.6b.pristine/crypto/engine/vendor_defns/pkcs11f.h openssl-engine-0.9.6b/crypto/engine/vendor_defns/pkcs11f.h *** openssl-engine-0.9.6b.pristine/crypto/engine/vendor_defns/pkcs11f.h Thu Jan 1 10:00:00 1970 --- openssl-engine-0.9.6b/crypto/engine/vendor_defns/pkcs11f.h Tue Jul 31 11:05:16 2001 *************** *** 0 **** --- 1,922 ---- + This file is Copyright 2001 Eracom Technologies Australia Ltd. + + This file is provided for your information and assistance. You are permitted to copy it, to use it to create compatible software, and for review and comment. However, you may not distribute changed versions or other derivative works. All other rights are reserved. + + IN NO EVENT SHALL Eracom Technologies (`ERACOM`) BE LIABLE for any damages arising directly or indirectly from this file, its use or this licence. Without prejudice to the generality of the foregoing: all liability shall be excluded for direct, indirect, special, incidental, consequential or other damages or any loss of profits, business, revenue goodwill or anticipated savings; liability shall be excluded even if ERACOM or anyone else has been advised of the possibility of damage. + In any case the liability of ERACOM shall be reduced to the minimum legally possible under any applicable legislation. + + ERACOM SPECIFICALLY DISCLAIM ALL AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not limited to, any implied warranties of merchantability, fitness for a particular purpose, satisfactory quality, and/or non-infringement of any third party rights. + In any case the warranty of ERACOM shall be reduced to the minimum legally possible under any applicable legislation. + + By using or distributing this file you will be accepting these terms and conditions, including the limitation of liability and lack of warranty. If you do not wish to accept these terms and conditions, DO NOT USE THE FILE. + + /* + * $Id: pkcs11f.h,v 1.2 2001/02/15 08:17:11 vedat Exp $ + * $Author: vedat $ + * + * Copyright (c) 2000,2001 ERACOM Pty. Ltd. + * All Rights Reserved - Proprietary Information of ERACOM Pty. Ltd. + * Not to be Construed as a Published Work. + * + * $Source: /eracom/cvs/prod/include/pkcs11f.h,v $ + * $Revision: 1.2 $ + * $Date: 2001/02/15 08:17:11 $ + */ + + /* pkcs11f.h include file for PKCS #11. 1997 December 22 */ + + /* This function contains pretty much everything about all the */ + /* Cryptoki function prototypes. Because this information is */ + /* used for more than just declaring function prototypes, the */ + /* order of the functions appearing herein is important, and */ + /* should not be altered. */ + + + + /* General-purpose */ + + /* C_Initialize initializes the Cryptoki library. */ + CK_PKCS11_FUNCTION_INFO(C_Initialize) + #ifdef CK_NEED_ARG_LIST + ( + CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets + * cast to CK_C_INITIALIZE_ARGS_PTR + * and dereferenced */ + ); + #endif + + + /* C_Finalize indicates that an application is done with the + * Cryptoki library. */ + CK_PKCS11_FUNCTION_INFO(C_Finalize) + #ifdef CK_NEED_ARG_LIST + ( + CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ + ); + #endif + + + /* C_GetInfo returns general information about Cryptoki. */ + CK_PKCS11_FUNCTION_INFO(C_GetInfo) + #ifdef CK_NEED_ARG_LIST + ( + CK_INFO_PTR pInfo /* location that receives information */ + ); + #endif + + + /* C_GetFunctionList returns the function list. */ + CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) + #ifdef CK_NEED_ARG_LIST + ( + CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to + * function list */ + ); + #endif + + + + /* Slot and token management */ + + /* C_GetSlotList obtains a list of slots in the system. */ + CK_PKCS11_FUNCTION_INFO(C_GetSlotList) + #ifdef CK_NEED_ARG_LIST + ( + CK_BBOOL tokenPresent, /* only slots with tokens? */ + CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ + CK_ULONG_PTR pulCount /* receives number of slots */ + ); + #endif + + + /* C_GetSlotInfo obtains information about a particular slot in + * the system. */ + CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) + #ifdef CK_NEED_ARG_LIST + ( + CK_SLOT_ID slotID, /* the ID of the slot */ + CK_SLOT_INFO_PTR pInfo /* receives the slot information */ + ); + #endif + + + /* C_GetTokenInfo obtains information about a particular token + * in the system. */ + CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) + #ifdef CK_NEED_ARG_LIST + ( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_TOKEN_INFO_PTR pInfo /* receives the token information */ + ); + #endif + + + /* C_GetMechanismList obtains a list of mechanism types + * supported by a token. */ + CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) + #ifdef CK_NEED_ARG_LIST + ( + CK_SLOT_ID slotID, /* ID of token's slot */ + CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ + CK_ULONG_PTR pulCount /* gets # of mechs. */ + ); + #endif + + + /* C_GetMechanismInfo obtains information about a particular + * mechanism possibly supported by a token. */ + CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) + #ifdef CK_NEED_ARG_LIST + ( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_MECHANISM_TYPE type, /* type of mechanism */ + CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ + ); + #endif + + + /* C_InitToken initializes a token. */ + CK_PKCS11_FUNCTION_INFO(C_InitToken) + #ifdef CK_NEED_ARG_LIST + ( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_CHAR_PTR pPin, /* the SO's initial PIN */ + CK_ULONG ulPinLen, /* length in bytes of the PIN */ + CK_CHAR_PTR pLabel /* 32-byte token label (blank padded) */ + ); + #endif + + + /* C_InitPIN initializes the normal user's PIN. */ + CK_PKCS11_FUNCTION_INFO(C_InitPIN) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_CHAR_PTR pPin, /* the normal user's PIN */ + CK_ULONG ulPinLen /* length in bytes of the PIN */ + ); + #endif + + + /* C_SetPIN modifies the PIN of the user who is logged in. */ + CK_PKCS11_FUNCTION_INFO(C_SetPIN) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_CHAR_PTR pOldPin, /* the old PIN */ + CK_ULONG ulOldLen, /* length of the old PIN */ + CK_CHAR_PTR pNewPin, /* the new PIN */ + CK_ULONG ulNewLen /* length of the new PIN */ + ); + #endif + + + + /* Session management */ + + /* C_OpenSession opens a session between an application and a + * token. */ + CK_PKCS11_FUNCTION_INFO(C_OpenSession) + #ifdef CK_NEED_ARG_LIST + ( + CK_SLOT_ID slotID, /* the slot's ID */ + CK_FLAGS flags, /* from CK_SESSION_INFO */ + CK_VOID_PTR pApplication, /* passed to callback */ + CK_NOTIFY Notify, /* callback function */ + CK_SESSION_HANDLE_PTR phSession /* gets session handle */ + ); + #endif + + + /* C_CloseSession closes a session between an application and a + * token. */ + CK_PKCS11_FUNCTION_INFO(C_CloseSession) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession /* the session's handle */ + ); + #endif + + + /* C_CloseAllSessions closes all sessions with a token. */ + CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) + #ifdef CK_NEED_ARG_LIST + ( + CK_SLOT_ID slotID /* the token's slot */ + ); + #endif + + + /* C_GetSessionInfo obtains information about the session. */ + CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_SESSION_INFO_PTR pInfo /* receives session info */ + ); + #endif + + + /* C_GetOperationState obtains the state of the cryptographic operation + * in a session. */ + CK_PKCS11_FUNCTION_INFO(C_GetOperationState) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pOperationState, /* gets state */ + CK_ULONG_PTR pulOperationStateLen /* gets state length */ + ); + #endif + + + /* C_SetOperationState restores the state of the cryptographic + * operation in a session. */ + CK_PKCS11_FUNCTION_INFO(C_SetOperationState) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pOperationState, /* holds state */ + CK_ULONG ulOperationStateLen, /* holds state length */ + CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ + CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ + ); + #endif + + + /* C_Login logs a user into a token. */ + CK_PKCS11_FUNCTION_INFO(C_Login) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_USER_TYPE userType, /* the user type */ + CK_CHAR_PTR pPin, /* the user's PIN */ + CK_ULONG ulPinLen /* the length of the PIN */ + ); + #endif + + + /* C_Logout logs a user out from a token. */ + CK_PKCS11_FUNCTION_INFO(C_Logout) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession /* the session's handle */ + ); + #endif + + + + /* Object management */ + + /* C_CreateObject creates a new object. */ + CK_PKCS11_FUNCTION_INFO(C_CreateObject) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ + ); + #endif + + + /* C_CopyObject copies an object, creating a new object for the + * copy. */ + CK_PKCS11_FUNCTION_INFO(C_CopyObject) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ + ); + #endif + + + /* C_DestroyObject destroys an object. */ + CK_PKCS11_FUNCTION_INFO(C_DestroyObject) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject /* the object's handle */ + ); + #endif + + + /* C_GetObjectSize gets the size of an object in bytes. */ + CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ULONG_PTR pulSize /* receives size of object */ + ); + #endif + + + /* C_GetAttributeValue obtains the value of one or more object + * attributes. */ + CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ + CK_ULONG ulCount /* attributes in template */ + ); + #endif + + + /* C_SetAttributeValue modifies the value of one or more object + * attributes */ + CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ + CK_ULONG ulCount /* attributes in template */ + ); + #endif + + + /* C_FindObjectsInit initializes a search for token and session + * objects that match a template. */ + CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ + CK_ULONG ulCount /* attrs in search template */ + ); + #endif + + + /* C_FindObjects continues a search for token and session + * objects that match a template, obtaining additional object + * handles. */ + CK_PKCS11_FUNCTION_INFO(C_FindObjects) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ + CK_ULONG ulMaxObjectCount, /* max handles to get */ + CK_ULONG_PTR pulObjectCount /* actual # returned */ + ); + #endif + + + /* C_FindObjectsFinal finishes a search for token and session + * objects. */ + CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession /* the session's handle */ + ); + #endif + + + + /* Encryption and decryption */ + + /* C_EncryptInit initializes an encryption operation. */ + CK_PKCS11_FUNCTION_INFO(C_EncryptInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of encryption key */ + ); + #endif + + + /* C_Encrypt encrypts single-part data. */ + CK_PKCS11_FUNCTION_INFO(C_Encrypt) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pData, /* the plaintext data */ + CK_ULONG ulDataLen, /* bytes of plaintext */ + CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ + ); + #endif + + + /* C_EncryptUpdate continues a multiple-part encryption + * operation. */ + CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext data len */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ + ); + #endif + + + /* C_EncryptFinal finishes a multiple-part encryption + * operation. */ + CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session handle */ + CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ + CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ + ); + #endif + + + /* C_DecryptInit initializes a decryption operation. */ + CK_PKCS11_FUNCTION_INFO(C_DecryptInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of decryption key */ + ); + #endif + + + /* C_Decrypt decrypts encrypted data in a single part. */ + CK_PKCS11_FUNCTION_INFO(C_Decrypt) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedData, /* ciphertext */ + CK_ULONG ulEncryptedDataLen, /* ciphertext length */ + CK_BYTE_PTR pData, /* gets plaintext */ + CK_ULONG_PTR pulDataLen /* gets p-text size */ + ); + #endif + + + /* C_DecryptUpdate continues a multiple-part decryption + * operation. */ + CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* encrypted data */ + CK_ULONG ulEncryptedPartLen, /* input length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* p-text size */ + ); + #endif + + + /* C_DecryptFinal finishes a multiple-part decryption + * operation. */ + CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pLastPart, /* gets plaintext */ + CK_ULONG_PTR pulLastPartLen /* p-text size */ + ); + #endif + + + + /* Message digesting */ + + /* C_DigestInit initializes a message-digesting operation. */ + CK_PKCS11_FUNCTION_INFO(C_DigestInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ + ); + #endif + + + /* C_Digest digests data in a single part. */ + CK_PKCS11_FUNCTION_INFO(C_Digest) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* data to be digested */ + CK_ULONG ulDataLen, /* bytes of data to digest */ + CK_BYTE_PTR pDigest, /* gets the message digest */ + CK_ULONG_PTR pulDigestLen /* gets digest length */ + ); + #endif + + + /* C_DigestUpdate continues a multiple-part message-digesting + * operation. */ + CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* data to be digested */ + CK_ULONG ulPartLen /* bytes of data to be digested */ + ); + #endif + + + /* C_DigestKey continues a multi-part message-digesting + * operation, by digesting the value of a secret key as part of + * the data already digested. */ + CK_PKCS11_FUNCTION_INFO(C_DigestKey) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hKey /* secret key to digest */ + ); + #endif + + + /* C_DigestFinal finishes a multiple-part message-digesting + * operation. */ + CK_PKCS11_FUNCTION_INFO(C_DigestFinal) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pDigest, /* gets the message digest */ + CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ + ); + #endif + + + + /* Signing and MACing */ + + /* C_SignInit initializes a signature (private key encryption) + * operation, where the signature is (will be) an appendix to + * the data, and plaintext cannot be recovered from the + *signature. */ + CK_PKCS11_FUNCTION_INFO(C_SignInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of signature key */ + ); + #endif + + + /* C_Sign signs (encrypts with private key) data in a single + * part, where the signature is (will be) an appendix to the + * data, and plaintext cannot be recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_Sign) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data to sign */ + CK_ULONG ulDataLen, /* count of bytes to sign */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ + ); + #endif + + + /* C_SignUpdate continues a multiple-part signature operation, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_SignUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* the data to sign */ + CK_ULONG ulPartLen /* count of bytes to sign */ + ); + #endif + + + /* C_SignFinal finishes a multiple-part signature operation, + * returning the signature. */ + CK_PKCS11_FUNCTION_INFO(C_SignFinal) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ + ); + #endif + + + /* C_SignRecoverInit initializes a signature operation, where + * the data can be recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the signature key */ + ); + #endif + + + /* C_SignRecover signs data in a single operation, where the + * data can be recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_SignRecover) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data to sign */ + CK_ULONG ulDataLen, /* count of bytes to sign */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ + ); + #endif + + + + /* Verifying signatures and MACs */ + + /* C_VerifyInit initializes a verification operation, where the + * signature is an appendix to the data, and plaintext cannot + * cannot be recovered from the signature (e.g. DSA). */ + CK_PKCS11_FUNCTION_INFO(C_VerifyInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* verification key */ + ); + #endif + + + /* C_Verify verifies a signature in a single-part operation, + * where the signature is an appendix to the data, and plaintext + * cannot be recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_Verify) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* signed data */ + CK_ULONG ulDataLen, /* length of signed data */ + CK_BYTE_PTR pSignature, /* signature */ + CK_ULONG ulSignatureLen /* signature length*/ + ); + #endif + + + /* C_VerifyUpdate continues a multiple-part verification + * operation, where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* signed data */ + CK_ULONG ulPartLen /* length of signed data */ + ); + #endif + + + /* C_VerifyFinal finishes a multiple-part verification + * operation, checking the signature. */ + CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* signature to verify */ + CK_ULONG ulSignatureLen /* signature length */ + ); + #endif + + + /* C_VerifyRecoverInit initializes a signature verification + * operation, where the data is recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* verification key */ + ); + #endif + + + /* C_VerifyRecover verifies a signature in a single-part + * operation, where the data is recovered from the signature. */ + CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* signature to verify */ + CK_ULONG ulSignatureLen, /* signature length */ + CK_BYTE_PTR pData, /* gets signed data */ + CK_ULONG_PTR pulDataLen /* gets signed data len */ + ); + #endif + + + + /* Dual-function cryptographic operations */ + + /* C_DigestEncryptUpdate continues a multiple-part digesting + * and encryption operation. */ + CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext length */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ + ); + #endif + + + /* C_DecryptDigestUpdate continues a multiple-part decryption and + * digesting operation. */ + CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* ciphertext */ + CK_ULONG ulEncryptedPartLen, /* ciphertext length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* gets plaintext len */ + ); + #endif + + + /* C_SignEncryptUpdate continues a multiple-part signing and + * encryption operation. */ + CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext length */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ + ); + #endif + + + /* C_DecryptVerifyUpdate continues a multiple-part decryption and + * verify operation. */ + CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* ciphertext */ + CK_ULONG ulEncryptedPartLen, /* ciphertext length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* gets p-text length */ + ); + #endif + + + + /* Key management */ + + /* C_GenerateKey generates a secret key, creating a new key + * object. */ + CK_PKCS11_FUNCTION_INFO(C_GenerateKey) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* key generation mech. */ + CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ + CK_ULONG ulCount, /* # of attrs in template */ + CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ + ); + #endif + + + /* C_GenerateKeyPair generates a public-key/private-key pair, + * creating new key objects. */ + CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session + * handle */ + CK_MECHANISM_PTR pMechanism, /* key-gen + * mech. */ + CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template + * for pub. + * key */ + CK_ULONG ulPublicKeyAttributeCount, /* # pub. + * attrs. */ + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template + * for priv. + * key */ + CK_ULONG ulPrivateKeyAttributeCount, /* # priv. + * attrs. */ + CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. + * key + * handle */ + CK_OBJECT_HANDLE_PTR phPrivateKey /* gets + * priv. key + * handle */ + ); + #endif + + + /* C_WrapKey wraps (i.e., encrypts) a key. */ + CK_PKCS11_FUNCTION_INFO(C_WrapKey) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ + CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ + CK_OBJECT_HANDLE hKey, /* key to be wrapped */ + CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ + CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ + ); + #endif + + + /* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new + * key object. */ + CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ + CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ + CK_BYTE_PTR pWrappedKey, /* the wrapped key */ + CK_ULONG ulWrappedKeyLen, /* wrapped key len */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ + ); + #endif + + + /* C_DeriveKey derives a key from a base key, creating a new key + * object. */ + CK_PKCS11_FUNCTION_INFO(C_DeriveKey) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ + CK_OBJECT_HANDLE hBaseKey, /* base key */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ + ); + #endif + + + + /* Random number generation */ + + /* C_SeedRandom mixes additional seed material into the token's + * random number generator. */ + CK_PKCS11_FUNCTION_INFO(C_SeedRandom) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSeed, /* the seed material */ + CK_ULONG ulSeedLen /* length of seed material */ + ); + #endif + + + /* C_GenerateRandom generates random data. */ + CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR RandomData, /* receives the random data */ + CK_ULONG ulRandomLen /* # of bytes to generate */ + ); + #endif + + + + /* Parallel function management */ + + /* C_GetFunctionStatus is a legacy function; it obtains an + * updated status of a function running in parallel with an + * application. */ + CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession /* the session's handle */ + ); + #endif + + + /* C_CancelFunction is a legacy function; it cancels a function + * running in parallel. */ + CK_PKCS11_FUNCTION_INFO(C_CancelFunction) + #ifdef CK_NEED_ARG_LIST + ( + CK_SESSION_HANDLE hSession /* the session's handle */ + ); + #endif + + + + /* Functions added in for Cryptoki Version 2.01 or later */ + + /* C_WaitForSlotEvent waits for a slot event (token insertion, + * removal, etc.) to occur. */ + CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) + #ifdef CK_NEED_ARG_LIST + ( + CK_FLAGS flags, /* blocking/nonblocking flag */ + CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ + CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ + ); + #endif