+// AsymmetricAlgorithm version of C_SignFinal
+static CK_RV AsymSignFinalHW(CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
+ PrivateKey* privateKey = session->getPrivateKey();
+ if (asymCrypto == NULL || privateKey == NULL)
+ {
+ session->resetOp();
+ return CKR_OPERATION_NOT_INITIALIZED;
+ }
+
+ // Check if re-authentication is required
+ if (session->getReAuthentication())
+ {
+ session->resetOp();
+ return CKR_USER_NOT_LOGGED_IN;
+ }
+
+ // Size of the signature
+ CK_ULONG size = privateKey->getOutputLength();
+ if (pSignature == NULL_PTR)
+ {
+ *pulSignatureLen = size;
+ return CKR_OK;
+ }
+
+ // Check buffer size
+ if (*pulSignatureLen < size)
+ {
+ *pulSignatureLen = size;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+#if 0
+ // Get the signature
+ ByteString signature;
+ if (!asymCrypto->signFinal(signature))
+ {
+ session->resetOp();
+ return CKR_GENERAL_ERROR;
+ }
+#endif
+ AsymMech::Type mechanism = session->getMechanism();
+ // Extract HW key handle
+ CK_ULONG hwKeyHandle = 0;
+ CK_OBJECT_HANDLE hKey = session->getKeyHandle();
+ if(Extract_key_handle (hSession, hKey, &hwKeyHandle) != CKR_OK)
+ {
+ LOG("ERROR in extracting key handle \n");
+ session->resetOp();
+ return CKR_GENERAL_ERROR;
+ }
+ LOG("Extracted key handle value : 0x%lx \n", hwKeyHandle);
+
+ void *hwCryptoOpaque = session->getHwCryptoOpaque();
+ // Sign the data
+ if(HwInfraSignFinal((void *)&hwKeyHandle, mechanism,
+ hwCryptoOpaque, pSignature, (int *) pulSignatureLen) != 0 )
+ {
+ 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;
+ }
+ *pulSignatureLen = size;
+
+ session->resetOp();
+ return CKR_OK;
+}
+
+