summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/ckfw/mechanism.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/ckfw/mechanism.c')
-rw-r--r--security/nss/lib/ckfw/mechanism.c1102
1 files changed, 1102 insertions, 0 deletions
diff --git a/security/nss/lib/ckfw/mechanism.c b/security/nss/lib/ckfw/mechanism.c
new file mode 100644
index 0000000000..fe20aa94a5
--- /dev/null
+++ b/security/nss/lib/ckfw/mechanism.c
@@ -0,0 +1,1102 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * mechanism.c
+ *
+ * This file implements the NSSCKFWMechanism type and methods.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWMechanism
+ *
+ * -- create/destroy --
+ * nssCKFWMechanism_Create
+ * nssCKFWMechanism_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWMechanism_GetMDMechanism
+ * nssCKFWMechanism_GetParameter
+ *
+ * -- private accessors --
+ *
+ * -- module fronts --
+ * nssCKFWMechanism_GetMinKeySize
+ * nssCKFWMechanism_GetMaxKeySize
+ * nssCKFWMechanism_GetInHardware
+ * nssCKFWMechanism_GetCanEncrypt
+ * nssCKFWMechanism_GetCanDecrypt
+ * nssCKFWMechanism_GetCanDigest
+ * nssCKFWMechanism_GetCanSign
+ * nssCKFWMechanism_GetCanSignRecover
+ * nssCKFWMechanism_GetCanVerify
+ * nssCKFWMechanism_GetCanGenerate
+ * nssCKFWMechanism_GetCanGenerateKeyPair
+ * nssCKFWMechanism_GetCanUnwrap
+ * nssCKFWMechanism_GetCanWrap
+ * nssCKFWMechanism_GetCanDerive
+ * nssCKFWMechanism_EncryptInit
+ * nssCKFWMechanism_DecryptInit
+ * nssCKFWMechanism_DigestInit
+ * nssCKFWMechanism_SignInit
+ * nssCKFWMechanism_VerifyInit
+ * nssCKFWMechanism_SignRecoverInit
+ * nssCKFWMechanism_VerifyRecoverInit
+ * nssCKFWMechanism_GenerateKey
+ * nssCKFWMechanism_GenerateKeyPair
+ * nssCKFWMechanism_GetWrapKeyLength
+ * nssCKFWMechanism_WrapKey
+ * nssCKFWMechanism_UnwrapKey
+ * nssCKFWMechanism_DeriveKey
+ */
+
+struct NSSCKFWMechanismStr {
+ NSSCKMDMechanism *mdMechanism;
+ NSSCKMDToken *mdToken;
+ NSSCKFWToken *fwToken;
+ NSSCKMDInstance *mdInstance;
+ NSSCKFWInstance *fwInstance;
+};
+
+/*
+ * nssCKFWMechanism_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKFWMechanism *
+nssCKFWMechanism_Create(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
+{
+ NSSCKFWMechanism *fwMechanism;
+
+ fwMechanism = nss_ZNEW(NULL, NSSCKFWMechanism);
+ if (!fwMechanism) {
+ return (NSSCKFWMechanism *)NULL;
+ }
+ fwMechanism->mdMechanism = mdMechanism;
+ fwMechanism->mdToken = mdToken;
+ fwMechanism->fwToken = fwToken;
+ fwMechanism->mdInstance = mdInstance;
+ fwMechanism->fwInstance = fwInstance;
+ return fwMechanism;
+}
+
+/*
+ * nssCKFWMechanism_Destroy
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWMechanism_Destroy(
+ NSSCKFWMechanism *fwMechanism)
+{
+ /* destroy any fw resources held by nssCKFWMechanism (currently none) */
+
+ if (fwMechanism->mdMechanism->Destroy) {
+ /* destroys it's parent as well */
+ fwMechanism->mdMechanism->Destroy(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance);
+ }
+ /* if the Destroy function wasn't supplied, then the mechanism is 'static',
+ * and there is nothing to destroy */
+ return;
+}
+
+/*
+ * nssCKFWMechanism_GetMDMechanism
+ *
+ */
+NSS_IMPLEMENT NSSCKMDMechanism *
+nssCKFWMechanism_GetMDMechanism(
+ NSSCKFWMechanism *fwMechanism)
+{
+ return fwMechanism->mdMechanism;
+}
+
+/*
+ * nssCKFWMechanism_GetMinKeySize
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWMechanism_GetMinKeySize(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->GetMinKeySize) {
+ return 0;
+ }
+
+ return fwMechanism->mdMechanism->GetMinKeySize(fwMechanism->mdMechanism,
+ fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
+}
+
+/*
+ * nssCKFWMechanism_GetMaxKeySize
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWMechanism_GetMaxKeySize(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->GetMaxKeySize) {
+ return 0;
+ }
+
+ return fwMechanism->mdMechanism->GetMaxKeySize(fwMechanism->mdMechanism,
+ fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
+}
+
+/*
+ * nssCKFWMechanism_GetInHardware
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWMechanism_GetInHardware(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->GetInHardware) {
+ return CK_FALSE;
+ }
+
+ return fwMechanism->mdMechanism->GetInHardware(fwMechanism->mdMechanism,
+ fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
+}
+
+/*
+ * the following are determined automatically by which of the cryptographic
+ * functions are defined for this mechanism.
+ */
+/*
+ * nssCKFWMechanism_GetCanEncrypt
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanEncrypt(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->EncryptInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanDecrypt
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanDecrypt(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->DecryptInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanDigest
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanDigest(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->DigestInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanSign
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanSign(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->SignInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanSignRecover
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanSignRecover(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->SignRecoverInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanVerify
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanVerify(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->VerifyInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanVerifyRecover
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanVerifyRecover(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->VerifyRecoverInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanGenerate
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanGenerate(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->GenerateKey) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanGenerateKeyPair
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanGenerateKeyPair(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->GenerateKeyPair) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanUnwrap
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanUnwrap(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->UnwrapKey) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanWrap
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanWrap(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->WrapKey) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * nssCKFWMechanism_GetCanDerive
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetCanDerive(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
+{
+ if (!fwMechanism->mdMechanism->DeriveKey) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
+}
+
+/*
+ * These are the actual crypto operations
+ */
+
+/*
+ * nssCKFWMechanism_EncryptInit
+ * Start an encryption session.
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_EncryptInit(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
+{
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ CK_RV error = CKR_OK;
+
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_EncryptDecrypt);
+ if (fwOperation) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ if (!fwMechanism->mdMechanism->EncryptInit) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = nssCKFWObject_GetMDObject(fwObject);
+ mdOperation = fwMechanism->mdMechanism->EncryptInit(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdObject,
+ fwObject,
+ &error);
+ if (!mdOperation) {
+ goto loser;
+ }
+
+ fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
+ mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance,
+ NSSCKFWCryptoOperationType_Encrypt, &error);
+ if (fwOperation) {
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
+ NSSCKFWCryptoOperationState_EncryptDecrypt);
+ }
+
+loser:
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_DecryptInit
+ * Start an encryption session.
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_DecryptInit(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
+{
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ CK_RV error = CKR_OK;
+
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_EncryptDecrypt);
+ if (fwOperation) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ if (!fwMechanism->mdMechanism->DecryptInit) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = nssCKFWObject_GetMDObject(fwObject);
+ mdOperation = fwMechanism->mdMechanism->DecryptInit(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdObject,
+ fwObject,
+ &error);
+ if (!mdOperation) {
+ goto loser;
+ }
+
+ fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
+ mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance,
+ NSSCKFWCryptoOperationType_Decrypt, &error);
+ if (fwOperation) {
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
+ NSSCKFWCryptoOperationState_EncryptDecrypt);
+ }
+
+loser:
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_DigestInit
+ * Start an encryption session.
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_DigestInit(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKFWSession *fwSession)
+{
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ CK_RV error = CKR_OK;
+
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_Digest);
+ if (fwOperation) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ if (!fwMechanism->mdMechanism->DigestInit) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdOperation = fwMechanism->mdMechanism->DigestInit(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ &error);
+ if (!mdOperation) {
+ goto loser;
+ }
+
+ fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
+ mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance,
+ NSSCKFWCryptoOperationType_Digest, &error);
+ if (fwOperation) {
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
+ NSSCKFWCryptoOperationState_Digest);
+ }
+
+loser:
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_SignInit
+ * Start an encryption session.
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_SignInit(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
+{
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ CK_RV error = CKR_OK;
+
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_SignVerify);
+ if (fwOperation) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ if (!fwMechanism->mdMechanism->SignInit) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = nssCKFWObject_GetMDObject(fwObject);
+ mdOperation = fwMechanism->mdMechanism->SignInit(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdObject,
+ fwObject,
+ &error);
+ if (!mdOperation) {
+ goto loser;
+ }
+
+ fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
+ mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance,
+ NSSCKFWCryptoOperationType_Sign, &error);
+ if (fwOperation) {
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
+ NSSCKFWCryptoOperationState_SignVerify);
+ }
+
+loser:
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_VerifyInit
+ * Start an encryption session.
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_VerifyInit(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
+{
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ CK_RV error = CKR_OK;
+
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_SignVerify);
+ if (fwOperation) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ if (!fwMechanism->mdMechanism->VerifyInit) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = nssCKFWObject_GetMDObject(fwObject);
+ mdOperation = fwMechanism->mdMechanism->VerifyInit(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdObject,
+ fwObject,
+ &error);
+ if (!mdOperation) {
+ goto loser;
+ }
+
+ fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
+ mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance,
+ NSSCKFWCryptoOperationType_Verify, &error);
+ if (fwOperation) {
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
+ NSSCKFWCryptoOperationState_SignVerify);
+ }
+
+loser:
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_SignRecoverInit
+ * Start an encryption session.
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_SignRecoverInit(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
+{
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ CK_RV error = CKR_OK;
+
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_SignVerify);
+ if (fwOperation) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ if (!fwMechanism->mdMechanism->SignRecoverInit) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = nssCKFWObject_GetMDObject(fwObject);
+ mdOperation = fwMechanism->mdMechanism->SignRecoverInit(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdObject,
+ fwObject,
+ &error);
+ if (!mdOperation) {
+ goto loser;
+ }
+
+ fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
+ mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance,
+ NSSCKFWCryptoOperationType_SignRecover, &error);
+ if (fwOperation) {
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
+ NSSCKFWCryptoOperationState_SignVerify);
+ }
+
+loser:
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_VerifyRecoverInit
+ * Start an encryption session.
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_VerifyRecoverInit(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
+{
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ CK_RV error = CKR_OK;
+
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_SignVerify);
+ if (fwOperation) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ if (!fwMechanism->mdMechanism->VerifyRecoverInit) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = nssCKFWObject_GetMDObject(fwObject);
+ mdOperation = fwMechanism->mdMechanism->VerifyRecoverInit(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdObject,
+ fwObject,
+ &error);
+ if (!mdOperation) {
+ goto loser;
+ }
+
+ fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
+ mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance,
+ NSSCKFWCryptoOperationType_VerifyRecover, &error);
+ if (fwOperation) {
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
+ NSSCKFWCryptoOperationState_SignVerify);
+ }
+
+loser:
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_GenerateKey
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWMechanism_GenerateKey(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_PTR pMechanism,
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError)
+{
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ NSSCKFWObject *fwObject = NULL;
+ NSSArena *arena;
+
+ if (!fwMechanism->mdMechanism->GenerateKey) {
+ *pError = CKR_FUNCTION_FAILED;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ arena = nssCKFWToken_GetArena(fwMechanism->fwToken, pError);
+ if (!arena) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = fwMechanism->mdMechanism->GenerateKey(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ pTemplate,
+ ulAttributeCount,
+ pError);
+
+ if (!mdObject) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ fwObject = nssCKFWObject_Create(arena, mdObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
+
+ return fwObject;
+}
+
+/*
+ * nssCKFWMechanism_GenerateKeyPair
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_GenerateKeyPair(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_PTR pMechanism,
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount,
+ NSSCKFWObject **fwPublicKeyObject,
+ NSSCKFWObject **fwPrivateKeyObject)
+{
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdPublicKeyObject;
+ NSSCKMDObject *mdPrivateKeyObject;
+ NSSArena *arena;
+ CK_RV error = CKR_OK;
+
+ if (!fwMechanism->mdMechanism->GenerateKeyPair) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ arena = nssCKFWToken_GetArena(fwMechanism->fwToken, &error);
+ if (!arena) {
+ if (CKR_OK == error) {
+ error = CKR_GENERAL_ERROR;
+ }
+ return error;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ error = fwMechanism->mdMechanism->GenerateKeyPair(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ pPublicKeyTemplate,
+ ulPublicKeyAttributeCount,
+ pPrivateKeyTemplate,
+ ulPrivateKeyAttributeCount,
+ &mdPublicKeyObject,
+ &mdPrivateKeyObject);
+
+ if (CKR_OK != error) {
+ return error;
+ }
+
+ *fwPublicKeyObject = nssCKFWObject_Create(arena, mdPublicKeyObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, &error);
+ if (!*fwPublicKeyObject) {
+ return error;
+ }
+ *fwPrivateKeyObject = nssCKFWObject_Create(arena, mdPrivateKeyObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, &error);
+
+ return error;
+}
+
+/*
+ * nssCKFWMechanism_GetWrapKeyLength
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWMechanism_GetWrapKeyLength(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_PTR pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwWrappingKeyObject,
+ NSSCKFWObject *fwKeyObject,
+ CK_RV *pError)
+{
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdWrappingKeyObject;
+ NSSCKMDObject *mdKeyObject;
+
+ if (!fwMechanism->mdMechanism->WrapKey) {
+ *pError = CKR_FUNCTION_FAILED;
+ return (CK_ULONG)0;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
+ mdKeyObject = nssCKFWObject_GetMDObject(fwKeyObject);
+ return fwMechanism->mdMechanism->GetWrapKeyLength(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdWrappingKeyObject,
+ fwWrappingKeyObject,
+ mdKeyObject,
+ fwKeyObject,
+ pError);
+}
+
+/*
+ * nssCKFWMechanism_WrapKey
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_WrapKey(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_PTR pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwWrappingKeyObject,
+ NSSCKFWObject *fwKeyObject,
+ NSSItem *wrappedKey)
+{
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdWrappingKeyObject;
+ NSSCKMDObject *mdKeyObject;
+
+ if (!fwMechanism->mdMechanism->WrapKey) {
+ return CKR_FUNCTION_FAILED;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
+ mdKeyObject = nssCKFWObject_GetMDObject(fwKeyObject);
+ return fwMechanism->mdMechanism->WrapKey(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdWrappingKeyObject,
+ fwWrappingKeyObject,
+ mdKeyObject,
+ fwKeyObject,
+ wrappedKey);
+}
+
+/*
+ * nssCKFWMechanism_UnwrapKey
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWMechanism_UnwrapKey(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_PTR pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwWrappingKeyObject,
+ NSSItem *wrappedKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError)
+{
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ NSSCKMDObject *mdWrappingKeyObject;
+ NSSCKFWObject *fwObject = NULL;
+ NSSArena *arena;
+
+ if (!fwMechanism->mdMechanism->UnwrapKey) {
+ /* we could simulate UnwrapKey using Decrypt and Create object, but
+ * 1) it's not clear that would work well, and 2) the low level token
+ * may want to restrict unwrap key for a reason, so just fail it it
+ * can't be done */
+ *pError = CKR_FUNCTION_FAILED;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ arena = nssCKFWToken_GetArena(fwMechanism->fwToken, pError);
+ if (!arena) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
+ mdObject = fwMechanism->mdMechanism->UnwrapKey(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdWrappingKeyObject,
+ fwWrappingKeyObject,
+ wrappedKey,
+ pTemplate,
+ ulAttributeCount,
+ pError);
+
+ if (!mdObject) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ fwObject = nssCKFWObject_Create(arena, mdObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
+
+ return fwObject;
+}
+
+/*
+ * nssCKFWMechanism_DeriveKey
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWMechanism_DeriveKey(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_PTR pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwBaseKeyObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError)
+{
+ NSSCKMDSession *mdSession;
+ NSSCKMDObject *mdObject;
+ NSSCKMDObject *mdBaseKeyObject;
+ NSSCKFWObject *fwObject = NULL;
+ NSSArena *arena;
+
+ if (!fwMechanism->mdMechanism->DeriveKey) {
+ *pError = CKR_FUNCTION_FAILED;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ arena = nssCKFWToken_GetArena(fwMechanism->fwToken, pError);
+ if (!arena) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdBaseKeyObject = nssCKFWObject_GetMDObject(fwBaseKeyObject);
+ mdObject = fwMechanism->mdMechanism->DeriveKey(
+ fwMechanism->mdMechanism,
+ fwMechanism,
+ pMechanism,
+ mdSession,
+ fwSession,
+ fwMechanism->mdToken,
+ fwMechanism->fwToken,
+ fwMechanism->mdInstance,
+ fwMechanism->fwInstance,
+ mdBaseKeyObject,
+ fwBaseKeyObject,
+ pTemplate,
+ ulAttributeCount,
+ pError);
+
+ if (!mdObject) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ fwObject = nssCKFWObject_Create(arena, mdObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
+
+ return fwObject;
+}