diff options
author | Pramod Raghavendra Jayathirth <pramod.raghavendra.jayathirth@intel.com> | 2018-03-27 09:24:56 -0700 |
---|---|---|
committer | Pramod <pramod.raghavendra.jayathirth@intel.com> | 2018-03-30 02:17:20 +0000 |
commit | 4ba28823277dd1d154e4a26f7eae440c40b1f9fd (patch) | |
tree | 6acf40941e2cb98670374be20279e18cc96b5c64 /SoftHSMv2/src/lib/SoftHSM.cpp | |
parent | 8a5b33a9ba846d785d244e29bc29a46f7be34928 (diff) |
Adds the HardwareInfra layer in SoftHSM
This enables the support of multiple HSMs
Issue-ID: AAF-200
Change-Id: I825a72a0bf46827ff3be0c0311085cf970b970a6
Signed-off-by: Pramod <pramod.raghavendra.jayathirth@intel.com>
Diffstat (limited to 'SoftHSMv2/src/lib/SoftHSM.cpp')
-rw-r--r-- | SoftHSMv2/src/lib/SoftHSM.cpp | 174 |
1 files changed, 159 insertions, 15 deletions
diff --git a/SoftHSMv2/src/lib/SoftHSM.cpp b/SoftHSMv2/src/lib/SoftHSM.cpp index 7a23a8a..214178f 100644 --- a/SoftHSMv2/src/lib/SoftHSM.cpp +++ b/SoftHSMv2/src/lib/SoftHSM.cpp @@ -67,6 +67,8 @@ #include "P11Objects.h" #include "odd.h" +#include "HwInfra.h" + #if defined(WITH_OPENSSL) #include "OSSLCryptoFactory.h" #else @@ -101,6 +103,39 @@ std::auto_ptr<SoftHSM> SoftHSM::instance(NULL); #endif +static CK_RV Extract_key_handle(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, void *hwKeyHandle) +{ + CK_RV rv=CK_TRUE; + + // get value of the hw key handle + CK_ATTRIBUTE valAttrib[] = { + {CKA_PRIME_1, NULL_PTR, 0} + }; + + // Get the length of the attribute first + rv = C_GetAttributeValue(hSession, hObject, valAttrib, sizeof(valAttrib)/sizeof(CK_ATTRIBUTE)); + if(rv != CKR_OK) + { + printf("Getting length of keyHandle with C_GetAttributeValue() API failed ! \n"); + return rv; + } + + valAttrib[0].pValue = (CK_VOID_PTR) malloc(valAttrib[0].ulValueLen); + + rv = C_GetAttributeValue(hSession, hObject, valAttrib, sizeof(valAttrib)/sizeof(CK_ATTRIBUTE)); + + // Convert the keyHandle from string to CK_ULONG + sscanf((char*) valAttrib[0].pValue, "%lx", (CK_ULONG *) hwKeyHandle); + printf("Extract_key_handle:: hwKeyHandle: %lu \n", (CK_ULONG) hwKeyHandle); + + if(!(valAttrib[0].pValue)) + { + free(valAttrib[0].pValue); + } + + return rv; +} + static CK_RV newP11Object(CK_OBJECT_CLASS objClass, CK_KEY_TYPE keyType, CK_CERTIFICATE_TYPE certType, P11Object **p11object) { switch(objClass) { @@ -342,6 +377,7 @@ SoftHSM::SoftHSM() slotManager = NULL; sessionManager = NULL; handleManager = NULL; + isHWavailable = false; } // Destructor @@ -518,6 +554,17 @@ CK_RV SoftHSM::C_Initialize(CK_VOID_PTR pInitArgs) // Set the state to initialised isInitialised = true; + if(prepareHWPlugin()) + { + printf("HW plugin NOT available to use ! \n"); + isHWavailable = false; + } + else + { + printf("HW plugin available and initialized ! \n"); + isHWavailable = true; + } + return CKR_OK; } @@ -4168,20 +4215,33 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan #endif } - // Initialize signing - if (bAllowMultiPartOp && !asymCrypto->signInit(privateKey,mechanism,param,paramLen)) - { - asymCrypto->recyclePrivateKey(privateKey); - CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto); - return CKR_MECHANISM_INVALID; - } - - // Check if re-authentication is required - if (key->getBooleanValue(CKA_ALWAYS_AUTHENTICATE, false)) - { - session->setReAuthentication(true); - } + // Initialize signing + if(isHWavailable) + { + // Extract HW key handle + CK_ULONG hwKeyHandle = 0; + if(!Extract_key_handle (hSession, hKey, &hwKeyHandle)) + { + LOG("ERROR in extracting key handle \n"); + session->resetOp(); + return CKR_GENERAL_ERROR; + } + LOG("Extracted key handle value: %lu \n", hwKeyHandle); + if(! HwInfraSignInit(&hwKeyHandle, mechanism, param, paramLen)) + { + return CKR_MECHANISM_INVALID; + } + } + else + { + if (bAllowMultiPartOp && !asymCrypto->signInit(privateKey,mechanism,param,paramLen)) + { + asymCrypto->recyclePrivateKey(privateKey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto); + return CKR_MECHANISM_INVALID; + } + } session->setOpType(SESSION_OP_SIGN); session->setAsymmetricCryptoOp(asymCrypto); session->setMechanism(mechanism); @@ -4189,6 +4249,7 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan session->setAllowMultiPartOp(bAllowMultiPartOp); session->setAllowSinglePartOp(true); session->setPrivateKey(privateKey); + session->setKeyHandle(hKey); return CKR_OK; } @@ -4336,6 +4397,79 @@ static CK_RV AsymSign(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, C return CKR_OK; } +// AsymmetricAlgorithm version of C_Sign +static CK_RV AsymSignHW(CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) +{ + AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp(); + AsymMech::Type mechanism = session->getMechanism(); + PrivateKey* privateKey = session->getPrivateKey(); + CK_ULONG hwKeyHandle = 0; + if (asymCrypto == NULL || !session->getAllowSinglePartOp() || privateKey == NULL) + { + session->resetOp(); + return CKR_OPERATION_NOT_INITIALIZED; + } + + // Size of the signature + CK_ULONG size = privateKey->getOutputLength(); + if (pSignature == NULL_PTR) + { + *pulSignatureLen = size; + return CKR_OK; + } + + // Check buffer sizeq + if (*pulSignatureLen < size) + { + *pulSignatureLen = size; + return CKR_BUFFER_TOO_SMALL; + } + + // Get the data + ByteString data; + + // We must allow input length <= k and therfore need to prepend the data with zeroes. + if (mechanism == AsymMech::RSA) { + data.wipe(size-ulDataLen); + } + + data += ByteString(pData, ulDataLen); + ByteString signature; + + // Extract HW key handle + CK_OBJECT_HANDLE hKey = session->getKeyHandle(); + if(!Extract_key_handle (hSession, hKey, &hwKeyHandle)) + { + LOG("ERROR in extracting key handle \n"); + session->resetOp(); + return CKR_GENERAL_ERROR; + } + LOG("Extracted key handle value: %lu \n", hwKeyHandle); + + // Sign the data + if(!HwInfraSign((void *)&hwKeyHandle, mechanism, + pData, ulDataLen, + pSignature, (int *) pulSignatureLen)) + { + session->resetOp(); + return CKR_GENERAL_ERROR; + } + + // Check size + if (*pulSignatureLen != size) + { + ERROR_MSG("The size of the signature differs from the size of the mechanism"); + session->resetOp(); + return CKR_GENERAL_ERROR; + } + + + session->resetOp(); + return CKR_OK; +} + + + // Sign the data in a single pass operation CK_RV SoftHSM::C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { @@ -4356,8 +4490,18 @@ CK_RV SoftHSM::C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ul return MacSign(session, pData, ulDataLen, pSignature, pulSignatureLen); else - return AsymSign(session, pData, ulDataLen, - pSignature, pulSignatureLen); + { + if(isHWavailable) + { + return AsymSignHW(hSession, session, pData, ulDataLen, + pSignature, pulSignatureLen); + } + else + { + return AsymSign(session, pData, ulDataLen, + pSignature, pulSignatureLen); + } + } } // MacAlgorithm version of C_SignUpdate |