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