diff options
Diffstat (limited to 'security/nss/lib/ckfw/mechanism.c')
-rw-r--r-- | security/nss/lib/ckfw/mechanism.c | 1102 |
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 000000000..fe20aa94a --- /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; +} |