Copy #ifdef WIN32
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#elif defined (LINUX)
#include <memory.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
#else
#error OS Specific defined required
#endif
#include "pkcs11.h"
/* *** DECLARE/INITIALIZE GLOBAL VARIABLES *** */
CK_FUNCTION_LIST *pkcs11;
#ifdef WIN32
#ifdef WIN64
static char const libraryPath[] = "ap220w64HSM.dll";
static HINSTANCE lm ;
#else
static char const libraryPath[] = "bp201w32hsm.dll";
static HINSTANCE lm ;
#endif
#elif defined(LINUX)
static char const libraryPath[] = "pkcs11.so" ;
static void *lm ;
#else
#error OS not defined.
#endif
static CK_CHAR PriLabel[20] ;
static CK_CHAR PubLabel[20] ;
static CK_BYTE UserPin[20] ;
static CK_BBOOL bTrue = TRUE;
static CK_BBOOL bFalse = FALSE;
static CK_KEY_TYPE ECCKeyType = CKK_EC;
static CK_OBJECT_CLASS PublicKeyClass = CKO_PUBLIC_KEY;
static CK_OBJECT_CLASS PrivateKeyClass = CKO_PRIVATE_KEY;
void CloseLibModule(void) ;
CK_RV LoadPKCS11Module(void) ;
CK_RV checkSlot(CK_SLOT_ID) ;
CK_RV ECCaction(CK_SESSION_HANDLE, int) ;
CK_RV generateECCKeyPair(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_CHAR_PTR, CK_CHAR_PTR, CK_CHAR_PTR, CK_ULONG) ;
CK_RV ECCSigningTest(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) ;
/* *** MAIN *************************************************************************************** */
int main(int argc, char* argv[])
{
CK_RV rc = 0;
CK_BBOOL bInitialized = FALSE;
char buffer[256] = {0};
CK_C_INITIALIZE_ARGS args = {0};
CK_SLOT_ID slotID = 0;
CK_SESSION_HANDLE hSession = 0;
char *pPath = NULL ;
size_t len = 0 ;
int keylengthID ;
if ( argc != 6 )
{
printf("\n\n-------Invalid parameteres--------\n");
printf("Usage : C>RSAKeyGen Slot_id User_PIN Private_KeyLabel Public_KeyLabel KeyLength_ID\n");
printf(" Slot_id : Slot Number : ex) 0 \n");
printf(" User_PIN: User PIN number : ex) 1234 \n");
printf(" Private_KeyLabel: Private Key Label String : ex) PriTestKey \n");
printf(" Public_KeyLabel : Public Key Label String : ex) PubTestKey \n");
printf(" KeyLength_ID : ECC Key Length ID : ex) 1 \n");
printf(" 1: P192, 2: P224, 3: P256, 4: P384, 5: P521, 6: 256k1\n");
return !CKR_OK ;
}
#ifdef WIN32
strcpy_s(libraryPath,sizeof(libraryPath),KeyperLibrary) ; /* PKCS11 Library */
#elif defined(LINUX)
strcpy(libraryPath,KeyperLibrary) ; /* PKCS11 Library */
#else
#error OS not defined.
#endif
slotID = atoi(argv[1]) ;
#ifdef WIN32
strcpy_s(UserPin,sizeof(UserPin),argv[2]) ; /* User PIN Number */
strcpy_s(PriLabel,sizeof(PriLabel),argv[3]) ; /* Private Key Label */
strcpy_s(PubLabel,sizeof(PubLabel),argv[4]) ; /* Public Key Label */
#elif defined(LINUX)
strcpy((char *)UserPin,argv[2]) ; /* User PIN Number */
strcpy((char *)PriLabel,argv[3]) ; /* Private Key Label */
strcpy((char *)PubLabel,argv[4]) ; /* Public Key Label */
#else
#error OS not defined.
#endif
keylengthID = atoi(argv[5]) ;
if ( keylengthID < 1 || keylengthID > 6 )
{
printf("----- KeyLength_ID should be between 1 and 6 ----- \n");
return !CKR_OK ;
}
if ( strcmp(PriLabel,PubLabel) == 0 )
{
printf("----- Private KeyLabel and Public KeyLabel should be different ----- \n");
return !CKR_OK ;
}
rc = LoadPKCS11Module() ;
if ( rc != CKR_OK ) return rc ;
/* 1. Initialize the pkcs#11 library ... */
rc = pkcs11->C_Initialize(&args);
if ( rc != CKR_OK )
{
CloseLibModule() ;
return rc ;
}
bInitialized = TRUE;
/* 2. Check the slot_id */
rc = checkSlot(slotID);
if ( rc != CKR_OK )
{
CloseLibModule() ;
return rc ;
}
/* 3. Then open a session and login as a User ... */
/* open session (must be serial/rw) */
rc = pkcs11->C_OpenSession(slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &hSession);
if ( rc != CKR_OK )
{
printf("\n\n---There is no HSM or HSM is not ON-Line ----\n");
CloseLibModule() ;
return rc ;
}
/* login as a User */
rc = pkcs11->C_Login(hSession, CKU_USER, (CK_UTF8CHAR_PTR)UserPin, strlen((char*) UserPin));
if ( rc != CKR_OK )
{
printf("\n\n--- Incorrect User PIN number-----------\n");
CloseLibModule() ;
return rc ;
}
/* 4. Generate ECC Key */
rc = ECCaction(hSession,keylengthID);
if ( rc != CKR_OK )
{
CloseLibModule() ;
return rc ;
}
/* 5. When we have completed the Crypto Operations, we must tidy up ... */
/* logout */
rc = pkcs11->C_Logout(hSession);
/* close session */
rc = pkcs11->C_CloseSession(hSession);
/* 6. The last Cryptoki call - always finalize the library (if it has been initialised)! */
if (bInitialized)
{
rc = pkcs11->C_Finalize(NULL_PTR);
}
CloseLibModule() ;
return rc;
}
/* *** end of MAIN ******************************************************************************** */
CK_RV LoadPKCS11Module(void)
{
CK_RV rc;
CK_RV (*pFunction)();
#ifdef WIN32
lm = LoadLibrary( libraryPath );
#elif defined(LINUX)
lm = dlopen( libraryPath, RTLD_LAZY | RTLD_LOCAL );
#else
#error OS not defined.
#endif
if ( lm == NULL )
{
printf("There is no PKCS11 Module : %s\n",libraryPath);
return !CKR_OK ;
}
#ifdef WIN32
pFunction = (CK_RV (*)())GetProcAddress(lm,"C_GetFunctionList");
#elif defined(LINUX)
pFunction = (CK_RV (*)())dlsym(lm,"C_GetFunctionList");
#else
#error OS not defined.
#endif
if (pFunction == NULL )
{
printf("There is no C_GetFunctionList()\n");
CloseLibModule() ;
return !CKR_OK;
}
rc = pFunction(&pkcs11);
if (rc != CKR_OK)
{
printf("C_GetFunctionList() Error \n");
CloseLibModule() ;
return !CKR_OK;
}
return CKR_OK;
}
void CloseLibModule(void)
{
#ifdef WIN32
FreeLibrary(lm);
#elif defined(LINUX)
dlclose(lm);
#else
#error OS not defined.
#endif
}
/* *** Check the SLOT ID ********************************************************************************* */
CK_RV checkSlot(CK_SLOT_ID sID)
{
CK_RV rc;
CK_SLOT_ID_PTR pSlotList ;
CK_ULONG numSlots, i ;
/* see if there are slots with tokens */
rc = pkcs11->C_GetSlotList(TRUE, NULL, &numSlots);
if ( rc != CKR_OK )
{
printf(" GetSlotList Error \n") ;
return rc ;
}
if (numSlots)
{ /* we've got one or more */
/* call pkcs11->C_GetSlotList() again with a correctly sized buffer */
pSlotList = (CK_SLOT_ID_PTR)malloc(sizeof(CK_SLOT_ID)*numSlots);
if ( pSlotList == NULL )
{ /* Memory Full */
printf(" Memory Full \n") ;
return !CKR_OK;
}
memset(pSlotList, 0xFF, sizeof(CK_SLOT_ID)*numSlots);
rc = pkcs11->C_GetSlotList(TRUE, pSlotList, &numSlots);
if ( rc != CKR_OK )
{
printf(" GetSlotList Error2 \n") ;
free(pSlotList) ; /* tidy up */
return rc ;
}
for ( i = 0 ; i < numSlots ; i++ )
{
if ( pSlotList[i] == sID )
{ /* Slot exists */
free(pSlotList) ; /* tidy up */
return rc ;
}
}
printf("There is no Slot-Id : %d \n",sID) ;
/* tidy up */
free(pSlotList) ;
}
return !CKR_OK;
}
/* *** ECC Action CODE **************************************************************************** */
CK_RV ECCaction(CK_SESSION_HANDLE hSession, int keylengthID)
{
CK_RV rc;
CK_OBJECT_HANDLE hPriKey;
CK_ULONG count = 0;
CK_OBJECT_HANDLE newhandle = 0 ;
CK_ATTRIBUTE objPriTemplate[] = {
{CKA_TOKEN, &bTrue, sizeof(bTrue)},
{CKA_LABEL, PriLabel, strlen((char*)PriLabel)}};
CK_ATTRIBUTE objPubTemplate[] = {
{CKA_TOKEN, &bTrue, sizeof(bTrue)},
{CKA_LABEL, PubLabel, strlen((char*)PubLabel)}};
CK_BYTE encodedParams[10] ;
CK_ULONG encodePlength ;
/* OID(Object Identifier) value for ESDSA */
CK_BYTE P192Params[10] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x01 };
CK_BYTE P224Params[7] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x21};
CK_BYTE P256Params[10] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 };
CK_BYTE P384Params[7] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 };
CK_BYTE P521Params[7] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23 };
CK_BYTE K256Params[7] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x0a }; /* secp256k1 */
switch(keylengthID) {
case 1 :
memcpy(encodedParams,P192Params,10) ;
encodePlength = 10 ;
break ;
case 2 :
memcpy(encodedParams,P224Params,7) ;
encodePlength = 7 ;
break ;
case 3 :
memcpy(encodedParams,P256Params,10) ;
encodePlength = 10 ;
break ;
case 4 :
memcpy(encodedParams,P384Params,7) ;
encodePlength = 7 ;
break ;
case 5 :
memcpy(encodedParams,P521Params,7) ;
encodePlength = 7 ;
break ;
case 6 :
memcpy(encodedParams,K256Params,7) ;
encodePlength = 7 ;
break ;
default :
printf("\nInvalid ECC key length \n");
/* error Recovery routine */
memcpy(encodedParams,P192Params,10) ;
encodePlength = 10 ;
break ;
}
/* Generate ECC Key pair */
rc = generateECCKeyPair(hSession, &hPriKey, PriLabel, PubLabel,encodedParams, encodePlength);
if ( rc != CKR_OK ) return rc ;
printf("\n\n--- ECC Private-Key Signing Test ----\n");
/* ECC Private-Key Signing Test */
rc = ECCSigningTest(hSession, hPriKey);
return rc;
}
/* ___ GENERATE ECC KEY PAIR _______________________________________________*/
CK_RV generateECCKeyPair(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE *hPrivKey, CK_CHAR_PTR PriLabel, CK_CHAR_PTR PubLabel, CK_CHAR_PTR pencodedParams , CK_ULONG encodePlength )
{
CK_RV rc;
CK_OBJECT_HANDLE hPubKey ;
// get the ECC Key Generation mechanism
CK_MECHANISM eccGenMech = {CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0};
// generate the EC Public Template
CK_ATTRIBUTE pubKeyTemplate[] = {
{CKA_CLASS, &PublicKeyClass, sizeof(PublicKeyClass)},
{CKA_TOKEN, &bTrue, sizeof(bTrue)},
{CKA_MODIFIABLE, &bFalse, sizeof(bFalse)},
{CKA_VERIFY, &bTrue, sizeof(bTrue)},
{CKA_DERIVE, &bTrue, sizeof(bTrue)},
{CKA_KEY_TYPE, &ECCKeyType, sizeof(ECCKeyType)},
{CKA_EC_PARAMS, pencodedParams, encodePlength },
{CKA_LABEL, PubLabel, strlen((char*)PubLabel)}
};
// generate the EC Private Template
CK_ATTRIBUTE privKeyTemplate[] ={
{CKA_CLASS, &PrivateKeyClass, sizeof(PrivateKeyClass)},
{CKA_TOKEN, &bTrue, sizeof(bTrue)},
{CKA_PRIVATE, &bTrue, sizeof(bTrue)},
{CKA_MODIFIABLE, &bFalse, sizeof(bFalse)},
{CKA_LABEL, PriLabel, strlen((char*)PriLabel)},
{CKA_KEY_TYPE, &ECCKeyType, sizeof(ECCKeyType)},
{CKA_SIGN, &bTrue, sizeof(bTrue)},
{CKA_SENSITIVE, &bTrue, sizeof(bTrue)},
{CKA_DERIVE, &bTrue, sizeof(bTrue)}
};
printf("\n\n--- Start to generate ECC Key Pair --------------\n");
// reset the ECC Key handles
hPubKey = 0;
*hPrivKey = 0;
// generate the ECC Key Pair
rc = pkcs11->C_GenerateKeyPair(hSession, &eccGenMech,
pubKeyTemplate, sizeof(pubKeyTemplate)/sizeof(CK_ATTRIBUTE),
privKeyTemplate, sizeof(privKeyTemplate)/sizeof(CK_ATTRIBUTE),
&hPubKey, hPrivKey );
if ( rc == CKR_OK ) printf("\n\n--- ECC Key Pair Generation Completed ----\n");
else printf("\n\n--- ECC Key Generation Fail !!!!! Error Code : %08X-----------\n",rc);
return rc;
}
/* ___ ECC Signing Test ___________________________________________________ */
CK_RV ECCSigningTest(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPriKey)
{
CK_RV rc;
CK_BYTE data[64] = { /* just Test Data */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x60, 0x61, 0x62, 0x63 } ;
CK_ULONG dataLen = sizeof(data);
unsigned char signature[1024];
CK_ULONG signatureLen = sizeof(signature);
CK_ULONG i ;
// get a ECDSA sign/verify mechanism
CK_MECHANISM signVerifyMech = { CKM_ECDSA, NULL_PTR, 0 };
printf("\n\n--- Start ECC Signing--------------------\n");
// sign the data
rc = pkcs11->C_SignInit(hSession, &signVerifyMech, hPriKey);
rc = pkcs11->C_Sign(hSession, data, dataLen, signature, &signatureLen);
if ( rc == CKR_OK )
{
printf("\r\nSigned Data : %d bytes \r\n",signatureLen ) ;
for ( i = 0 ; i < signatureLen ; i++ ) {
printf(" %02X ",signature[i]) ;
}
printf("\r\n") ;
}
else printf("\n\n--- ECC Sign Fail !!!!! -------------------\n");
return rc;
}