Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
pkcs11c.c File Reference
#include "seccomon.h"
#include "secitem.h"
#include "secport.h"
#include "blapi.h"
#include "pqgutil.h"
#include "pkcs11.h"
#include "pkcs11i.h"
#include "lowkeyi.h"
#include "pcert.h"
#include "sechash.h"
#include "secder.h"
#include "secdig.h"
#include "lowpbe.h"
#include "pkcs11t.h"
#include "secoid.h"
#include "alghmac.h"
#include "softoken.h"
#include "secasn1.h"
#include "secerr.h"
#include "ssl3prot.h"
#include "prprf.h"
#include "pkcs11f.h"

Go to the source code of this file.

Defines

#define __PASTE(x, y)   x##y
#define CK_EXTERN   extern
#define CK_PKCS11_FUNCTION_INFO(func)   CK_RV __PASTE(NS,func)
#define CK_NEED_ARG_LIST   1
#define INIT_MECH(mech, mmm)
#define DOSUB(mmm)
#define INIT_RSA_SIGN_MECH(mmm)
#define INIT_HMAC_MECH(mmm)
#define INIT_RSA_VFY_MECH(mmm)
#define PAIRWISE_DIGEST_LENGTH   SHA1_LENGTH /* 160-bits */
#define PAIRWISE_MESSAGE_LENGTH   20 /* 160-bits */
#define NUM_MIXERS   9
#define SSL3_PMS_LENGTH   48
#define SSL3_MASTER_SECRET_LENGTH   48
#define sftk_Decrement(stateSize, len)

Functions

static void sftk_Null (void *data, PRBool freeit)
static void sftk_FreePrivKey (NSSLOWKEYPrivateKey *key, PRBool freeit)
static void sftk_Space (void *data, PRBool freeit)
static CK_RV sftk_cdmf2des (unsigned char *cdmfkey, unsigned char *deskey)
CK_RV NSC_DestroyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
SFTKSessionContext * sftk_ReturnContextByType (SFTKSession *session, SFTKContextType type)
void sftk_SetContextByType (SFTKSession *session, SFTKContextType type, SFTKSessionContext *context)
static CK_RV sftk_GetContext (CK_SESSION_HANDLE handle, SFTKSessionContext **contextPtr, SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr)
static CK_RV sftk_InitGeneric (SFTKSession *session, SFTKSessionContext **contextPtr, SFTKContextType ctype, SFTKObject **keyPtr, CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr, CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation)
static CK_RV sftk_CryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype, SFTKContextType contextType, PRBool isEncrypt)
CK_RV NSC_EncryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
CK_RV NSC_EncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
CK_RV NSC_EncryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
CK_RV NSC_DecryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
CK_RV NSC_DecryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
CK_RV NSC_DecryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
CK_RV NSC_Decrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
CK_RV NSC_DigestInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
CK_RV NSC_Digest (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
CK_RV NSC_DigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
CK_RV NSC_DigestFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
static SECStatus sftk_HMACCopy (CK_ULONG *copyLen, unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, unsigned char *hash, unsigned int hashLen)
static SECStatus sftk_HMACCmp (CK_ULONG *copyLen, unsigned char *sig, unsigned int sigLen, unsigned char *hash, unsigned int hashLen)
static CK_RV sftk_doHMACInit (SFTKSessionContext *context, HASH_HashType hash, SFTKObject *key, CK_ULONG mac_size)
static SECStatus sftk_SSLMACSign (SFTKSSLMACInfo *info, unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, unsigned char *hash, unsigned int hashLen)
static SECStatus sftk_SSLMACVerify (SFTKSSLMACInfo *info, unsigned char *sig, unsigned int sigLen, unsigned char *hash, unsigned int hashLen)
static CK_RV sftk_doSSLMACInit (SFTKSessionContext *context, SECOidTag oid, SFTKObject *key, CK_ULONG mac_size)
static CK_RV sftk_InitCBCMac (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage, SFTKContextType contextType)
static SECStatus sftk_HashSign (SFTKHashSignInfo *info, unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, unsigned char *hash, unsigned int hashLen)
SECStatus RSA_HashSign (SECOidTag hashOid, NSSLOWKEYPrivateKey *key, unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, unsigned char *hash, unsigned int hashLen)
static SECStatus nsc_DSA_Verify_Stub (void *ctx, void *sigBuf, unsigned int sigLen, void *dataBuf, unsigned int dataLen)
static SECStatus nsc_DSA_Sign_Stub (void *ctx, void *sigBuf, unsigned int *sigLen, unsigned int maxSigLen, void *dataBuf, unsigned int dataLen)
CK_RV NSC_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
static CK_RV sftk_MACUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, SFTKContextType type)
CK_RV NSC_SignUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
CK_RV NSC_SignFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
CK_RV NSC_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
CK_RV NSC_SignRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
CK_RV NSC_SignRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
static SECStatus sftk_hashCheckSign (SFTKHashVerifyInfo *info, unsigned char *sig, unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
SECStatus RSA_HashCheckSign (SECOidTag hashOid, NSSLOWKEYPublicKey *key, unsigned char *sig, unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
CK_RV NSC_VerifyInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
CK_RV NSC_Verify (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
CK_RV NSC_VerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
CK_RV NSC_VerifyFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
CK_RV NSC_VerifyRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
CK_RV NSC_VerifyRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
CK_RV NSC_SeedRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
CK_RV NSC_GenerateRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
static CK_RV nsc_pbe_key_gen (NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism, char *buf, CK_ULONG *key_length, PRBool faulty3DES)
static CK_RV nsc_parameter_gen (CK_KEY_TYPE key_type, SFTKObject *key)
static CK_RV nsc_SetupBulkKeyGen (CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type, CK_ULONG *key_length)
CK_RV nsc_SetupHMACKeyGen (CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
static CK_RV nsc_SetupPBEKeyGen (CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe, CK_KEY_TYPE *key_type)
CK_RV NSC_GenerateKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
static CK_RV sftk_PairwiseConsistencyCheck (CK_SESSION_HANDLE hSession, SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
static SECItem * sftk_PackagePrivateKey (SFTKObject *key, CK_RV *crvp)
static CK_RV sftk_mapWrap (CK_RV crv)
CK_RV NSC_WrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
static SECStatus sftk_unwrapPrivateKey (SFTKObject *key, SECItem *bpki)
CK_RV NSC_UnwrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
static CK_RV sftk_buildSSLKey (CK_SESSION_HANDLE hSession, SFTKObject *baseKey, PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize, CK_OBJECT_HANDLE *keyHandle)
static void sftk_freeSSLKeys (CK_SESSION_HANDLE session, CK_SSL3_KEY_MAT_OUT *returnedMaterial)
static CK_RV sftk_DeriveSensitiveCheck (SFTKObject *baseKey, SFTKObject *destKey)
unsigned long sftk_MapKeySize (CK_KEY_TYPE keyType)
CK_RV NSC_DeriveKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
CK_RV NSC_GetFunctionStatus (CK_SESSION_HANDLE hSession)
CK_RV NSC_CancelFunction (CK_SESSION_HANDLE hSession)
CK_RV NSC_GetOperationState (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
CK_RV NSC_SetOperationState (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
CK_RV NSC_DigestEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
CK_RV NSC_DecryptDigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
CK_RV NSC_SignEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
CK_RV NSC_DecryptVerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
CK_RV NSC_DigestKey (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)

Variables

static unsigned char ssl_pad_1 [60]
static unsigned char ssl_pad_2 [60]
static const char *const mixers [NUM_MIXERS]

Define Documentation

#define __PASTE (   x,
  y 
)    x##y

Definition at line 78 of file pkcs11c.c.

#define CK_EXTERN   extern

Definition at line 87 of file pkcs11c.c.

Definition at line 90 of file pkcs11c.c.

Definition at line 88 of file pkcs11c.c.

#define DOSUB (   mmm)
Value:
static CK_RV \
sftk_doSub ## mmm(SFTKSessionContext *context) { \
    mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \
    context->hashInfo    = (void *)      mmm ## _ctx; \
    context->hashUpdate  = (SFTKHash)    mmm ## _Update; \
    context->end         = (SFTKEnd)     mmm ## _End; \
    context->hashdestroy = (SFTKDestroy) mmm ## _DestroyContext; \
    if (!context->hashInfo) { \
       return CKR_HOST_MEMORY; \
    } \
    mmm ## _Begin( mmm ## _ctx ); \
    return CKR_OK; \
}

Definition at line 1255 of file pkcs11c.c.

#define INIT_HMAC_MECH (   mmm)
Value:
case CKM_ ## mmm ## _HMAC_GENERAL: \
       crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, \
                            *(CK_ULONG *)pMechanism->pParameter); \
       break; \
    case CKM_ ## mmm ## _HMAC: \
       crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, mmm ## _LENGTH); \
       break;
#define INIT_MECH (   mech,
  mmm 
)
Value:
case mech: { \
       mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \
	context->cipherInfo    = (void *)mmm ## _ctx; \
	context->cipherInfoLen = mmm ## _FlattenSize(mmm ## _ctx); \
	context->currentMech   = mech; \
	context->hashUpdate    = (SFTKHash)    mmm ## _Update; \
	context->end           = (SFTKEnd)     mmm ## _End; \
	context->destroy       = (SFTKDestroy) mmm ## _DestroyContext; \
	context->maxLen        = mmm ## _LENGTH; \
        if (mmm ## _ctx) \
           mmm ## _Begin(mmm ## _ctx); \
       else  \
           crv = CKR_HOST_MEMORY; \
       break; \
    }
Value:
case CKM_ ## mmm ## _RSA_PKCS: \
        context->multi = PR_TRUE; \
       crv = sftk_doSub ## mmm (context); \
       if (crv != CKR_OK) break; \
       context->update = (SFTKCipher) sftk_HashSign; \
       info = PORT_New(SFTKHashSignInfo); \
       if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
	info->hashOid = SEC_OID_ ## mmm ; \
       goto finish_rsa;
Value:
case CKM_ ## mmm ## _RSA_PKCS: \
        context->multi = PR_TRUE; \
       crv = sftk_doSub ## mmm (context); \
       if (crv != CKR_OK) break; \
       context->verify = (SFTKVerify) sftk_hashCheckSign; \
       info = PORT_New(SFTKHashVerifyInfo); \
       if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
	info->hashOid = SEC_OID_ ## mmm ; \
       goto finish_rsa;
#define NUM_MIXERS   9

Definition at line 4647 of file pkcs11c.c.

Definition at line 3031 of file pkcs11c.c.

#define PAIRWISE_MESSAGE_LENGTH   20 /* 160-bits */

Definition at line 3032 of file pkcs11c.c.

#define sftk_Decrement (   stateSize,
  len 
)
Value:
stateSize = ((stateSize) > (CK_ULONG)(len)) ? \
                            ((stateSize) - (CK_ULONG)(len)) : 0;

Definition at line 5716 of file pkcs11c.c.

Definition at line 4659 of file pkcs11c.c.

Definition at line 4658 of file pkcs11c.c.


Function Documentation

Definition at line 5673 of file pkcs11c.c.

Here is the caller graph for this function:

CK_RV NSC_Decrypt ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pEncryptedData,
CK_ULONG  ulEncryptedDataLen,
CK_BYTE_PTR  pData,
CK_ULONG_PTR  pulDataLen 
)

Definition at line 1051 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulDataLen;
    CK_RV crv;
    CK_RV crv2;
    SECStatus rv = SECSuccess;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_FALSE,&session);
    if (crv != CKR_OK) return crv;

    if (!pData) {
       *pulDataLen = ulEncryptedDataLen + context->blockSize;
       goto finish;
    }

    if (context->doPad && context->multi) {
       CK_ULONG finalLen;
       /* padding is fairly complicated, have the update and final 
        * code deal with it */
       sftk_FreeSession(session);
       crv = NSC_DecryptUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
                                                 pData, pulDataLen);
       if (crv != CKR_OK) 
           *pulDataLen = 0;
       maxoutlen -= *pulDataLen;
       pData     += *pulDataLen;
       finalLen = maxoutlen;
       crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
       if (crv2 == CKR_OK) 
           *pulDataLen += finalLen;
       return crv == CKR_OK ? crv2 : crv;
    }

    rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, 
                                   pEncryptedData, ulEncryptedDataLen);
    /* XXX need to do MUCH better error mapping than this. */
    crv = (rv == SECSuccess)  ? CKR_OK : CKR_DEVICE_ERROR;
    if (rv == SECSuccess && context->doPad) {
       CK_ULONG padding = pData[outlen - 1];
       if (padding > context->blockSize || !padding) {
           crv = CKR_ENCRYPTED_DATA_INVALID;
       } else
           outlen -= padding;
    }
    *pulDataLen = (CK_ULONG) outlen;
    sftk_SetContextByType(session, SFTK_DECRYPT, NULL);
    sftk_FreeContext(context);
finish:
    sftk_FreeSession(session);
    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DecryptDigestUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pEncryptedPart,
CK_ULONG  ulEncryptedPartLen,
CK_BYTE_PTR  pPart,
CK_ULONG_PTR  pulPartLen 
)

Definition at line 5799 of file pkcs11c.c.

{
    CK_RV crv;

    crv = NSC_DecryptUpdate(hSession,pEncryptedPart, ulEncryptedPartLen, 
                                                 pPart, pulPartLen);
    if (crv != CKR_OK) return crv;
    crv = NSC_DigestUpdate(hSession,pPart,*pulPartLen);

    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DecryptFinal ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pLastPart,
CK_ULONG_PTR  pulLastPartLen 
)

Definition at line 1000 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxout = *pulLastPartLen;
    CK_RV crv;
    SECStatus rv = SECSuccess;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session);
    if (crv != CKR_OK) return crv;

    *pulLastPartLen = 0;
    if (!pLastPart) {
       /* caller is checking the amount of remaining data */
       if (context->padDataLength > 0) {
           *pulLastPartLen = context->padDataLength;
       }
       rv = SECSuccess;
       goto finish;
    }

    if (context->doPad) {
       /* decrypt our saved buffer */
       if (context->padDataLength != 0) {
           /* this assumes that pLastPart is big enough to hold the *whole*
            * buffer!!! */
           rv = (*context->update)(context->cipherInfo, pLastPart, &outlen,
               maxout, context->padBuf, context->blockSize);
           if (rv == SECSuccess) {
              unsigned int padSize = 
                         (unsigned int) pLastPart[context->blockSize-1];
              if ((padSize > context->blockSize) || (padSize == 0)) {
                  rv = SECFailure;
              } else {
                  *pulLastPartLen = outlen - padSize;
              }
           }
       }
    }

    sftk_SetContextByType(session, SFTK_DECRYPT, NULL);
    sftk_FreeContext(context);
finish:
    sftk_FreeSession(session);
    return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 923 of file pkcs11c.c.

{
    return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT,
                                          SFTK_DECRYPT, PR_FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DecryptUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pEncryptedPart,
CK_ULONG  ulEncryptedPartLen,
CK_BYTE_PTR  pPart,
CK_ULONG_PTR  pulPartLen 
)

Definition at line 931 of file pkcs11c.c.

{
    SFTKSessionContext *context;
    unsigned int padoutlen = 0;
    unsigned int outlen;
    unsigned int maxout = *pulPartLen;
    CK_RV crv;
    SECStatus rv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL);
    if (crv != CKR_OK) return crv;

    /* this can only happen on an NSS programming error */
    PORT_Assert((context->padDataLength == 0) 
              || context->padDataLength == context->blockSize);


    if (!pPart) {
       if (context->doPad) {
           /* we can check the data length here because if we are padding,
            * then we must be using a block cipher. In the non-padding case
            * the error will be returned by the underlying decryption
            * function when do do the actual decrypt. We need to do the
            * check here to avoid returning a negative length to the caller.
            */
           if ((ulEncryptedPartLen == 0) ||
              (ulEncryptedPartLen % context->blockSize) != 0) {
              return CKR_ENCRYPTED_DATA_LEN_RANGE;
           }
           *pulPartLen = 
              ulEncryptedPartLen + context->padDataLength - context->blockSize;
           return CKR_OK;
       }
       /* for stream ciphers there is are no constraints on ulEncryptedPartLen.
        * for block ciphers, it must be a multiple of blockSize. The error is
        * detected when this function is called again do decrypt the output.
        */
       *pulPartLen = ulEncryptedPartLen;
       return CKR_OK;
    }

    if (context->doPad) {
       /* first decrypt our saved buffer */
       if (context->padDataLength != 0) {
           rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
               maxout, context->padBuf, context->blockSize);
           if (rv != SECSuccess)  return CKR_DEVICE_ERROR;
           pPart += padoutlen;
           maxout -= padoutlen;
       }
       /* now save the final block for the next decrypt or the final */
       PORT_Memcpy(context->padBuf,&pEncryptedPart[ulEncryptedPartLen -
                            context->blockSize], context->blockSize);
       context->padDataLength = context->blockSize;
       ulEncryptedPartLen -= context->padDataLength;
    }

    /* do it: NOTE: this assumes buf size in is >= buf size out! */
    rv = (*context->update)(context->cipherInfo,pPart, &outlen,
               maxout, pEncryptedPart, ulEncryptedPartLen);
    *pulPartLen = (CK_ULONG) (outlen + padoutlen);
    return (rv == SECSuccess)  ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DecryptVerifyUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pEncryptedData,
CK_ULONG  ulEncryptedDataLen,
CK_BYTE_PTR  pData,
CK_ULONG_PTR  pulDataLen 
)

Definition at line 5833 of file pkcs11c.c.

{
    CK_RV crv;

    crv = NSC_DecryptUpdate(hSession,pEncryptedData, ulEncryptedDataLen, 
                                                 pData, pulDataLen);
    if (crv != CKR_OK) return crv;
    crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);

    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DeriveKey ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_OBJECT_HANDLE  hBaseKey,
CK_ATTRIBUTE_PTR  pTemplate,
CK_ULONG  ulAttributeCount,
CK_OBJECT_HANDLE_PTR  phKey 
)

Definition at line 4663 of file pkcs11c.c.

{
    SFTKSession *   session;
    SFTKSlot    *   slot    = sftk_SlotFromSessionHandle(hSession);
    SFTKObject  *   key;
    SFTKObject  *   sourceKey;
    SFTKAttribute * att;
    SFTKAttribute * att2;
    unsigned char * buf;
    SHA1Context *   sha;
    MD5Context *    md5;
    MD2Context *    md2;
    CK_ULONG        macSize;
    CK_ULONG        tmpKeySize;
    CK_ULONG        IVSize;
    CK_ULONG        keySize = 0;
    CK_RV           crv     = CKR_OK;
    CK_BBOOL        cktrue  = CK_TRUE;
    CK_KEY_TYPE     keyType = CKK_GENERIC_SECRET;
    CK_OBJECT_CLASS classType      = CKO_SECRET_KEY;
    CK_KEY_DERIVATION_STRING_DATA *stringPtr;
    PRBool          isTLS = PR_FALSE;
    PRBool          isDH = PR_FALSE;
    SECStatus       rv;
    int             i;
    unsigned int    outLen;
    unsigned char   sha_out[SHA1_LENGTH];
    unsigned char   key_block[NUM_MIXERS * MD5_LENGTH];
    unsigned char   key_block2[MD5_LENGTH];
    PRBool          isFIPS;        

    /*
     * now lets create an object to hang the attributes off of
     */
    if (phKey) *phKey = CK_INVALID_HANDLE;

    key = sftk_NewObject(slot); /* fill in the handle later */
    if (key == NULL) {
       return CKR_HOST_MEMORY;
    }
    isFIPS = (slot->slotID == FIPS_SLOT_ID);

    /*
     * load the template values into the object
     */
    for (i=0; i < (int) ulAttributeCount; i++) {
       crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
       if (crv != CKR_OK) break;

       if (pTemplate[i].type == CKA_KEY_TYPE) {
           keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue;
       }
       if (pTemplate[i].type == CKA_VALUE_LEN) {
           keySize = *(CK_ULONG *)pTemplate[i].pValue;
       }
    }
    if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }

    if (keySize == 0) {
       keySize = sftk_MapKeySize(keyType);
    }

    /* Derive can only create SECRET KEY's currently... */
    classType = CKO_SECRET_KEY;
    crv = sftk_forceAttribute (key,CKA_CLASS,&classType,sizeof(classType));
    if (crv != CKR_OK) {
       sftk_FreeObject(key);
       return crv;
    }

    /* look up the base key we're deriving with */ 
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
       sftk_FreeObject(key);
        return CKR_SESSION_HANDLE_INVALID;
    }

    sourceKey = sftk_ObjectFromHandle(hBaseKey,session);
    sftk_FreeSession(session);
    if (sourceKey == NULL) {
       sftk_FreeObject(key);
        return CKR_KEY_HANDLE_INVALID;
    }

    /* get the value of the base key */
    att = sftk_FindAttribute(sourceKey,CKA_VALUE);
    if (att == NULL) {
       sftk_FreeObject(key);
       sftk_FreeObject(sourceKey);
        return CKR_KEY_HANDLE_INVALID;
    }

    switch (pMechanism->mechanism) {
    /*
     * generate the master secret 
     */
    case CKM_TLS_MASTER_KEY_DERIVE:
    case CKM_TLS_MASTER_KEY_DERIVE_DH:
       isTLS = PR_TRUE;
       /* fall thru */
    case CKM_SSL3_MASTER_KEY_DERIVE:
    case CKM_SSL3_MASTER_KEY_DERIVE_DH:
      {
       CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
       SSL3RSAPreMasterSecret *          rsa_pms;
       unsigned char                     crsrdata[SSL3_RANDOM_LENGTH * 2];

        if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) ||
            (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH))
              isDH = PR_TRUE;

       /* first do the consistancy checks */
       if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
       if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
                                   CKK_GENERIC_SECRET)) {
           if (att2) sftk_FreeAttribute(att2);
           crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
           break;
       }
       sftk_FreeAttribute(att2);
       if (keyType != CKK_GENERIC_SECRET) {
           crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
           break;
       }
       if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
           crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
           break;
       }

       /* finally do the key gen */
       ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
                                   pMechanism->pParameter;

       PORT_Memcpy(crsrdata, 
                   ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
       PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, 
                   ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);

       if (ssl3_master->pVersion) {
           SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
           rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
           /* don't leak more key material then necessary for SSL to work */
           if ((sessKey == NULL) || sessKey->wasDerived) {
              ssl3_master->pVersion->major = 0xff;
              ssl3_master->pVersion->minor = 0xff;
           } else {
              ssl3_master->pVersion->major = rsa_pms->client_version[0];
              ssl3_master->pVersion->minor = rsa_pms->client_version[1];
           }
       }
       if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH) {
          crv = CKR_MECHANISM_PARAM_INVALID;
          break;
       }
       if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) {
          crv = CKR_MECHANISM_PARAM_INVALID;
          break;
       }

        if (isTLS) {
           SECStatus status;
           SECItem crsr   = { siBuffer, NULL, 0 };
           SECItem master = { siBuffer, NULL, 0 };
           SECItem pms    = { siBuffer, NULL, 0 };

           crsr.data   = crsrdata;
           crsr.len    = sizeof crsrdata;
           master.data = key_block;
           master.len  = SSL3_MASTER_SECRET_LENGTH;
           pms.data    = (unsigned char*)att->attrib.pValue;
           pms.len     =                 att->attrib.ulValueLen;

           status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
           if (status != SECSuccess) {
              crv = CKR_FUNCTION_FAILED;
              break;
           }
       } else {
           /* now allocate the hash contexts */
           md5 = MD5_NewContext();
           if (md5 == NULL) { 
              crv = CKR_HOST_MEMORY;
              break;
           }
           sha = SHA1_NewContext();
           if (sha == NULL) { 
              PORT_Free(md5);
              crv = CKR_HOST_MEMORY;
              break;
           }
            for (i = 0; i < 3; i++) {
              SHA1_Begin(sha);
              SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
              SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, 
                       att->attrib.ulValueLen);
              SHA1_Update(sha, crsrdata, sizeof crsrdata);
              SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
              PORT_Assert(outLen == SHA1_LENGTH);

              MD5_Begin(md5);
              MD5_Update(md5, (const unsigned char*)att->attrib.pValue, 
                      att->attrib.ulValueLen);
              MD5_Update(md5, sha_out, outLen);
              MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
              PORT_Assert(outLen == MD5_LENGTH);
            }
           PORT_Free(md5);
           PORT_Free(sha);
       }

       /* store the results */
       crv = sftk_forceAttribute
                     (key,CKA_VALUE,key_block,SSL3_MASTER_SECRET_LENGTH);
       if (crv != CKR_OK) break;
       keyType = CKK_GENERIC_SECRET;
       crv = sftk_forceAttribute (key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
       if (isTLS) {
           /* TLS's master secret is used to "sign" finished msgs with PRF. */
           /* XXX This seems like a hack.   But SFTK_Derive only accepts 
            * one "operation" argument. */
           crv = sftk_forceAttribute(key,CKA_SIGN,  &cktrue,sizeof(CK_BBOOL));
           if (crv != CKR_OK) break;
           crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
           if (crv != CKR_OK) break;
           /* While we're here, we might as well force this, too. */
           crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
           if (crv != CKR_OK) break;
       }
       break;
      }

    case CKM_TLS_KEY_AND_MAC_DERIVE:
       isTLS = PR_TRUE;
       /* fall thru */
    case CKM_SSL3_KEY_AND_MAC_DERIVE:
      {
       CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
       CK_SSL3_KEY_MAT_OUT *   ssl3_keys_out;
       CK_ULONG                effKeySize;
       unsigned int            block_needed;
       unsigned char           srcrdata[SSL3_RANDOM_LENGTH * 2];
       unsigned char           crsrdata[SSL3_RANDOM_LENGTH * 2];

       crv = sftk_DeriveSensitiveCheck(sourceKey,key);
       if (crv != CKR_OK) break;

       if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH) {
           crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
           break;
       }
       att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
       if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
                                   CKK_GENERIC_SECRET)) {
           if (att2) sftk_FreeAttribute(att2);
           crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
           break;
       }
       sftk_FreeAttribute(att2);
       md5 = MD5_NewContext();
       if (md5 == NULL) { 
           crv = CKR_HOST_MEMORY;
           break;
       }
       sha = SHA1_NewContext();
       if (sha == NULL) { 
           PORT_Free(md5);
           crv = CKR_HOST_MEMORY;
           break;
       }
       ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter;

       PORT_Memcpy(srcrdata, 
                   ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
       PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, 
                  ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);

       PORT_Memcpy(crsrdata, 
                  ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
       PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, 
                  ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);

       /*
        * clear out our returned keys so we can recover on failure
        */
       ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
       ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE;
       ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE;
       ssl3_keys_out->hClientKey       = CK_INVALID_HANDLE;
       ssl3_keys_out->hServerKey       = CK_INVALID_HANDLE;

       /*
        * How much key material do we need?
        */
       macSize    = ssl3_keys->ulMacSizeInBits/8;
       effKeySize = ssl3_keys->ulKeySizeInBits/8;
       IVSize     = ssl3_keys->ulIVSizeInBits/8;
       if (keySize == 0) {
           effKeySize = keySize;
       }
       block_needed = 2 * (macSize + effKeySize + 
                           ((!ssl3_keys->bIsExport) * IVSize));
       PORT_Assert(block_needed <= sizeof key_block);
       if (block_needed > sizeof key_block)
           block_needed = sizeof key_block;

       /*
        * generate the key material: This looks amazingly similar to the
        * PMS code, and is clearly crying out for a function to provide it.
        */
       if (isTLS) {
           SECStatus     status;
           SECItem       srcr   = { siBuffer, NULL, 0 };
           SECItem       keyblk = { siBuffer, NULL, 0 };
           SECItem       master = { siBuffer, NULL, 0 }; 

           srcr.data   = srcrdata;
           srcr.len    = sizeof srcrdata;
           keyblk.data = key_block;
           keyblk.len  = block_needed;
           master.data = (unsigned char*)att->attrib.pValue;
           master.len  =                 att->attrib.ulValueLen;

           status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
                           isFIPS);
           if (status != SECSuccess) {
              goto key_and_mac_derive_fail;
           }
       } else {
           unsigned int block_bytes = 0;
           /* key_block = 
            *     MD5(master_secret + SHA('A' + master_secret + 
            *                      ServerHello.random + ClientHello.random)) +
            *     MD5(master_secret + SHA('BB' + master_secret + 
            *                      ServerHello.random + ClientHello.random)) +
            *     MD5(master_secret + SHA('CCC' + master_secret + 
            *                      ServerHello.random + ClientHello.random)) +
            *     [...];
            */
           for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) {
             SHA1_Begin(sha);
             SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
             SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, 
                       att->attrib.ulValueLen);
             SHA1_Update(sha, srcrdata, sizeof srcrdata);
             SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
             PORT_Assert(outLen == SHA1_LENGTH);
             MD5_Begin(md5);
             MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
                      att->attrib.ulValueLen);
             MD5_Update(md5, sha_out, outLen);
             MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
             PORT_Assert(outLen == MD5_LENGTH);
             block_bytes += outLen;
           }
       }

       /*
        * Put the key material where it goes.
        */
       i = 0;               /* now shows how much consumed */

       /* 
        * The key_block is partitioned as follows:
        * client_write_MAC_secret[CipherSpec.hash_size]
        */
       crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
                                    &ssl3_keys_out->hClientMacSecret);
       if (crv != CKR_OK)
           goto key_and_mac_derive_fail;

       i += macSize;

       /* 
        * server_write_MAC_secret[CipherSpec.hash_size]
        */
       crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
                                       &ssl3_keys_out->hServerMacSecret);
       if (crv != CKR_OK) {
           goto key_and_mac_derive_fail;
       }
       i += macSize;

       if (keySize) {
           if (!ssl3_keys->bIsExport) {
              /* 
              ** Generate Domestic write keys and IVs.
              ** client_write_key[CipherSpec.key_material]
              */
              crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
                                   keySize, &ssl3_keys_out->hClientKey);
              if (crv != CKR_OK) {
                  goto key_and_mac_derive_fail;
              }
              i += keySize;

              /* 
              ** server_write_key[CipherSpec.key_material]
              */
              crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
                                   keySize, &ssl3_keys_out->hServerKey);
              if (crv != CKR_OK) {
                  goto key_and_mac_derive_fail;
              }
              i += keySize;

              /* 
              ** client_write_IV[CipherSpec.IV_size]
              */
              if (IVSize > 0) {
                  PORT_Memcpy(ssl3_keys_out->pIVClient, 
                              &key_block[i], IVSize);
                  i += IVSize;
              }

              /* 
              ** server_write_IV[CipherSpec.IV_size]
              */
              if (IVSize > 0) {
                  PORT_Memcpy(ssl3_keys_out->pIVServer, 
                              &key_block[i], IVSize);
                  i += IVSize;
              }
              PORT_Assert(i <= sizeof key_block);

           } else if (!isTLS) {

              /*
              ** Generate SSL3 Export write keys and IVs.
              ** client_write_key[CipherSpec.key_material]
              ** final_client_write_key = MD5(client_write_key +
              **                   ClientHello.random + ServerHello.random);
              */
              MD5_Begin(md5);
              MD5_Update(md5, &key_block[i], effKeySize);
              MD5_Update(md5, crsrdata, sizeof crsrdata);
              MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
              i += effKeySize;
              crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
                                   keySize,&ssl3_keys_out->hClientKey);
              if (crv != CKR_OK) {
                  goto key_and_mac_derive_fail;
              }

              /*
              ** server_write_key[CipherSpec.key_material]
              ** final_server_write_key = MD5(server_write_key +
              **                    ServerHello.random + ClientHello.random);
              */
              MD5_Begin(md5);
              MD5_Update(md5, &key_block[i], effKeySize);
              MD5_Update(md5, srcrdata, sizeof srcrdata);
              MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
              i += effKeySize;
              crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
                                    keySize,&ssl3_keys_out->hServerKey);
              if (crv != CKR_OK) {
                  goto key_and_mac_derive_fail;
              }

              /*
              ** client_write_IV = 
              **     MD5(ClientHello.random + ServerHello.random);
              */
              MD5_Begin(md5);
              MD5_Update(md5, crsrdata, sizeof crsrdata);
              MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
              PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize);

              /*
              ** server_write_IV = 
              **     MD5(ServerHello.random + ClientHello.random);
              */
              MD5_Begin(md5);
              MD5_Update(md5, srcrdata, sizeof srcrdata);
              MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
              PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize);

           } else {

              /*
              ** Generate TLS Export write keys and IVs.
              */
              SECStatus     status;
              SECItem       secret = { siBuffer, NULL, 0 };
              SECItem       crsr   = { siBuffer, NULL, 0 };
              SECItem       keyblk = { siBuffer, NULL, 0 };

              /*
              ** client_write_key[CipherSpec.key_material]
              ** final_client_write_key = PRF(client_write_key, 
              **                              "client write key",
              **                              client_random + server_random);
              */
              secret.data = &key_block[i];
              secret.len  = effKeySize;
              i          += effKeySize;
              crsr.data   = crsrdata;
              crsr.len    = sizeof crsrdata;
              keyblk.data = key_block2;
              keyblk.len  = sizeof key_block2;
              status = TLS_PRF(&secret, "client write key", &crsr, &keyblk,
                              isFIPS);
              if (status != SECSuccess) {
                  goto key_and_mac_derive_fail;
              }
              crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2, 
                                   keySize, &ssl3_keys_out->hClientKey);
              if (crv != CKR_OK) {
                  goto key_and_mac_derive_fail;
              }

              /*
              ** server_write_key[CipherSpec.key_material]
              ** final_server_write_key = PRF(server_write_key,
              **                              "server write key",
              **                              client_random + server_random);
              */
              secret.data = &key_block[i];
              secret.len  = effKeySize;
              i          += effKeySize;
              keyblk.data = key_block2;
              keyblk.len  = sizeof key_block2;
              status = TLS_PRF(&secret, "server write key", &crsr, &keyblk,
                              isFIPS);
              if (status != SECSuccess) {
                  goto key_and_mac_derive_fail;
              }
              crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2, 
                                   keySize, &ssl3_keys_out->hServerKey);
              if (crv != CKR_OK) {
                  goto key_and_mac_derive_fail;
              }

              /*
              ** iv_block = PRF("", "IV block", 
              **                    client_random + server_random);
              ** client_write_IV[SecurityParameters.IV_size]
              ** server_write_IV[SecurityParameters.IV_size]
              */
              if (IVSize) {
                  secret.data = NULL;
                  secret.len  = 0;
                  keyblk.data = &key_block[i];
                  keyblk.len  = 2 * IVSize;
                  status = TLS_PRF(&secret, "IV block", &crsr, &keyblk,
                                  isFIPS);
                  if (status != SECSuccess) {
                     goto key_and_mac_derive_fail;
                  }
                  PORT_Memcpy(ssl3_keys_out->pIVClient, keyblk.data, IVSize);
                  PORT_Memcpy(ssl3_keys_out->pIVServer, keyblk.data + IVSize,
                                IVSize);
              }
           }
       }

       crv = CKR_OK;

       if (0) {
key_and_mac_derive_fail:
           if (crv == CKR_OK)
              crv = CKR_FUNCTION_FAILED;
           sftk_freeSSLKeys(hSession, ssl3_keys_out);
       }
       MD5_DestroyContext(md5, PR_TRUE);
       SHA1_DestroyContext(sha, PR_TRUE);
       sftk_FreeObject(key);
       key = NULL;
       break;
      }

    case CKM_CONCATENATE_BASE_AND_KEY:
      {
       SFTKObject *newKey;

       crv = sftk_DeriveSensitiveCheck(sourceKey,key);
       if (crv != CKR_OK) break;

       session = sftk_SessionFromHandle(hSession);
       if (session == NULL) {
            crv = CKR_SESSION_HANDLE_INVALID;
           break;
       }

       newKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *)
                                   pMechanism->pParameter,session);
       sftk_FreeSession(session);
       if ( newKey == NULL) {
            crv = CKR_KEY_HANDLE_INVALID;
           break;
       }

       if (sftk_isTrue(newKey,CKA_SENSITIVE)) {
           crv = sftk_forceAttribute(newKey,CKA_SENSITIVE,&cktrue,
                                                 sizeof(CK_BBOOL));
           if (crv != CKR_OK) {
              sftk_FreeObject(newKey);
              break;
           }
       }

       att2 = sftk_FindAttribute(newKey,CKA_VALUE);
       if (att2 == NULL) {
           sftk_FreeObject(newKey);
            crv = CKR_KEY_HANDLE_INVALID;
           break;
       }
       tmpKeySize = att->attrib.ulValueLen+att2->attrib.ulValueLen;
       if (keySize == 0) keySize = tmpKeySize;
       if (keySize > tmpKeySize) {
           sftk_FreeObject(newKey);
           sftk_FreeAttribute(att2);
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
       }
       buf = (unsigned char*)PORT_Alloc(tmpKeySize);
       if (buf == NULL) {
           sftk_FreeAttribute(att2);
           sftk_FreeObject(newKey);
           crv = CKR_HOST_MEMORY;  
           break;
       }

       PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
       PORT_Memcpy(buf+att->attrib.ulValueLen,
                            att2->attrib.pValue,att2->attrib.ulValueLen);

       crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
       PORT_ZFree(buf,tmpKeySize);
       sftk_FreeAttribute(att2);
       sftk_FreeObject(newKey);
       break;
      }

    case CKM_CONCATENATE_BASE_AND_DATA:
       crv = sftk_DeriveSensitiveCheck(sourceKey,key);
       if (crv != CKR_OK) break;

       stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter;
       tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
       if (keySize == 0) keySize = tmpKeySize;
       if (keySize > tmpKeySize) {
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
       }
       buf = (unsigned char*)PORT_Alloc(tmpKeySize);
       if (buf == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }

       PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
       PORT_Memcpy(buf+att->attrib.ulValueLen,stringPtr->pData,
                                                 stringPtr->ulLen);

       crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
       PORT_ZFree(buf,tmpKeySize);
       break;
    case CKM_CONCATENATE_DATA_AND_BASE:
       crv = sftk_DeriveSensitiveCheck(sourceKey,key);
       if (crv != CKR_OK) break;

       stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
       tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
       if (keySize == 0) keySize = tmpKeySize;
       if (keySize > tmpKeySize) {
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
       }
       buf = (unsigned char*)PORT_Alloc(tmpKeySize);
       if (buf == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }

       PORT_Memcpy(buf,stringPtr->pData,stringPtr->ulLen);
       PORT_Memcpy(buf+stringPtr->ulLen,att->attrib.pValue,
                                                 att->attrib.ulValueLen);

       crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
       PORT_ZFree(buf,tmpKeySize);
       break;
    case CKM_XOR_BASE_AND_DATA:
       crv = sftk_DeriveSensitiveCheck(sourceKey,key);
       if (crv != CKR_OK) break;

       stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
       tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen);
       if (keySize == 0) keySize = tmpKeySize;
       if (keySize > tmpKeySize) {
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
       }
       buf = (unsigned char*)PORT_Alloc(keySize);
       if (buf == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }

       
       PORT_Memcpy(buf,att->attrib.pValue,keySize);
       for (i=0; i < (int)keySize; i++) {
           buf[i] ^= stringPtr->pData[i];
       }

       crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
       PORT_ZFree(buf,keySize);
       break;

    case CKM_EXTRACT_KEY_FROM_KEY:
      {
       /* the following assumes 8 bits per byte */
       CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
       CK_ULONG shift   = extract & 0x7;      /* extract mod 8 the fast way */
       CK_ULONG offset  = extract >> 3;       /* extract div 8 the fast way */

       crv = sftk_DeriveSensitiveCheck(sourceKey,key);
       if (crv != CKR_OK) break;

       if (keySize == 0)  {
           crv = CKR_TEMPLATE_INCOMPLETE;
           break;
       }
       /* make sure we have enough bits in the original key */
       if (att->attrib.ulValueLen < 
                     (offset + keySize + ((shift != 0)? 1 :0)) ) {
           crv = CKR_MECHANISM_PARAM_INVALID;
           break;
       }
       buf = (unsigned char*)PORT_Alloc(keySize);
       if (buf == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }

       /* copy the bits we need into the new key */     
       for (i=0; i < (int)keySize; i++) {
           unsigned char *value =
                      ((unsigned char *)att->attrib.pValue)+offset+i;
           if (shift) {
               buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift));
           } else {
              buf[i] = value[0];
           }
       }

       crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
       PORT_ZFree(buf,keySize);
       break;
      }
    case CKM_MD2_KEY_DERIVATION:
       if (keySize == 0) keySize = MD2_LENGTH;
       if (keySize > MD2_LENGTH) {
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
       }
       /* now allocate the hash contexts */
       md2 = MD2_NewContext();
       if (md2 == NULL) { 
           crv = CKR_HOST_MEMORY;
           break;
       }
       MD2_Begin(md2);
       MD2_Update(md2,(const unsigned char*)att->attrib.pValue,
                 att->attrib.ulValueLen);
       MD2_End(md2,key_block,&outLen,MD2_LENGTH);
       MD2_DestroyContext(md2, PR_TRUE);

       crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize);
       break;
    case CKM_MD5_KEY_DERIVATION:
       if (keySize == 0) keySize = MD5_LENGTH;
       if (keySize > MD5_LENGTH) {
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
       }
       /* now allocate the hash contexts */
       md5 = MD5_NewContext();
       if (md5 == NULL) { 
           crv = CKR_HOST_MEMORY;
           break;
       }
       MD5_Begin(md5);
       MD5_Update(md5,(const unsigned char*)att->attrib.pValue,
                 att->attrib.ulValueLen);
       MD5_End(md5,key_block,&outLen,MD5_LENGTH);
       MD5_DestroyContext(md5, PR_TRUE);

       crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize);
       break;
     case CKM_SHA1_KEY_DERIVATION:
       if (keySize == 0) keySize = SHA1_LENGTH;
       if (keySize > SHA1_LENGTH) {
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
       }
       /* now allocate the hash contexts */
       sha = SHA1_NewContext();
       if (sha == NULL) { 
           crv = CKR_HOST_MEMORY;
           break;
       }
       SHA1_Begin(sha);
       SHA1_Update(sha,(const unsigned char*)att->attrib.pValue,
                  att->attrib.ulValueLen);
       SHA1_End(sha,key_block,&outLen,SHA1_LENGTH);
       SHA1_DestroyContext(sha, PR_TRUE);

       crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize);
       break;

    case CKM_DH_PKCS_DERIVE:
      {
       SECItem  derived,  dhPublic;
       SECItem  dhPrime,  dhValue;
       /* sourceKey - values for the local existing low key */
       /* get prime and value attributes */
       crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME); 
       if (crv != SECSuccess) break;
       crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE); 
       if (crv != SECSuccess) {
           PORT_Free(dhPrime.data);
           break;
       }

       dhPublic.data = pMechanism->pParameter;
       dhPublic.len  = pMechanism->ulParameterLen;

       /* calculate private value - oct */
       rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize); 

       PORT_Free(dhPrime.data);
       PORT_Free(dhValue.data);
     
       if (rv == SECSuccess) {
           sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
           PORT_ZFree(derived.data, derived.len);
       } else
           crv = CKR_HOST_MEMORY;
           
       break;
      }

#ifdef NSS_ENABLE_ECC
    case CKM_ECDH1_DERIVE:
    case CKM_ECDH1_COFACTOR_DERIVE:
      {
       SECItem  ecScalar, ecPoint;
       SECItem  tmp;
       PRBool   withCofactor = PR_FALSE;
       unsigned char secret_hash[20];
       unsigned char *secret;
       unsigned char *keyData = NULL;
       int secretlen;
       CK_ECDH1_DERIVE_PARAMS *mechParams;
       NSSLOWKEYPrivateKey *privKey;

       /* Check mechanism parameters */
       mechParams = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter;
       if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) ||
           ((mechParams->kdf == CKD_NULL) &&
              ((mechParams->ulSharedDataLen != 0) || 
                  (mechParams->pSharedData != NULL)))) {
           crv = CKR_MECHANISM_PARAM_INVALID;
           break;
       }

       privKey = sftk_GetPrivKey(sourceKey, CKK_EC, &crv);
       if (privKey == NULL) {
           break;
       }

       /* Now we are working with a non-NULL private key */
       SECITEM_CopyItem(NULL, &ecScalar, &privKey->u.ec.privateValue);

       ecPoint.data = mechParams->pPublicData;
       ecPoint.len  = mechParams->ulPublicDataLen;

       if (pMechanism->mechanism == CKM_ECDH1_COFACTOR_DERIVE) {
           withCofactor = PR_TRUE;
       } else {
           /* When not using cofactor derivation, one should
            * validate the public key to avoid small subgroup
            * attacks.
            */
           if (EC_ValidatePublicKey(&privKey->u.ec.ecParams, &ecPoint) 
              != SECSuccess) {
              crv = CKR_ARGUMENTS_BAD;
              PORT_Free(ecScalar.data);
              if (privKey != sourceKey->objectInfo)
                  nsslowkey_DestroyPrivateKey(privKey);
              break;
           }
       }

       rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar,
                        withCofactor, &tmp); 
       PORT_Free(ecScalar.data);
       if (privKey != sourceKey->objectInfo)
          nsslowkey_DestroyPrivateKey(privKey);

       if (rv != SECSuccess) {
           crv = CKR_DEVICE_ERROR;
           break;
       }

       /*
        * tmp is the raw data created by ECDH_Derive,
        * secret and secretlen are the values we will eventually pass as our
        * generated key.
        */
       secret = tmp.data;
       secretlen = tmp.len;

       /*
        * apply the kdf function.
        */
       if (mechParams->kdf == CKD_SHA1_KDF) {
           /* Compute SHA1 hash */
           PORT_Memset(secret_hash, 0, 20);
           rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len);
           if (rv != SECSuccess) {
              PORT_ZFree(tmp.data, tmp.len);
              crv = CKR_HOST_MEMORY;
              break;
           } 
           secret = secret_hash;
           secretlen = 20;
       }

       /*
        * if keySize is supplied, then we are generating a key of a specific 
        * length. This is done by taking the least significant 'keySize' 
        * bytes from the unsigned value calculated by ECDH. Note: this may 
        * mean padding temp with extra leading zeros from what ECDH_Derive 
        * already returned (which itself may contain leading zeros).
        */
       if (keySize) {
           if (secretlen < keySize) {
               keyData = PORT_ZAlloc(keySize);
              if (!keyData) {
                  PORT_ZFree(tmp.data, tmp.len);
                  crv = CKR_HOST_MEMORY;
                  break;
              }
              PORT_Memcpy(&keyData[keySize-secretlen],secret,secretlen);
              secret = keyData;
           } else {
              secret += (secretlen - keySize);
           }
           secretlen = keySize;
       }

       sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
       PORT_ZFree(tmp.data, tmp.len);
       if (keyData) {
           PORT_ZFree(keyData, keySize);
       }
       PORT_Memset(secret_hash, 0, 20);
           
       break;
      }
#endif /* NSS_ENABLE_ECC */

    default:
       crv = CKR_MECHANISM_INVALID;
    }
    sftk_FreeAttribute(att);
    sftk_FreeObject(sourceKey);
    if (crv != CKR_OK) { 
       if (key) sftk_FreeObject(key);
       return crv;
    }

    /* link the key object into the list */
    if (key) {
       SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
       PORT_Assert(sessKey);
       /* get the session */
       sessKey->wasDerived = PR_TRUE;
       session = sftk_SessionFromHandle(hSession);
       if (session == NULL) {
           sftk_FreeObject(key);
           return CKR_HOST_MEMORY;
       }

       crv = sftk_handleObject(key,session);
       sftk_FreeSession(session);
       *phKey = key->handle;
       sftk_FreeObject(key);
    }
    return crv;
}

Here is the caller graph for this function:

Definition at line 184 of file pkcs11c.c.

{
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    SFTKSession *session;
    SFTKObject *object;
    SFTKFreeStatus status;

    /*
     * This whole block just makes sure we really can destroy the
     * requested object.
     */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
        return CKR_SESSION_HANDLE_INVALID;
    }

    object = sftk_ObjectFromHandle(hObject,session);
    if (object == NULL) {
       sftk_FreeSession(session);
       return CKR_OBJECT_HANDLE_INVALID;
    }

    /* don't destroy a private object if we aren't logged in */
    if ((!slot->isLoggedIn) && (slot->needLogin) &&
                            (sftk_isTrue(object,CKA_PRIVATE))) {
       sftk_FreeSession(session);
       sftk_FreeObject(object);
       return CKR_USER_NOT_LOGGED_IN;
    }

    /* don't destroy a token object if we aren't in a rw session */

    if (((session->info.flags & CKF_RW_SESSION) == 0) &&
                            (sftk_isTrue(object,CKA_TOKEN))) {
       sftk_FreeSession(session);
       sftk_FreeObject(object);
       return CKR_SESSION_READ_ONLY;
    }

    sftk_DeleteObject(session,object);

    sftk_FreeSession(session);

    /*
     * get some indication if the object is destroyed. Note: this is not
     * 100%. Someone may have an object reference outstanding (though that
     * should not be the case by here. Also note that the object is "half"
     * destroyed. Our internal representation is destroyed, but it may still
     * be in the data base.
     */
    status = sftk_FreeObject(object);

    return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_Digest ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pData,
CK_ULONG  ulDataLen,
CK_BYTE_PTR  pDigest,
CK_ULONG_PTR  pulDigestLen 
)

Definition at line 1175 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int digestLen;
    unsigned int maxout = *pulDigestLen;
    CK_RV crv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_FALSE,&session);
    if (crv != CKR_OK) return crv;

    if (pDigest == NULL) {
       *pulDigestLen = context->maxLen;
       goto finish;
    }

    /* do it: */
    (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen);
    /*  NOTE: this assumes buf size is bigenough for the algorithm */
    (*context->end)(context->cipherInfo, pDigest, &digestLen,maxout);
    *pulDigestLen = digestLen;

    sftk_SetContextByType(session, SFTK_HASH, NULL);
    sftk_FreeContext(context);
finish:
    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DigestEncryptUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pPart,
CK_ULONG  ulPartLen,
CK_BYTE_PTR  pEncryptedPart,
CK_ULONG_PTR  pulEncryptedPartLen 
)

Definition at line 5782 of file pkcs11c.c.

{
    CK_RV crv;

    crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart, 
                                                pulEncryptedPartLen);
    if (crv != CKR_OK) return crv;
    crv = NSC_DigestUpdate(hSession,pPart,ulPartLen);

    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DigestFinal ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pDigest,
CK_ULONG_PTR  pulDigestLen 
)

Definition at line 1225 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int maxout = *pulDigestLen;
    unsigned int digestLen;
    CK_RV crv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
    if (crv != CKR_OK) return crv;

    if (pDigest != NULL) {
        (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
        *pulDigestLen = digestLen;
       sftk_SetContextByType(session, SFTK_HASH, NULL);
       sftk_FreeContext(context);
    } else {
       *pulDigestLen = context->maxLen;
    }

    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DigestInit ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism 
)

Definition at line 1116 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    CK_RV crv = CKR_OK;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) 
       return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session,&context,SFTK_HASH,NULL,0,NULL, 0, 0);
    if (crv != CKR_OK) {
       sftk_FreeSession(session);
       return crv;
    }


#define INIT_MECH(mech,mmm) \
    case mech: { \
       mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \
       context->cipherInfo    = (void *)mmm ## _ctx; \
       context->cipherInfoLen = mmm ## _FlattenSize(mmm ## _ctx); \
       context->currentMech   = mech; \
       context->hashUpdate    = (SFTKHash)    mmm ## _Update; \
       context->end           = (SFTKEnd)     mmm ## _End; \
       context->destroy       = (SFTKDestroy) mmm ## _DestroyContext; \
       context->maxLen        = mmm ## _LENGTH; \
        if (mmm ## _ctx) \
           mmm ## _Begin(mmm ## _ctx); \
       else  \
           crv = CKR_HOST_MEMORY; \
       break; \
    }

    switch(pMechanism->mechanism) {
    INIT_MECH(CKM_MD2,    MD2)
    INIT_MECH(CKM_MD5,    MD5)
    INIT_MECH(CKM_SHA_1,  SHA1)
    INIT_MECH(CKM_SHA256, SHA256)
    INIT_MECH(CKM_SHA384, SHA384)
    INIT_MECH(CKM_SHA512, SHA512)

    default:
       crv = CKR_MECHANISM_INVALID;
       break;
    }

    if (crv != CKR_OK) {
        sftk_FreeContext(context);
       sftk_FreeSession(session);
       return crv;
    }
    sftk_SetContextByType(session, SFTK_HASH, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5850 of file pkcs11c.c.

{
    SFTKSession *session = NULL;
    SFTKObject *key = NULL;
    SFTKAttribute *att;
    CK_RV crv;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) return CKR_SESSION_HANDLE_INVALID;

    key = sftk_ObjectFromHandle(hKey,session);
    sftk_FreeSession(session);
    if (key == NULL)  return CKR_KEY_HANDLE_INVALID;

    /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */

    /* make sure it's a valid  key for this operation */
    if (key->objclass != CKO_SECRET_KEY) {
       sftk_FreeObject(key);
       return CKR_KEY_TYPE_INCONSISTENT;
    }
    /* get the key value */
    att = sftk_FindAttribute(key,CKA_VALUE);
    sftk_FreeObject(key);
    if (!att) {
        return CKR_KEY_HANDLE_INVALID;        
    }
    crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue,
                        att->attrib.ulValueLen);
    sftk_FreeAttribute(att);
    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_DigestUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pPart,
CK_ULONG  ulPartLen 
)

Definition at line 1209 of file pkcs11c.c.

{
    SFTKSessionContext *context;
    CK_RV crv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_TRUE,NULL);
    if (crv != CKR_OK) return crv;
    /* do it: */
    (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus nsc_DSA_Sign_Stub ( void ctx,
void sigBuf,
unsigned int sigLen,
unsigned int  maxSigLen,
void dataBuf,
unsigned int  dataLen 
) [static]

Definition at line 1656 of file pkcs11c.c.

{
    SECItem signature, digest;
    SECStatus rv;
    NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;

    signature.data = (unsigned char *)sigBuf;
    signature.len = maxSigLen;
    digest.data = (unsigned char *)dataBuf;
    digest.len = dataLen;
    rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
       sftk_fatalError = PR_TRUE;
    }
    *sigLen = signature.len;
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus nsc_DSA_Verify_Stub ( void ctx,
void sigBuf,
unsigned int  sigLen,
void dataBuf,
unsigned int  dataLen 
) [static]

Definition at line 1642 of file pkcs11c.c.

{
    SECItem signature, digest;
    NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;

    signature.data = (unsigned char *)sigBuf;
    signature.len = sigLen;
    digest.data = (unsigned char *)dataBuf;
    digest.len = dataLen;
    return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_Encrypt ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pData,
CK_ULONG  ulDataLen,
CK_BYTE_PTR  pEncryptedData,
CK_ULONG_PTR  pulEncryptedDataLen 
)

Definition at line 837 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulEncryptedDataLen;
    CK_RV crv;
    CK_RV crv2;
    SECStatus rv = SECSuccess;
    SECItem   pText;

    pText.type = siBuffer;
    pText.data = pData;
    pText.len  = ulDataLen;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,&session);
    if (crv != CKR_OK) return crv;

    if (!pEncryptedData) {
       *pulEncryptedDataLen = context->multi ? 
              ulDataLen + 2 * context->blockSize : context->maxLen;
       goto finish;
    }

    if (context->doPad) {
       if (context->multi) {
           CK_ULONG finalLen;
           /* padding is fairly complicated, have the update and final 
            * code deal with it */
           sftk_FreeSession(session);
           crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData, 
                                   pulEncryptedDataLen);
           if (crv != CKR_OK) 
              *pulEncryptedDataLen = 0;
           maxoutlen      -= *pulEncryptedDataLen;
           pEncryptedData += *pulEncryptedDataLen;
           finalLen = maxoutlen;
           crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
           if (crv2 == CKR_OK) 
              *pulEncryptedDataLen += finalLen;
           return crv == CKR_OK ? crv2 : crv;
       }
       /* doPad without multi means that padding must be done on the first
       ** and only update.  There will be no final.
       */
       PORT_Assert(context->blockSize > 1);
       if (context->blockSize > 1) {
           CK_ULONG remainder = ulDataLen % context->blockSize;
           CK_ULONG padding   = context->blockSize - remainder;
           pText.len += padding;
           pText.data = PORT_ZAlloc(pText.len);
           if (pText.data) {
              memcpy(pText.data, pData, ulDataLen);
              memset(pText.data + ulDataLen, padding, padding);
           } else {
              crv = CKR_HOST_MEMORY;
              goto fail;
           }
       }
    }

    /* do it: NOTE: this assumes buf size is big enough. */
    rv = (*context->update)(context->cipherInfo, pEncryptedData, 
                         &outlen, maxoutlen, pText.data, pText.len);
    crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
    *pulEncryptedDataLen = (CK_ULONG) outlen;
    if (pText.data != pData)
       PORT_ZFree(pText.data, pText.len);
fail:
    sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
    sftk_FreeContext(context);
finish:
    sftk_FreeSession(session);

    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_EncryptFinal ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pLastEncryptedPart,
CK_ULONG_PTR  pulLastEncryptedPartLen 
)

Definition at line 789 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen,i;
    unsigned int maxout = *pulLastEncryptedPartLen;
    CK_RV crv;
    SECStatus rv = SECSuccess;
    PRBool contextFinished = PR_TRUE;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,&session);
    if (crv != CKR_OK) return crv;

    *pulLastEncryptedPartLen = 0;
    if (!pLastEncryptedPart) {
       /* caller is checking the amount of remaining data */
       if (context->blockSize > 0 && context->doPad) {
           *pulLastEncryptedPartLen = context->blockSize;
           contextFinished = PR_FALSE; /* still have padding to go */
       }
       goto finish;
    }

    /* do padding */
    if (context->doPad) {
       unsigned char  padbyte = (unsigned char) 
                            (context->blockSize - context->padDataLength); 
       /* fill out rest of pad buffer with pad magic*/
       for (i=context->padDataLength; i < context->blockSize; i++) {
           context->padBuf[i] = padbyte;
       }
       rv = (*context->update)(context->cipherInfo,pLastEncryptedPart, 
                     &outlen, maxout, context->padBuf, context->blockSize);
       if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen;
    }

finish:
    if (contextFinished) {
       sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
       sftk_FreeContext(context);
    }
    sftk_FreeSession(session);
    return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 704 of file pkcs11c.c.

{
    return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT, 
                                          SFTK_ENCRYPT, PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_EncryptUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pPart,
CK_ULONG  ulPartLen,
CK_BYTE_PTR  pEncryptedPart,
CK_ULONG_PTR  pulEncryptedPartLen 
)

Definition at line 712 of file pkcs11c.c.

{
    SFTKSessionContext *context;
    unsigned int outlen,i;
    unsigned int padoutlen = 0;
    unsigned int maxout = *pulEncryptedPartLen;
    CK_RV crv;
    SECStatus rv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL);
    if (crv != CKR_OK) return crv;

    if (!pEncryptedPart) {
       if (context->doPad) {
           CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength;
           CK_ULONG blocksToSend = totalDataAvailable/context->blockSize;

           *pulEncryptedPartLen = blocksToSend * context->blockSize;
           return CKR_OK;
       }
       *pulEncryptedPartLen = ulPartLen;
       return CKR_OK;
    }

    /* do padding */
    if (context->doPad) {
       /* deal with previous buffered data */
       if (context->padDataLength != 0) {
           /* fill in the padded to a full block size */
           for (i=context->padDataLength; 
                     (ulPartLen != 0) && i < context->blockSize; i++) {
              context->padBuf[i] = *pPart++;
              ulPartLen--;
              context->padDataLength++;
           }

           /* not enough data to encrypt yet? then return */
           if (context->padDataLength != context->blockSize) {
              *pulEncryptedPartLen = 0;
              return CKR_OK;
           }
           /* encrypt the current padded data */
           rv = (*context->update)(context->cipherInfo, pEncryptedPart, 
              &padoutlen, context->blockSize, context->padBuf,
                                                 context->blockSize);
           if (rv != SECSuccess) return CKR_DEVICE_ERROR;
           pEncryptedPart += padoutlen;
           maxout -= padoutlen;
       }
       /* save the residual */
       context->padDataLength = ulPartLen % context->blockSize;
       if (context->padDataLength) {
           PORT_Memcpy(context->padBuf,
                     &pPart[ulPartLen-context->padDataLength],
                                                 context->padDataLength);
           ulPartLen -= context->padDataLength;
       }
       /* if we've exhausted our new buffer, we're done */
       if (ulPartLen == 0) {
           *pulEncryptedPartLen = padoutlen;
           return CKR_OK;
       }
    }


    /* do it: NOTE: this assumes buf size in is >= buf size out! */
    rv = (*context->update)(context->cipherInfo,pEncryptedPart, 
                                   &outlen, maxout, pPart, ulPartLen);
    *pulEncryptedPartLen = (CK_ULONG) (outlen + padoutlen);
    return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_GenerateKey ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_ATTRIBUTE_PTR  pTemplate,
CK_ULONG  ulCount,
CK_OBJECT_HANDLE_PTR  phKey 
)

Definition at line 2835 of file pkcs11c.c.

{
    SFTKObject *key;
    SFTKSession *session;
    PRBool checkWeak = PR_FALSE;
    CK_ULONG key_length = 0;
    CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE;
    CK_OBJECT_CLASS objclass = CKO_SECRET_KEY;
    CK_RV crv = CKR_OK;
    CK_BBOOL cktrue = CK_TRUE;
    int i;
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    char buf[MAX_KEY_LEN];
    enum {nsc_pbe, nsc_ssl, nsc_bulk, nsc_param} key_gen_type;
    NSSPKCS5PBEParameter *pbe_param;
    SSL3RSAPreMasterSecret *rsa_pms;
    CK_VERSION *version;
    /* in very old versions of NSS, there were implementation errors with key 
     * generation methods.  We want to beable to read these, but not 
     * produce them any more.  The affected algorithm was 3DES.
     */
    PRBool faultyPBE3DES = PR_FALSE;


    /*
     * now lets create an object to hang the attributes off of
     */
    key = sftk_NewObject(slot); /* fill in the handle later */
    if (key == NULL) {
       return CKR_HOST_MEMORY;
    }

    /*
     * load the template values into the object
     */
    for (i=0; i < (int) ulCount; i++) {
       if (pTemplate[i].type == CKA_VALUE_LEN) {
           key_length = *(CK_ULONG *)pTemplate[i].pValue;
           continue;
       }

       crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
       if (crv != CKR_OK) break;
    }
    if (crv != CKR_OK) {
       sftk_FreeObject(key);
       return crv;
    }

    /* make sure we don't have any class, key_type, or value fields */
    sftk_DeleteAttributeType(key,CKA_CLASS);
    sftk_DeleteAttributeType(key,CKA_KEY_TYPE);
    sftk_DeleteAttributeType(key,CKA_VALUE);

    /* Now Set up the parameters to generate the key (based on mechanism) */
    key_gen_type = nsc_bulk; /* bulk key by default */
    switch (pMechanism->mechanism) {
    case CKM_CDMF_KEY_GEN:
    case CKM_DES_KEY_GEN:
    case CKM_DES2_KEY_GEN:
    case CKM_DES3_KEY_GEN:
       checkWeak = PR_TRUE;
    case CKM_RC2_KEY_GEN:
    case CKM_RC4_KEY_GEN:
    case CKM_GENERIC_SECRET_KEY_GEN:
    case CKM_AES_KEY_GEN:
#if NSS_SOFTOKEN_DOES_RC5
    case CKM_RC5_KEY_GEN:
#endif
       crv = nsc_SetupBulkKeyGen(pMechanism->mechanism,&key_type,&key_length);
       break;
    case CKM_SSL3_PRE_MASTER_KEY_GEN:
       key_type = CKK_GENERIC_SECRET;
       key_length = 48;
       key_gen_type = nsc_ssl;
       break;
    case CKM_PBA_SHA1_WITH_SHA1_HMAC:
    case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
    case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
    case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
       key_gen_type = nsc_pbe;
       key_type = CKK_GENERIC_SECRET;
       crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
       break;
    case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
       faultyPBE3DES = PR_TRUE;
    case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
    case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
    case CKM_PBE_SHA1_DES3_EDE_CBC:
    case CKM_PBE_SHA1_DES2_EDE_CBC:
    case CKM_PBE_SHA1_RC2_128_CBC:
    case CKM_PBE_SHA1_RC2_40_CBC:
    case CKM_PBE_SHA1_RC4_128:
    case CKM_PBE_SHA1_RC4_40:
    case CKM_PBE_MD5_DES_CBC:
    case CKM_PBE_MD2_DES_CBC:
       key_gen_type = nsc_pbe;
       crv = nsc_SetupPBEKeyGen(pMechanism,&pbe_param, &key_type);
       break;
    case CKM_DSA_PARAMETER_GEN:
       key_gen_type = nsc_param;
       key_type = CKK_DSA;
       objclass = CKO_KG_PARAMETERS;
       crv = CKR_OK;
       break;
    default:
       crv = CKR_MECHANISM_INVALID;
       break;
    }

    /* make sure we aren't going to overflow the buffer */
    if (sizeof(buf) < key_length) {
       /* someone is getting pretty optimistic about how big their key can
        * be... */
        crv = CKR_TEMPLATE_INCONSISTENT;
    }

    if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }

    /* if there was no error,
     * key_type *MUST* be set in the switch statement above */
    PORT_Assert( key_type != CKK_INVALID_KEY_TYPE );

    /*
     * now to the actual key gen.
     */
    switch (key_gen_type) {
    case nsc_pbe:
       crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length,
                            faultyPBE3DES);
       nsspkcs5_DestroyPBEParameter(pbe_param);
       break;
    case nsc_ssl:
       rsa_pms = (SSL3RSAPreMasterSecret *)buf;
       version = (CK_VERSION *)pMechanism->pParameter;
       rsa_pms->client_version[0] = version->major;
        rsa_pms->client_version[1] = version->minor;
        crv = 
           NSC_GenerateRandom(0,&rsa_pms->random[0], sizeof(rsa_pms->random));
       break;
    case nsc_bulk:
       /* get the key, check for weak keys and repeat if found */
       do {
            crv = NSC_GenerateRandom(0, (unsigned char *)buf, key_length);
       } while (crv == CKR_OK && checkWeak && 
                     sftk_IsWeakKey((unsigned char *)buf,key_type));
       break;
    case nsc_param:
       /* generate parameters */
       *buf = 0;
       crv = nsc_parameter_gen(key_type,key);
       break;
    }

    if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }

    /* Add the class, key_type, and value */
    crv = sftk_AddAttributeType(key,CKA_CLASS,&objclass,sizeof(CK_OBJECT_CLASS));
    if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
    crv = sftk_AddAttributeType(key,CKA_KEY_TYPE,&key_type,sizeof(CK_KEY_TYPE));
    if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
    if (key_length != 0) {
       crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length);
       if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
    }

    /* get the session */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
       sftk_FreeObject(key);
        return CKR_SESSION_HANDLE_INVALID;
    }

    /*
     * handle the base object stuff
     */
    crv = sftk_handleObject(key,session);
    sftk_FreeSession(session);
    if (sftk_isTrue(key,CKA_SENSITIVE)) {
       sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
    }
    if (!sftk_isTrue(key,CKA_EXTRACTABLE)) {
       sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
    }

    *phKey = key->handle;
    sftk_FreeObject(key);
    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_GenerateKeyPair ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_ATTRIBUTE_PTR  pPublicKeyTemplate,
CK_ULONG  ulPublicKeyAttributeCount,
CK_ATTRIBUTE_PTR  pPrivateKeyTemplate,
CK_ULONG  ulPrivateKeyAttributeCount,
CK_OBJECT_HANDLE_PTR  phPublicKey,
CK_OBJECT_HANDLE_PTR  phPrivateKey 
)

Definition at line 3315 of file pkcs11c.c.

{
    SFTKObject *     publicKey,*privateKey;
    SFTKSession *    session;
    CK_KEY_TYPE      key_type;
    CK_RV            crv    = CKR_OK;
    CK_BBOOL         cktrue        = CK_TRUE;
    SECStatus               rv;
    CK_OBJECT_CLASS  pubClass = CKO_PUBLIC_KEY;
    CK_OBJECT_CLASS  privClass = CKO_PRIVATE_KEY;
    int              i;
    SFTKSlot *              slot   = sftk_SlotFromSessionHandle(hSession);
    unsigned int bitSize;

    /* RSA */
    int              public_modulus_bits = 0;
    SECItem          pubExp;
    RSAPrivateKey *  rsaPriv;

    /* DSA */
    PQGParams               pqgParam;
    DHParams                dhParam;
    DSAPrivateKey *  dsaPriv;

    /* Diffie Hellman */
    int              private_value_bits = 0;
    DHPrivateKey *   dhPriv;

#ifdef NSS_ENABLE_ECC
    /* Elliptic Curve Cryptography */
    SECItem          ecEncodedParams;  /* DER Encoded parameters */
    ECPrivateKey *   ecPriv;
    ECParams *          ecParams;
#endif /* NSS_ENABLE_ECC */

    /*
     * now lets create an object to hang the attributes off of
     */
    publicKey = sftk_NewObject(slot); /* fill in the handle later */
    if (publicKey == NULL) {
       return CKR_HOST_MEMORY;
    }

    /*
     * load the template values into the publicKey
     */
    for (i=0; i < (int) ulPublicKeyAttributeCount; i++) {
       if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS) {
           public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue;
           continue;
       }

       crv = sftk_AddAttributeType(publicKey,
                                sftk_attr_expand(&pPublicKeyTemplate[i]));
       if (crv != CKR_OK) break;
    }

    if (crv != CKR_OK) {
       sftk_FreeObject(publicKey);
       return CKR_HOST_MEMORY;
    }

    privateKey = sftk_NewObject(slot); /* fill in the handle later */
    if (privateKey == NULL) {
       sftk_FreeObject(publicKey);
       return CKR_HOST_MEMORY;
    }
    /*
     * now load the private key template
     */
    for (i=0; i < (int) ulPrivateKeyAttributeCount; i++) {
       if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) {
           private_value_bits = *(CK_ULONG *)pPrivateKeyTemplate[i].pValue;
           continue;
       }

       crv = sftk_AddAttributeType(privateKey,
                                sftk_attr_expand(&pPrivateKeyTemplate[i]));
       if (crv != CKR_OK) break;
    }

    if (crv != CKR_OK) {
       sftk_FreeObject(publicKey);
       sftk_FreeObject(privateKey);
       return CKR_HOST_MEMORY;
    }
    sftk_DeleteAttributeType(privateKey,CKA_CLASS);
    sftk_DeleteAttributeType(privateKey,CKA_KEY_TYPE);
    sftk_DeleteAttributeType(privateKey,CKA_VALUE);
    sftk_DeleteAttributeType(publicKey,CKA_CLASS);
    sftk_DeleteAttributeType(publicKey,CKA_KEY_TYPE);
    sftk_DeleteAttributeType(publicKey,CKA_VALUE);

    /* Now Set up the parameters to generate the key (based on mechanism) */
    switch (pMechanism->mechanism) {
    case CKM_RSA_PKCS_KEY_PAIR_GEN:
       /* format the keys */
       sftk_DeleteAttributeType(publicKey,CKA_MODULUS);
       sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
       sftk_DeleteAttributeType(privateKey,CKA_MODULUS);
       sftk_DeleteAttributeType(privateKey,CKA_PRIVATE_EXPONENT);
       sftk_DeleteAttributeType(privateKey,CKA_PUBLIC_EXPONENT);
       sftk_DeleteAttributeType(privateKey,CKA_PRIME_1);
       sftk_DeleteAttributeType(privateKey,CKA_PRIME_2);
       sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_1);
       sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_2);
       sftk_DeleteAttributeType(privateKey,CKA_COEFFICIENT);
       key_type = CKK_RSA;
       if (public_modulus_bits == 0) {
           crv = CKR_TEMPLATE_INCOMPLETE;
           break;
       }
       if (public_modulus_bits < RSA_MIN_MODULUS_BITS) {
           crv = CKR_ATTRIBUTE_VALUE_INVALID;
           break;
       }
       if (public_modulus_bits % 2 != 0) {
           crv = CKR_ATTRIBUTE_VALUE_INVALID;
           break;
       }

       /* extract the exponent */
       crv=sftk_Attribute2SSecItem(NULL,&pubExp,publicKey,CKA_PUBLIC_EXPONENT);
       if (crv != CKR_OK) break;
        bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len);
       if (bitSize < 2) {
           crv = CKR_ATTRIBUTE_VALUE_INVALID;
           break;
       }
        crv = sftk_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
                                              sftk_item_expand(&pubExp));
       if (crv != CKR_OK) {
           PORT_Free(pubExp.data);
           break;
       }

       rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
       PORT_Free(pubExp.data);
       if (rsaPriv == NULL) {
           if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
              sftk_fatalError = PR_TRUE;
           }
           crv = CKR_DEVICE_ERROR;
           break;
       }
        /* now fill in the RSA dependent paramenters in the public key */
        crv = sftk_AddAttributeType(publicKey,CKA_MODULUS,
                        sftk_item_expand(&rsaPriv->modulus));
       if (crv != CKR_OK) goto kpg_done;
        /* now fill in the RSA dependent paramenters in the private key */
        crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
                        sftk_item_expand(&rsaPriv->modulus));
       if (crv != CKR_OK) goto kpg_done;
        crv = sftk_AddAttributeType(privateKey,CKA_MODULUS,
                        sftk_item_expand(&rsaPriv->modulus));
       if (crv != CKR_OK) goto kpg_done;
        crv = sftk_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT,
                        sftk_item_expand(&rsaPriv->privateExponent));
       if (crv != CKR_OK) goto kpg_done;
        crv = sftk_AddAttributeType(privateKey,CKA_PRIME_1,
                        sftk_item_expand(&rsaPriv->prime1));
       if (crv != CKR_OK) goto kpg_done;
        crv = sftk_AddAttributeType(privateKey,CKA_PRIME_2,
                        sftk_item_expand(&rsaPriv->prime2));
       if (crv != CKR_OK) goto kpg_done;
        crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_1,
                        sftk_item_expand(&rsaPriv->exponent1));
       if (crv != CKR_OK) goto kpg_done;
        crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_2,
                        sftk_item_expand(&rsaPriv->exponent2));
       if (crv != CKR_OK) goto kpg_done;
        crv = sftk_AddAttributeType(privateKey,CKA_COEFFICIENT,
                        sftk_item_expand(&rsaPriv->coefficient));
kpg_done:
       /* Should zeroize the contents first, since this func doesn't. */
       PORT_FreeArena(rsaPriv->arena, PR_TRUE);
       break;
    case CKM_DSA_KEY_PAIR_GEN:
       sftk_DeleteAttributeType(publicKey,CKA_VALUE);
       sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
       sftk_DeleteAttributeType(privateKey,CKA_PRIME);
       sftk_DeleteAttributeType(privateKey,CKA_SUBPRIME);
       sftk_DeleteAttributeType(privateKey,CKA_BASE);
       key_type = CKK_DSA;

       /* extract the necessary paramters and copy them to the private key */
       crv=sftk_Attribute2SSecItem(NULL,&pqgParam.prime,publicKey,CKA_PRIME);
       if (crv != CKR_OK) break;
       crv=sftk_Attribute2SSecItem(NULL,&pqgParam.subPrime,publicKey,
                                   CKA_SUBPRIME);
       if (crv != CKR_OK) {
           PORT_Free(pqgParam.prime.data);
           break;
       }
       crv=sftk_Attribute2SSecItem(NULL,&pqgParam.base,publicKey,CKA_BASE);
       if (crv != CKR_OK) {
           PORT_Free(pqgParam.prime.data);
           PORT_Free(pqgParam.subPrime.data);
           break;
       }
        crv = sftk_AddAttributeType(privateKey,CKA_PRIME,
                                sftk_item_expand(&pqgParam.prime));
       if (crv != CKR_OK) {
           PORT_Free(pqgParam.prime.data);
           PORT_Free(pqgParam.subPrime.data);
           PORT_Free(pqgParam.base.data);
           break;
       }
        crv = sftk_AddAttributeType(privateKey,CKA_SUBPRIME,
                                sftk_item_expand(&pqgParam.subPrime));
       if (crv != CKR_OK) {
           PORT_Free(pqgParam.prime.data);
           PORT_Free(pqgParam.subPrime.data);
           PORT_Free(pqgParam.base.data);
           break;
       }
        crv = sftk_AddAttributeType(privateKey,CKA_BASE,
                                sftk_item_expand(&pqgParam.base));
       if (crv != CKR_OK) {
           PORT_Free(pqgParam.prime.data);
           PORT_Free(pqgParam.subPrime.data);
           PORT_Free(pqgParam.base.data);
           break;
       }

        bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data, 
                                                 pqgParam.subPrime.len);
        if (bitSize != DSA_Q_BITS)  {
           crv = CKR_TEMPLATE_INCOMPLETE;
           PORT_Free(pqgParam.prime.data);
           PORT_Free(pqgParam.subPrime.data);
           PORT_Free(pqgParam.base.data);
           break;
       }
        bitSize = sftk_GetLengthInBits(pqgParam.prime.data,pqgParam.prime.len);
        if ((bitSize <  DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) {
           crv = CKR_TEMPLATE_INCOMPLETE;
           PORT_Free(pqgParam.prime.data);
           PORT_Free(pqgParam.subPrime.data);
           PORT_Free(pqgParam.base.data);
           break;
       }
        bitSize = sftk_GetLengthInBits(pqgParam.base.data,pqgParam.base.len);
        if ((bitSize <  1) || (bitSize > DSA_MAX_P_BITS)) {
           crv = CKR_TEMPLATE_INCOMPLETE;
           PORT_Free(pqgParam.prime.data);
           PORT_Free(pqgParam.subPrime.data);
           PORT_Free(pqgParam.base.data);
           break;
       }
           
       /* Generate the key */
       rv = DSA_NewKey(&pqgParam, &dsaPriv);

       PORT_Free(pqgParam.prime.data);
       PORT_Free(pqgParam.subPrime.data);
       PORT_Free(pqgParam.base.data);

       if (rv != SECSuccess) {
           if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
              sftk_fatalError = PR_TRUE;
           }
           crv = CKR_DEVICE_ERROR;
           break;
       }

       /* store the generated key into the attributes */
        crv = sftk_AddAttributeType(publicKey,CKA_VALUE,
                        sftk_item_expand(&dsaPriv->publicValue));
       if (crv != CKR_OK) goto dsagn_done;

        /* now fill in the RSA dependent paramenters in the private key */
        crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
                        sftk_item_expand(&dsaPriv->publicValue));
       if (crv != CKR_OK) goto dsagn_done;
        crv = sftk_AddAttributeType(privateKey,CKA_VALUE,
                        sftk_item_expand(&dsaPriv->privateValue));

dsagn_done:
       /* should zeroize, since this function doesn't. */
       PORT_FreeArena(dsaPriv->params.arena, PR_TRUE);
       break;

    case CKM_DH_PKCS_KEY_PAIR_GEN:
       sftk_DeleteAttributeType(privateKey,CKA_PRIME);
       sftk_DeleteAttributeType(privateKey,CKA_BASE);
       sftk_DeleteAttributeType(privateKey,CKA_VALUE);
       sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
       key_type = CKK_DH;

       /* extract the necessary parameters and copy them to private keys */
        crv = sftk_Attribute2SSecItem(NULL, &dhParam.prime, publicKey, 
                                  CKA_PRIME);
       if (crv != CKR_OK) break;
       crv = sftk_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE);
       if (crv != CKR_OK) {
           PORT_Free(dhParam.prime.data);
           break;
       }
       crv = sftk_AddAttributeType(privateKey, CKA_PRIME, 
                                sftk_item_expand(&dhParam.prime));
       if (crv != CKR_OK) {
           PORT_Free(dhParam.prime.data);
           PORT_Free(dhParam.base.data);
           break;
       }
       crv = sftk_AddAttributeType(privateKey, CKA_BASE, 
                                sftk_item_expand(&dhParam.base));
       if (crv != CKR_OK) {
           PORT_Free(dhParam.prime.data);
           PORT_Free(dhParam.base.data);
           break;
       }
        bitSize = sftk_GetLengthInBits(dhParam.prime.data,dhParam.prime.len);
        if ((bitSize <  DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) {
           crv = CKR_TEMPLATE_INCOMPLETE;
           PORT_Free(dhParam.prime.data);
           PORT_Free(dhParam.base.data);
           break;
       }
        bitSize = sftk_GetLengthInBits(dhParam.base.data,dhParam.base.len);
        if ((bitSize <  1) || (bitSize > DH_MAX_P_BITS)) {
           crv = CKR_TEMPLATE_INCOMPLETE;
           PORT_Free(dhParam.prime.data);
           PORT_Free(dhParam.base.data);
           break;
       }

       rv = DH_NewKey(&dhParam, &dhPriv);
       PORT_Free(dhParam.prime.data);
       PORT_Free(dhParam.base.data);
       if (rv != SECSuccess) { 
           if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
              sftk_fatalError = PR_TRUE;
           }
           crv = CKR_DEVICE_ERROR;
           break;
       }

       crv=sftk_AddAttributeType(publicKey, CKA_VALUE, 
                            sftk_item_expand(&dhPriv->publicValue));
       if (crv != CKR_OK) goto dhgn_done;

        crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
                        sftk_item_expand(&dhPriv->publicValue));
       if (crv != CKR_OK) goto dhgn_done;

       crv=sftk_AddAttributeType(privateKey, CKA_VALUE, 
                           sftk_item_expand(&dhPriv->privateValue));

dhgn_done:
       /* should zeroize, since this function doesn't. */
       PORT_FreeArena(dhPriv->arena, PR_TRUE);
       break;

#ifdef NSS_ENABLE_ECC
    case CKM_EC_KEY_PAIR_GEN:
       sftk_DeleteAttributeType(privateKey,CKA_EC_PARAMS);
       sftk_DeleteAttributeType(privateKey,CKA_VALUE);
       sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
       key_type = CKK_EC;

       /* extract the necessary parameters and copy them to private keys */
       crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey, 
                                  CKA_EC_PARAMS);
       if (crv != CKR_OK) break;

       crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS, 
                                sftk_item_expand(&ecEncodedParams));
       if (crv != CKR_OK) {
         PORT_Free(ecEncodedParams.data);
         break;
       }

       /* Decode ec params before calling EC_NewKey */
       rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
       PORT_Free(ecEncodedParams.data);
       if (rv != SECSuccess) {
           crv = CKR_DEVICE_ERROR;
           break;
       }
       rv = EC_NewKey(ecParams, &ecPriv);
       PORT_FreeArena(ecParams->arena, PR_TRUE);
       if (rv != SECSuccess) { 
           if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
              sftk_fatalError = PR_TRUE;
           }
           crv = CKR_DEVICE_ERROR;
           break;
       }

       crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, 
                            sftk_item_expand(&ecPriv->publicValue));
       if (crv != CKR_OK) goto ecgn_done;

       crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 
                           sftk_item_expand(&ecPriv->privateValue));
       if (crv != CKR_OK) goto ecgn_done;

        crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
                        sftk_item_expand(&ecPriv->publicValue));
ecgn_done:
       /* should zeroize, since this function doesn't. */
       PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
       break;
#endif /* NSS_ENABLE_ECC */

    default:
       crv = CKR_MECHANISM_INVALID;
    }

    if (crv != CKR_OK) {
       sftk_FreeObject(privateKey);
       sftk_FreeObject(publicKey);
       return crv;
    }


    /* Add the class, key_type The loop lets us check errors blow out
     *  on errors and clean up at the bottom */
    session = NULL; /* make pedtantic happy... session cannot leave the*/
                  /* loop below NULL unless an error is set... */
    do {
       crv = sftk_AddAttributeType(privateKey,CKA_CLASS,&privClass,
                                          sizeof(CK_OBJECT_CLASS));
        if (crv != CKR_OK) break;
       crv = sftk_AddAttributeType(publicKey,CKA_CLASS,&pubClass,
                                          sizeof(CK_OBJECT_CLASS));
        if (crv != CKR_OK) break;
       crv = sftk_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type,
                                          sizeof(CK_KEY_TYPE));
        if (crv != CKR_OK) break;
       crv = sftk_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type,
                                          sizeof(CK_KEY_TYPE));
        if (crv != CKR_OK) break;
        session = sftk_SessionFromHandle(hSession);
        if (session == NULL) crv = CKR_SESSION_HANDLE_INVALID;
    } while (0);

    if (crv != CKR_OK) {
        sftk_FreeObject(privateKey);
        sftk_FreeObject(publicKey);
        return crv;
    }

    /*
     * handle the base object cleanup for the public Key
     */
    crv = sftk_handleObject(privateKey,session);
    if (crv != CKR_OK) {
        sftk_FreeSession(session);
       sftk_FreeObject(privateKey);
       sftk_FreeObject(publicKey);
       return crv;
    }

    /*
     * handle the base object cleanup for the private Key
     * If we have any problems, we destroy the public Key we've
     * created and linked.
     */
    crv = sftk_handleObject(publicKey,session);
    sftk_FreeSession(session);
    if (crv != CKR_OK) {
       sftk_FreeObject(publicKey);
       NSC_DestroyObject(hSession,privateKey->handle);
       sftk_FreeObject(privateKey);
       return crv;
    }
    if (sftk_isTrue(privateKey,CKA_SENSITIVE)) {
       sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
                                          &cktrue,sizeof(CK_BBOOL));
    }
    if (sftk_isTrue(publicKey,CKA_SENSITIVE)) {
       sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
                                          &cktrue,sizeof(CK_BBOOL));
    }
    if (!sftk_isTrue(privateKey,CKA_EXTRACTABLE)) {
       sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
                                          &cktrue,sizeof(CK_BBOOL));
    }
    if (!sftk_isTrue(publicKey,CKA_EXTRACTABLE)) {
       sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
                                          &cktrue,sizeof(CK_BBOOL));
    }

    /* Perform FIPS 140-2 pairwise consistency check. */
    crv = sftk_PairwiseConsistencyCheck(hSession,
                                   publicKey, privateKey, key_type);
    if (crv != CKR_OK) {
       NSC_DestroyObject(hSession,publicKey->handle);
       sftk_FreeObject(publicKey);
       NSC_DestroyObject(hSession,privateKey->handle);
       sftk_FreeObject(privateKey);
       if (sftk_audit_enabled) {
           char msg[128];
           PR_snprintf(msg,sizeof msg,
                     "C_GenerateKeyPair(hSession=0x%08lX, "
                     "pMechanism->mechanism=0x%08lX)=0x%08lX "
                     "self-test: pair-wise consistency test failed",
                     (PRUint32)hSession,(PRUint32)pMechanism->mechanism,
                     (PRUint32)crv);
           sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
       }
       return crv;
    }

    *phPrivateKey = privateKey->handle;
    *phPublicKey = publicKey->handle;
    sftk_FreeObject(publicKey);
    sftk_FreeObject(privateKey);

    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_GenerateRandom ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pRandomData,
CK_ULONG  ulRandomLen 
)

Definition at line 2536 of file pkcs11c.c.

{
    SECStatus rv;

    rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen);
    return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5667 of file pkcs11c.c.

Here is the caller graph for this function:

CK_RV NSC_GetOperationState ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pOperationState,
CK_ULONG_PTR  pulOperationStateLen 
)

Definition at line 5683 of file pkcs11c.c.

{
    SFTKSessionContext *context;
    SFTKSession *session;
    CK_RV crv;
    CK_ULONG pOSLen = *pulOperationStateLen;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
    if (crv != CKR_OK) return crv;

    *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE)
                            + sizeof(SFTKContextType);
    if (pOperationState == NULL) {
        sftk_FreeSession(session);
       return CKR_OK;
    } else {
       if (pOSLen < *pulOperationStateLen) {
           return CKR_BUFFER_TOO_SMALL;
       }
    }
    PORT_Memcpy(pOperationState,&context->type,sizeof(SFTKContextType));
    pOperationState += sizeof(SFTKContextType);
    PORT_Memcpy(pOperationState,&context->currentMech,
                                          sizeof(CK_MECHANISM_TYPE));
    pOperationState += sizeof(CK_MECHANISM_TYPE);
    PORT_Memcpy(pOperationState,context->cipherInfo,context->cipherInfoLen);
    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV nsc_parameter_gen ( CK_KEY_TYPE  key_type,
SFTKObject *  key 
) [static]

Definition at line 2588 of file pkcs11c.c.

{
    SFTKAttribute *attribute;
    CK_ULONG counter;
    unsigned int seedBits = 0;
    unsigned int primeBits;
    unsigned int j;
    CK_RV crv = CKR_OK;
    PQGParams *params = NULL;
    PQGVerify *vfy = NULL;
    SECStatus rv;

    attribute = sftk_FindAttribute(key, CKA_PRIME_BITS);
    if (attribute == NULL) {
       return CKR_TEMPLATE_INCOMPLETE;
    }
    primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
    sftk_FreeAttribute(attribute);
    j = PQG_PBITS_TO_INDEX(primeBits);
    if (j == (unsigned int)-1) {
       return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS);
    if (attribute != NULL) {
       seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
       sftk_FreeAttribute(attribute);
    }

    sftk_DeleteAttributeType(key,CKA_PRIME_BITS);
    sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS);

    if (seedBits == 0) {
       rv = PQG_ParamGen(j, &params, &vfy);
    } else {
       rv = PQG_ParamGenSeedLen(j,seedBits/8, &params, &vfy);
    }

    if (rv != SECSuccess) {
       if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
           sftk_fatalError = PR_TRUE;
       }
       return CKR_DEVICE_ERROR;
    }
    crv = sftk_AddAttributeType(key,CKA_PRIME,
                             params->prime.data, params->prime.len);
    if (crv != CKR_OK) goto loser;
    crv = sftk_AddAttributeType(key,CKA_SUBPRIME,
                             params->subPrime.data, params->subPrime.len);
    if (crv != CKR_OK) goto loser;
    crv = sftk_AddAttributeType(key,CKA_BASE,
                             params->base.data, params->base.len);
    if (crv != CKR_OK) goto loser;
    counter = vfy->counter;
    crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_COUNTER,
                             &counter, sizeof(counter));
    crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_SEED,
                             vfy->seed.data, vfy->seed.len);
    if (crv != CKR_OK) goto loser;
    crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_H,
                             vfy->h.data, vfy->h.len);
    if (crv != CKR_OK) goto loser;

loser:
    if (params) {
       PQG_DestroyParams(params);
    }
    if (vfy) {
       PQG_DestroyVerify(vfy);
    }
    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV nsc_pbe_key_gen ( NSSPKCS5PBEParameter *  pkcs5_pbe,
CK_MECHANISM_PTR  pMechanism,
char *  buf,
CK_ULONG key_length,
PRBool  faulty3DES 
) [static]

Definition at line 2555 of file pkcs11c.c.

{
    SECItem *pbe_key = NULL, iv, pwitem;
    CK_PBE_PARAMS *pbe_params = NULL;

    *key_length = 0;
    iv.data = NULL; iv.len = 0;

    pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;

    pwitem.data = (unsigned char *)pbe_params->pPassword;
    pwitem.len = (unsigned int)pbe_params->ulPasswordLen;
    pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES);
    if (pbe_key == NULL) {
       return CKR_HOST_MEMORY;
    }

    PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
    *key_length = pbe_key->len;
    SECITEM_ZfreeItem(pbe_key, PR_TRUE);
    pbe_key = NULL;

    if (iv.data) {
        if (pbe_params->pInitVector != NULL) {
           PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
        }
        PORT_Free(iv.data);
    }

    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_SeedRandom ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pSeed,
CK_ULONG  ulSeedLen 
)

Definition at line 2526 of file pkcs11c.c.

{
    SECStatus rv;

    rv = RNG_RandomUpdate(pSeed, ulSeedLen);
    return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_SetOperationState ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pOperationState,
CK_ULONG  ulOperationStateLen,
CK_OBJECT_HANDLE  hEncryptionKey,
CK_OBJECT_HANDLE  hAuthenticationKey 
)

Definition at line 5723 of file pkcs11c.c.

{
    SFTKSessionContext *context;
    SFTKSession *session;
    SFTKContextType type;
    CK_MECHANISM mech;
    CK_RV crv = CKR_OK;

    while (ulOperationStateLen != 0) {
       /* get what type of state we're dealing with... */
       PORT_Memcpy(&type,pOperationState, sizeof(SFTKContextType));

       /* fix up session contexts based on type */
       session = sftk_SessionFromHandle(hSession);
       if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
       context = sftk_ReturnContextByType(session, type);
       sftk_SetContextByType(session, type, NULL);
       if (context) { 
            sftk_FreeContext(context);
       }
       pOperationState += sizeof(SFTKContextType);
       sftk_Decrement(ulOperationStateLen,sizeof(SFTKContextType));


       /* get the mechanism structure */
       PORT_Memcpy(&mech.mechanism,pOperationState,sizeof(CK_MECHANISM_TYPE));
       pOperationState += sizeof(CK_MECHANISM_TYPE);
       sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE));
       /* should be filled in... but not necessary for hash */
       mech.pParameter = NULL;
       mech.ulParameterLen = 0;
       switch (type) {
       case SFTK_HASH:
           crv = NSC_DigestInit(hSession,&mech);
           if (crv != CKR_OK) break;
           crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, 
                                                        NULL);
           if (crv != CKR_OK) break;
           PORT_Memcpy(context->cipherInfo,pOperationState,
                                          context->cipherInfoLen);
           pOperationState += context->cipherInfoLen;
           sftk_Decrement(ulOperationStateLen,context->cipherInfoLen);
           break;
       default:
           /* do sign/encrypt/decrypt later */
           crv = CKR_SAVED_STATE_INVALID;
         }
         sftk_FreeSession(session);
        if (crv != CKR_OK) break;
    }
    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV nsc_SetupBulkKeyGen ( CK_MECHANISM_TYPE  mechanism,
CK_KEY_TYPE key_type,
CK_ULONG key_length 
) [static]

Definition at line 2668 of file pkcs11c.c.

{
    CK_RV crv = CKR_OK;

    switch (mechanism) {
    case CKM_RC2_KEY_GEN:
       *key_type = CKK_RC2;
       if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
       break;
#if NSS_SOFTOKEN_DOES_RC5
    case CKM_RC5_KEY_GEN:
       *key_type = CKK_RC5;
       if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
       break;
#endif
    case CKM_RC4_KEY_GEN:
       *key_type = CKK_RC4;
       if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
       break;
    case CKM_GENERIC_SECRET_KEY_GEN:
       *key_type = CKK_GENERIC_SECRET;
       if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
       break;
    case CKM_CDMF_KEY_GEN:
       *key_type = CKK_CDMF;
       *key_length = 8;
       break;
    case CKM_DES_KEY_GEN:
       *key_type = CKK_DES;
       *key_length = 8;
       break;
    case CKM_DES2_KEY_GEN:
       *key_type = CKK_DES2;
       *key_length = 16;
       break;
    case CKM_DES3_KEY_GEN:
       *key_type = CKK_DES3;
       *key_length = 24;
       break;
    case CKM_AES_KEY_GEN:
       *key_type = CKK_AES;
       if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
       break;
    default:
       PORT_Assert(0);
       crv = CKR_MECHANISM_INVALID;
       break;
    }

    return crv;
}

Here is the caller graph for this function:

CK_RV nsc_SetupHMACKeyGen ( CK_MECHANISM_PTR  pMechanism,
NSSPKCS5PBEParameter **  pbe 
)

Definition at line 2722 of file pkcs11c.c.

{
    SECItem  salt;
    CK_PBE_PARAMS *pbe_params = NULL;
    NSSPKCS5PBEParameter *params;
    PRArenaPool *arena = NULL;
    SECStatus rv;

    *pbe = NULL;

    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (arena == NULL) {
       return CKR_HOST_MEMORY;
    }

    params = (NSSPKCS5PBEParameter *) PORT_ArenaZAlloc(arena,
                            sizeof(NSSPKCS5PBEParameter));
    if (params == NULL) {
       PORT_FreeArena(arena,PR_TRUE);
       return CKR_HOST_MEMORY;
    }

    params->poolp = arena;
    params->ivLen = 0;
    params->pbeType = NSSPKCS5_PKCS12_V2;
    params->hashType = HASH_AlgSHA1;
    params->encAlg = SEC_OID_SHA1; /* any invalid value */
    params->is2KeyDES = PR_FALSE;
    params->keyID = pbeBitGenIntegrityKey;
    pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
    params->iter = pbe_params->ulIteration;

    salt.data = (unsigned char *)pbe_params->pSalt;
    salt.len = (unsigned int)pbe_params->ulSaltLen;
    rv = SECITEM_CopyItem(arena,&params->salt,&salt);
    if (rv != SECSuccess) {
       PORT_FreeArena(arena,PR_TRUE);
       return CKR_HOST_MEMORY;
    }
    switch (pMechanism->mechanism) {
    case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
    case CKM_PBA_SHA1_WITH_SHA1_HMAC:
       params->hashType = HASH_AlgSHA1; 
       params->keyLen = 20;
       break;
    case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
       params->hashType = HASH_AlgMD5; 
       params->keyLen = 16;
       break;
    case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
       params->hashType = HASH_AlgMD2; 
       params->keyLen = 16;
       break;
    default:
       PORT_FreeArena(arena,PR_TRUE);
       return CKR_MECHANISM_INVALID;
    }
    *pbe = params;
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV nsc_SetupPBEKeyGen ( CK_MECHANISM_PTR  pMechanism,
NSSPKCS5PBEParameter **  pbe,
CK_KEY_TYPE key_type 
) [static]

Definition at line 2784 of file pkcs11c.c.

{
    CK_RV crv = CKR_OK;
    SECOidData *oid;
    CK_PBE_PARAMS *pbe_params;
    NSSPKCS5PBEParameter *params;
    SECItem salt;

    *pbe = NULL;

    oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
    if (oid == NULL) {
       return CKR_MECHANISM_INVALID;
    }

    pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
    salt.data = (unsigned char *)pbe_params->pSalt;
    salt.len = (unsigned int)pbe_params->ulSaltLen;

    params=nsspkcs5_NewParam(oid->offset, &salt, pbe_params->ulIteration);
    if (params == NULL) {
       return CKR_MECHANISM_INVALID;
    }


    switch (params->encAlg) {
    case SEC_OID_DES_CBC:
       *key_type = CKK_DES;
       break;
    case SEC_OID_DES_EDE3_CBC:
       *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3;
       break;
    case SEC_OID_RC2_CBC:
       *key_type = CKK_RC2;
       break;
    case SEC_OID_RC4:
       *key_type = CKK_RC4;
       break;
    default:
       crv = CKR_MECHANISM_INVALID;
       nsspkcs5_DestroyPBEParameter(params);
       break;
    }
    if (crv == CKR_OK) {
       *pbe = params;
    }
    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_Sign ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pData,
CK_ULONG  ulDataLen,
CK_BYTE_PTR  pSignature,
CK_ULONG_PTR  pulSignatureLen 
)

Definition at line 2043 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulSignatureLen;
    CK_RV crv,crv2;
    SECStatus rv = SECSuccess;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_FALSE,&session);
    if (crv != CKR_OK) return crv;

    if (!pSignature) {
       *pulSignatureLen = context->maxLen;
       goto finish;
    }

    /* multi part Signing are completely implemented by SignUpdate and
     * sign Final */
    if (context->multi) {
        sftk_FreeSession(session);
       crv = NSC_SignUpdate(hSession,pData,ulDataLen);
       if (crv != CKR_OK) *pulSignatureLen = 0;
       crv2 = NSC_SignFinal(hSession, pSignature, pulSignatureLen);
       return crv == CKR_OK ? crv2 :crv;
    }

    rv = (*context->update)(context->cipherInfo, pSignature,
                                   &outlen, maxoutlen, pData, ulDataLen);
    *pulSignatureLen = (CK_ULONG) outlen;
    sftk_FreeContext(context);
    sftk_SetContextByType(session, SFTK_SIGN, NULL);

finish:
    sftk_FreeSession(session);

    return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_SignEncryptUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pPart,
CK_ULONG  ulPartLen,
CK_BYTE_PTR  pEncryptedPart,
CK_ULONG_PTR  pulEncryptedPartLen 
)

Definition at line 5816 of file pkcs11c.c.

{
    CK_RV crv;

    crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart, 
                                                pulEncryptedPartLen);
    if (crv != CKR_OK) return crv;
    crv = NSC_SignUpdate(hSession,pPart,ulPartLen);

    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_SignFinal ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pSignature,
CK_ULONG_PTR  pulSignatureLen 
)

Definition at line 1989 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int digestLen;
    unsigned int maxoutlen = *pulSignatureLen;
    unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];
    CK_RV crv;
    SECStatus rv = SECSuccess;

    /* make sure we're legal */
    *pulSignatureLen = 0;
    crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_TRUE,&session);
    if (crv != CKR_OK) return crv;

    if (!pSignature) {
       *pulSignatureLen = context->maxLen;
       goto finish;
    } else if (context->hashInfo) {
        (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
       rv = (*context->update)(context->cipherInfo, pSignature,
                                   &outlen, maxoutlen, tmpbuf, digestLen);
        *pulSignatureLen = (CK_ULONG) outlen;
    } else {
       /* deal with the last block if any residual */
       if (context->padDataLength) {
           /* fill out rest of pad buffer with pad magic*/
           int i;
           for (i=context->padDataLength; i < (int)context->blockSize; i++) {
              context->padBuf[i] = 0;
           }
           rv = (*context->update)(context->cipherInfo,context->macBuf,
              &outlen,SFTK_MAX_BLOCK_SIZE,context->padBuf,context->blockSize);
       }
       if (rv == SECSuccess) {
           PORT_Memcpy(pSignature,context->macBuf,context->macSize);
           *pulSignatureLen = context->macSize;
       }
    }

    sftk_FreeContext(context);
    sftk_SetContextByType(session, SFTK_SIGN, NULL);

finish:
    sftk_FreeSession(session);

    return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_SignInit ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_OBJECT_HANDLE  hKey 
)

Definition at line 1735 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPrivateKey *privKey;
    SFTKHashSignInfo *info = NULL;

    /* Block Cipher MACing Algorithms use a different Context init method..*/
    crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, SFTK_SIGN);
    if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;

    /* we're not using a block cipher mac */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session,&context,SFTK_SIGN,&key,hKey,&key_type,
                                          CKO_PRIVATE_KEY,CKA_SIGN);
    if (crv != CKR_OK) {
       sftk_FreeSession(session);
       return crv;
    }

    context->multi = PR_FALSE;

#define INIT_RSA_SIGN_MECH(mmm) \
    case CKM_ ## mmm ## _RSA_PKCS: \
        context->multi = PR_TRUE; \
       crv = sftk_doSub ## mmm (context); \
       if (crv != CKR_OK) break; \
       context->update = (SFTKCipher) sftk_HashSign; \
       info = PORT_New(SFTKHashSignInfo); \
       if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
       info->hashOid = SEC_OID_ ## mmm ; \
       goto finish_rsa; 

    switch(pMechanism->mechanism) {
    INIT_RSA_SIGN_MECH(MD5)
    INIT_RSA_SIGN_MECH(MD2)
    INIT_RSA_SIGN_MECH(SHA1)
    INIT_RSA_SIGN_MECH(SHA256)
    INIT_RSA_SIGN_MECH(SHA384)
    INIT_RSA_SIGN_MECH(SHA512)

    case CKM_RSA_PKCS:
       context->update = (SFTKCipher) RSA_Sign;
       goto finish_rsa;
    case CKM_RSA_X_509:
       context->update = (SFTKCipher)  RSA_SignRaw;
finish_rsa:
       if (key_type != CKK_RSA) {
           if (info) PORT_Free(info);
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
       if (privKey == NULL) {
           if (info) PORT_Free(info);
           break;
       }
       /* OK, info is allocated only if we're doing hash and sign mechanism.
        * It's necessary to be able to set the correct OID in the final 
        * signature.
        */
       if (info) {
           info->key = privKey;
           context->cipherInfo = info;
           context->destroy = (SFTKDestroy)sftk_Space;
       } else {
           context->cipherInfo = privKey;
           context->destroy = (SFTKDestroy)sftk_Null;
       }
       context->maxLen = nsslowkey_PrivateModulusLen(privKey);
       break;

    case CKM_DSA_SHA1:
        context->multi = PR_TRUE;
       crv = sftk_doSubSHA1(context);
       if (crv != CKR_OK) break;
       /* fall through */
    case CKM_DSA:
       if (key_type != CKK_DSA) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       privKey = sftk_GetPrivKey(key,CKK_DSA,&crv);
       if (privKey == NULL) {
           break;
       }
       context->cipherInfo = privKey;
       context->update     = (SFTKCipher) nsc_DSA_Sign_Stub;
       context->destroy    = (privKey == key->objectInfo) ?
              (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey;
       context->maxLen     = DSA_SIGNATURE_LEN;

       break;

#ifdef NSS_ENABLE_ECC
    case CKM_ECDSA_SHA1:
       context->multi = PR_TRUE;
       crv = sftk_doSubSHA1(context);
       if (crv != CKR_OK) break;
       /* fall through */
    case CKM_ECDSA:
       if (key_type != CKK_EC) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       privKey = sftk_GetPrivKey(key,CKK_EC,&crv);
       if (privKey == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }
       context->cipherInfo = privKey;
       context->update     = (SFTKCipher) nsc_ECDSASignStub;
       context->destroy    = (privKey == key->objectInfo) ?
              (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey;
       context->maxLen     = MAX_ECKEY_LEN * 2;

       break;
#endif /* NSS_ENABLE_ECC */

#define INIT_HMAC_MECH(mmm) \
    case CKM_ ## mmm ## _HMAC_GENERAL: \
       crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, \
                            *(CK_ULONG *)pMechanism->pParameter); \
       break; \
    case CKM_ ## mmm ## _HMAC: \
       crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, mmm ## _LENGTH); \
       break; 

    INIT_HMAC_MECH(MD2)
    INIT_HMAC_MECH(MD5)
    INIT_HMAC_MECH(SHA256)
    INIT_HMAC_MECH(SHA384)
    INIT_HMAC_MECH(SHA512)

    case CKM_SHA_1_HMAC_GENERAL:
       crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,
                            *(CK_ULONG *)pMechanism->pParameter);
       break;
    case CKM_SHA_1_HMAC:
       crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
       break;

    case CKM_SSL3_MD5_MAC:
       crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key,
                                   *(CK_ULONG *)pMechanism->pParameter);
       break;
    case CKM_SSL3_SHA1_MAC:
       crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key,
                                   *(CK_ULONG *)pMechanism->pParameter);
       break;
    case CKM_TLS_PRF_GENERAL:
       crv = sftk_TLSPRFInit(context, key, key_type);
       break;
    default:
       crv = CKR_MECHANISM_INVALID;
       break;
    }

    if (crv != CKR_OK) {
        sftk_FreeContext(context);
       sftk_FreeSession(session);
       return crv;
    }
    sftk_SetContextByType(session, SFTK_SIGN, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_SignRecover ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pData,
CK_ULONG  ulDataLen,
CK_BYTE_PTR  pSignature,
CK_ULONG_PTR  pulSignatureLen 
)

Definition at line 2109 of file pkcs11c.c.

{
    return NSC_Sign(hSession,pData,ulDataLen,pSignature,pulSignatureLen);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2092 of file pkcs11c.c.

{
    switch (pMechanism->mechanism) {
    case CKM_RSA_PKCS:
    case CKM_RSA_X_509:
       return NSC_SignInit(hSession,pMechanism,hKey);
    default:
       break;
    }
    return CKR_MECHANISM_INVALID;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_SignUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pPart,
CK_ULONG  ulPartLen 
)

Definition at line 1980 of file pkcs11c.c.

{
    return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_UnwrapKey ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_OBJECT_HANDLE  hUnwrappingKey,
CK_BYTE_PTR  pWrappedKey,
CK_ULONG  ulWrappedKeyLen,
CK_ATTRIBUTE_PTR  pTemplate,
CK_ULONG  ulAttributeCount,
CK_OBJECT_HANDLE_PTR  phKey 
)

Definition at line 4359 of file pkcs11c.c.

{
    SFTKObject *key = NULL;
    SFTKSession *session;
    CK_ULONG key_length = 0;
    unsigned char * buf = NULL;
    CK_RV crv = CKR_OK;
    int i;
    CK_ULONG bsize = ulWrappedKeyLen;
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    SECItem bpki;
    CK_OBJECT_CLASS target_type = CKO_SECRET_KEY;

    /*
     * now lets create an object to hang the attributes off of
     */
    key = sftk_NewObject(slot); /* fill in the handle later */
    if (key == NULL) {
       return CKR_HOST_MEMORY;
    }

    /*
     * load the template values into the object
     */
    for (i=0; i < (int) ulAttributeCount; i++) {
       if (pTemplate[i].type == CKA_VALUE_LEN) {
           key_length = *(CK_ULONG *)pTemplate[i].pValue;
           continue;
       }
        if (pTemplate[i].type == CKA_CLASS) {
           target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
       }
       crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
       if (crv != CKR_OK) break;
    }
    if (crv != CKR_OK) {
       sftk_FreeObject(key);
       return crv;
    }

    crv = sftk_CryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
                                                 SFTK_DECRYPT, PR_FALSE);
    if (crv != CKR_OK) {
       sftk_FreeObject(key);
       return sftk_mapWrap(crv);
    }

    /* allocate the buffer to decrypt into 
     * this assumes the unwrapped key is never larger than the
     * wrapped key. For all the mechanisms we support this is true */
    buf = (unsigned char *)PORT_Alloc( ulWrappedKeyLen);
    bsize = ulWrappedKeyLen;

    crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize);
    if (crv != CKR_OK) {
       sftk_FreeObject(key);
       PORT_Free(buf);
       return sftk_mapWrap(crv);
    }

    switch(target_type) {
       case CKO_SECRET_KEY:
           if (!sftk_hasAttribute(key,CKA_KEY_TYPE)) {
              crv = CKR_TEMPLATE_INCOMPLETE;
              break;
           }

           if (key_length == 0 || key_length > bsize) {
              key_length = bsize;
           }
           if (key_length > MAX_KEY_LEN) {
              crv = CKR_TEMPLATE_INCONSISTENT;
              break;
           }
    
           /* add the value */
           crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length);
           break;
       case CKO_PRIVATE_KEY:
           bpki.data = (unsigned char *)buf;
           bpki.len = bsize;
           crv = CKR_OK;
           if(sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) {
              crv = CKR_TEMPLATE_INCOMPLETE;
           }
           break;
       default:
           crv = CKR_TEMPLATE_INCONSISTENT;
           break;
    }

    PORT_ZFree(buf, bsize);
    if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }

    /* get the session */
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
       sftk_FreeObject(key);
        return CKR_SESSION_HANDLE_INVALID;
    }

    /*
     * handle the base object stuff
     */
    crv = sftk_handleObject(key,session);
    *phKey = key->handle;
    sftk_FreeSession(session);
    sftk_FreeObject(key);

    return crv;

}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_Verify ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pData,
CK_ULONG  ulDataLen,
CK_BYTE_PTR  pSignature,
CK_ULONG  ulSignatureLen 
)

Definition at line 2336 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    CK_RV crv, crv2;
    SECStatus rv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session);
    if (crv != CKR_OK) return crv;

    /* multi part Verifying are completely implemented by VerifyUpdate and
     * VerifyFinal */
    if (context->multi) {
       sftk_FreeSession(session);
       crv = NSC_VerifyUpdate(hSession, pData, ulDataLen);
       crv2 = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen);
       return crv == CKR_OK ? crv2 :crv;
    }

    rv = (*context->verify)(context->cipherInfo,pSignature, ulSignatureLen,
                                                  pData, ulDataLen);
    sftk_FreeContext(context);
    sftk_SetContextByType(session, SFTK_VERIFY, NULL);
    sftk_FreeSession(session);

    return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;

}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_VerifyFinal ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pSignature,
CK_ULONG  ulSignatureLen 
)

Definition at line 2380 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int digestLen;
    unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];
    CK_RV crv;
    SECStatus rv = SECSuccess;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_TRUE,&session);
    if (crv != CKR_OK) return crv;

    if (context->hashInfo) {
        (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
       rv = (*context->verify)(context->cipherInfo, pSignature, 
                                   ulSignatureLen, tmpbuf, digestLen);
    } else {
       if (context->padDataLength) {
           /* fill out rest of pad buffer with pad magic*/
           int i;
           for (i=context->padDataLength; i < (int)context->blockSize; i++) {
              context->padBuf[i] = 0;
           }
           rv = (*context->update)(context->cipherInfo,context->macBuf, 
              &outlen,SFTK_MAX_BLOCK_SIZE,context->padBuf,context->blockSize);
       }
       if (rv == SECSuccess) {
           rv =(PORT_Memcmp(pSignature,context->macBuf,context->macSize) == 0)
                             ? SECSuccess : SECFailure;
       }
    }

    sftk_FreeContext(context);
    sftk_SetContextByType(session, SFTK_VERIFY, NULL);
    sftk_FreeSession(session);
    return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;

}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2183 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPublicKey *pubKey;
    SFTKHashVerifyInfo *info = NULL;

    /* Block Cipher MACing Algorithms use a different Context init method..*/
    crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY, SFTK_VERIFY);
    if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session,&context,SFTK_VERIFY,&key,hKey,&key_type,
                                          CKO_PUBLIC_KEY,CKA_VERIFY);
    if (crv != CKR_OK) {
       sftk_FreeSession(session);
       return crv;
    }

    context->multi = PR_FALSE;

#define INIT_RSA_VFY_MECH(mmm) \
    case CKM_ ## mmm ## _RSA_PKCS: \
        context->multi = PR_TRUE; \
       crv = sftk_doSub ## mmm (context); \
       if (crv != CKR_OK) break; \
       context->verify = (SFTKVerify) sftk_hashCheckSign; \
       info = PORT_New(SFTKHashVerifyInfo); \
       if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
       info->hashOid = SEC_OID_ ## mmm ; \
       goto finish_rsa; 

    switch(pMechanism->mechanism) {
    INIT_RSA_VFY_MECH(MD5) 
    INIT_RSA_VFY_MECH(MD2) 
    INIT_RSA_VFY_MECH(SHA1) 
    INIT_RSA_VFY_MECH(SHA256) 
    INIT_RSA_VFY_MECH(SHA384) 
    INIT_RSA_VFY_MECH(SHA512) 

    case CKM_RSA_PKCS:
       context->verify = (SFTKVerify) RSA_CheckSign;
       goto finish_rsa;
    case CKM_RSA_X_509:
       context->verify = (SFTKVerify) RSA_CheckSignRaw;
finish_rsa:
       if (key_type != CKK_RSA) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
       if (pubKey == NULL) {
           break;
       }
       if (info) {
           info->key = pubKey;
           context->cipherInfo = info;
           context->destroy = sftk_Space;
       } else {
           context->cipherInfo = pubKey;
           context->destroy = sftk_Null;
       }
       break;
    case CKM_DSA_SHA1:
        context->multi = PR_TRUE;
       crv = sftk_doSubSHA1(context);
       if (crv != CKR_OK) break;
       /* fall through */
    case CKM_DSA:
       if (key_type != CKK_DSA) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       pubKey = sftk_GetPubKey(key,CKK_DSA,&crv);
       if (pubKey == NULL) {
           break;
       }
       context->cipherInfo = pubKey;
       context->verify     = (SFTKVerify) nsc_DSA_Verify_Stub;
       context->destroy    = sftk_Null;
       break;
#ifdef NSS_ENABLE_ECC
    case CKM_ECDSA_SHA1:
       context->multi = PR_TRUE;
       crv = sftk_doSubSHA1(context);
       if (crv != CKR_OK) break;
       /* fall through */
    case CKM_ECDSA:
       if (key_type != CKK_EC) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       pubKey = sftk_GetPubKey(key,CKK_EC,&crv);
       if (pubKey == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }
       context->cipherInfo = pubKey;
       context->verify     = (SFTKVerify) nsc_ECDSAVerifyStub;
       context->destroy    = sftk_Null;
       break;
#endif /* NSS_ENABLE_ECC */

    INIT_HMAC_MECH(MD2)
    INIT_HMAC_MECH(MD5)
    INIT_HMAC_MECH(SHA256)
    INIT_HMAC_MECH(SHA384)
    INIT_HMAC_MECH(SHA512)

    case CKM_SHA_1_HMAC_GENERAL:
       crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,
                            *(CK_ULONG *)pMechanism->pParameter);
       break;
    case CKM_SHA_1_HMAC:
       crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
       break;

    case CKM_SSL3_MD5_MAC:
       crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key,
                                   *(CK_ULONG *)pMechanism->pParameter);
       break;
    case CKM_SSL3_SHA1_MAC:
       crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key,
                                   *(CK_ULONG *)pMechanism->pParameter);
       break;
    case CKM_TLS_PRF_GENERAL:
       crv = sftk_TLSPRFInit(context, key, key_type);
       break;

    default:
       crv = CKR_MECHANISM_INVALID;
       break;
    }

    if (crv != CKR_OK) {
       if (info) PORT_Free(info);
        PORT_Free(context);
       sftk_FreeSession(session);
       return crv;
    }
    sftk_SetContextByType(session, SFTK_VERIFY, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_VerifyRecover ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pSignature,
CK_ULONG  ulSignatureLen,
CK_BYTE_PTR  pData,
CK_ULONG_PTR  pulDataLen 
)

Definition at line 2486 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;
    unsigned int outlen;
    unsigned int maxoutlen = *pulDataLen;
    CK_RV crv;
    SECStatus rv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER,
                                                 PR_FALSE,&session);
    if (crv != CKR_OK) return crv;
    if (pData == NULL) {
       /* to return the actual size, we need  to do the decrypt, just return
        * the max size, which is the size of the input signature. */
       *pulDataLen = ulSignatureLen;
       rv = SECSuccess;
       goto finish;
    }

    rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, 
                                          pSignature, ulSignatureLen);
    *pulDataLen = (CK_ULONG) outlen;

    sftk_FreeContext(context);
    sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, NULL);
finish:
    sftk_FreeSession(session);
    return (rv == SECSuccess)  ? CKR_OK : CKR_SIGNATURE_INVALID;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2429 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPublicKey *pubKey;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
    crv = sftk_InitGeneric(session,&context,SFTK_VERIFY_RECOVER,
                     &key,hKey,&key_type,CKO_PUBLIC_KEY,CKA_VERIFY_RECOVER);
    if (crv != CKR_OK) {
       sftk_FreeSession(session);
       return crv;
    }

    context->multi = PR_TRUE;

    switch(pMechanism->mechanism) {
    case CKM_RSA_PKCS:
    case CKM_RSA_X_509:
       if (key_type != CKK_RSA) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       context->multi = PR_FALSE;
       pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
       if (pubKey == NULL) {
           break;
       }
       context->cipherInfo = pubKey;
       context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509
                     ? RSA_CheckSignRecoverRaw : RSA_CheckSignRecover);
       context->destroy = sftk_Null;
       break;
    default:
       crv = CKR_MECHANISM_INVALID;
       break;
    }

    if (crv != CKR_OK) {
        PORT_Free(context);
       sftk_FreeSession(session);
       return crv;
    }
    sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_VerifyUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pPart,
CK_ULONG  ulPartLen 
)

Definition at line 2371 of file pkcs11c.c.

{
    return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CK_RV NSC_WrapKey ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_OBJECT_HANDLE  hWrappingKey,
CK_OBJECT_HANDLE  hKey,
CK_BYTE_PTR  pWrappedKey,
CK_ULONG_PTR  pulWrappedKeyLen 
)

Definition at line 3996 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKAttribute *attribute;
    SFTKObject *key;
    CK_RV crv;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) {
       return CKR_SESSION_HANDLE_INVALID;
    }

    key = sftk_ObjectFromHandle(hKey,session);
    sftk_FreeSession(session);
    if (key == NULL) {
       return CKR_KEY_HANDLE_INVALID;
    }

    switch(key->objclass) {
       case CKO_SECRET_KEY:
         {
           SFTKSessionContext *context = NULL;
           SECItem pText;

           attribute = sftk_FindAttribute(key,CKA_VALUE);

           if (attribute == NULL) {
              crv = CKR_KEY_TYPE_INCONSISTENT;
              break;
           }
           crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey, 
                                   CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
           if (crv != CKR_OK) {
              sftk_FreeAttribute(attribute);
              break;
           }

           pText.type = siBuffer;
           pText.data = (unsigned char *)attribute->attrib.pValue;
           pText.len  = attribute->attrib.ulValueLen;

           /* Find out if this is a block cipher. */
           crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,NULL);
           if (crv != CKR_OK || !context) 
               break;
           if (context->blockSize > 1) {
              unsigned int remainder = pText.len % context->blockSize;
               if (!context->doPad && remainder) {
                  /* When wrapping secret keys with unpadded block ciphers, 
                  ** the keys are zero padded, if necessary, to fill out 
                  ** a full block.
                  */
                  pText.len += context->blockSize - remainder;
                  pText.data = PORT_ZAlloc(pText.len);
                  if (pText.data)
                     memcpy(pText.data, attribute->attrib.pValue,
                                        attribute->attrib.ulValueLen);
                  else {
                     crv = CKR_HOST_MEMORY;
                     break;
                  }
              }
           }

           crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data, 
                            pText.len, pWrappedKey, pulWrappedKeyLen);
           /* always force a finalize, both on errors and when
            * we are just getting the size */
           if (crv != CKR_OK || pWrappedKey == NULL) {
              CK_RV lcrv ;
              lcrv = sftk_GetContext(hSession,&context,
                                   SFTK_ENCRYPT,PR_FALSE,NULL);
              sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
              if (lcrv == CKR_OK && context) {
                  sftk_FreeContext(context);
              }
           }

           if (pText.data != (unsigned char *)attribute->attrib.pValue) 
              PORT_ZFree(pText.data, pText.len);
           sftk_FreeAttribute(attribute);
           break;
         }

       case CKO_PRIVATE_KEY:
           {
              SECItem *bpki = sftk_PackagePrivateKey(key, &crv);
              SFTKSessionContext *context = NULL;

              if(!bpki) {
                  break;
              }

              crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
                                   CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
              if(crv != CKR_OK) {
                  SECITEM_ZfreeItem(bpki, PR_TRUE);
                  crv = CKR_KEY_TYPE_INCONSISTENT;
                  break;
              }

              crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
                                   pWrappedKey, pulWrappedKeyLen);
              /* always force a finalize */
              if (crv != CKR_OK || pWrappedKey == NULL) {
                  CK_RV lcrv ;
                  lcrv = sftk_GetContext(hSession,&context,
                                      SFTK_ENCRYPT,PR_FALSE,NULL);
                  sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
                  if (lcrv == CKR_OK && context)  {
                     sftk_FreeContext(context);
                  }
              }
              SECITEM_ZfreeItem(bpki, PR_TRUE);
              break;
           }

       default:
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
    }
    sftk_FreeObject(key);

    return sftk_mapWrap(crv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus RSA_HashCheckSign ( SECOidTag  hashOid,
NSSLOWKEYPublicKey *  key,
unsigned char *  sig,
unsigned int  sigLen,
unsigned char *  digest,
unsigned int  digestLen 
)

Definition at line 2129 of file pkcs11c.c.

{

    SECItem it;
    SGNDigestInfo *di = NULL;
    SECStatus rv = SECSuccess;
    
    it.data = NULL;

    if (key == NULL) goto loser;

    it.len = nsslowkey_PublicModulusLen(key); 
    if (!it.len) goto loser;

    it.data = (unsigned char *) PORT_Alloc(it.len);
    if (it.data == NULL) goto loser;

    /* decrypt the block */
    rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen);
    if (rv != SECSuccess) goto loser;

    di = SGN_DecodeDigestInfo(&it);
    if (di == NULL) goto loser;
    if (di->digest.len != digestLen)  goto loser; 

    /* make sure the tag is OK */
    if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) {
       goto loser;
    }
    /* make sure the "parameters" are not too bogus. */
    if (di->digestAlgorithm.parameters.len > 2) {
       goto loser;
    }
    /* Now check the signature */
    if (PORT_Memcmp(digest, di->digest.data, di->digest.len) == 0) {
       goto done;
    }

  loser:
    PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
    rv = SECFailure;

  done:
    if (it.data != NULL) PORT_Free(it.data);
    if (di != NULL) SGN_DestroyDigestInfo(di);
    
    return rv;
}

Here is the caller graph for this function:

SECStatus RSA_HashSign ( SECOidTag  hashOid,
NSSLOWKEYPrivateKey *  key,
unsigned char *  sig,
unsigned int sigLen,
unsigned int  maxLen,
unsigned char *  hash,
unsigned int  hashLen 
)

Definition at line 1602 of file pkcs11c.c.

{
    
    SECStatus rv = SECFailure;
    SECItem digder;
    PLArenaPool *arena = NULL;
    SGNDigestInfo *di = NULL;

    digder.data = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if ( !arena ) { goto loser; }
    
    /* Construct digest info */
    di = SGN_CreateDigestInfo(hashOid, hash, hashLen);
    if (!di) { goto loser; }

    /* Der encode the digest as a DigestInfo */
    rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di);
    if (rv != SECSuccess) {
       goto loser;
    }

    /*
    ** Encrypt signature after constructing appropriate PKCS#1 signature
    ** block
    */
    rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len);

  loser:
    SGN_DestroyDigestInfo(di);
    if (arena != NULL) {
       PORT_FreeArena(arena, PR_FALSE);
    }
    return rv;
}

Here is the caller graph for this function:

static CK_RV sftk_buildSSLKey ( CK_SESSION_HANDLE  hSession,
SFTKObject *  baseKey,
PRBool  isMacKey,
unsigned char *  keyBlock,
unsigned int  keySize,
CK_OBJECT_HANDLE keyHandle 
) [static]

Definition at line 4481 of file pkcs11c.c.

{
    SFTKObject *key;
    SFTKSession *session;
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_BBOOL cktrue = CK_TRUE;
    CK_BBOOL ckfalse = CK_FALSE;
    CK_RV crv = CKR_HOST_MEMORY;

    /*
     * now lets create an object to hang the attributes off of
     */
    *keyHandle = CK_INVALID_HANDLE;
    key = sftk_NewObject(baseKey->slot); 
    if (key == NULL) return CKR_HOST_MEMORY;
    sftk_narrowToSessionObject(key)->wasDerived = PR_TRUE;

    crv = sftk_CopyObject(key,baseKey);
    if (crv != CKR_OK) goto loser;
    if (isMacKey) {
       crv = sftk_forceAttribute(key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
       if (crv != CKR_OK) goto loser;
       crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
       if (crv != CKR_OK) goto loser;
       crv = sftk_forceAttribute(key,CKA_ENCRYPT,&ckfalse,sizeof(CK_BBOOL));
       if (crv != CKR_OK) goto loser;
       crv = sftk_forceAttribute(key,CKA_DECRYPT,&ckfalse,sizeof(CK_BBOOL));
       if (crv != CKR_OK) goto loser;
       crv = sftk_forceAttribute(key,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));
       if (crv != CKR_OK) goto loser;
       crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
       if (crv != CKR_OK) goto loser;
       crv = sftk_forceAttribute(key,CKA_WRAP,&ckfalse,sizeof(CK_BBOOL));
       if (crv != CKR_OK) goto loser;
       crv = sftk_forceAttribute(key,CKA_UNWRAP,&ckfalse,sizeof(CK_BBOOL));
       if (crv != CKR_OK) goto loser;
    }
    crv = sftk_forceAttribute(key,CKA_VALUE,keyBlock,keySize);
    if (crv != CKR_OK) goto loser;

    /* get the session */
    crv = CKR_HOST_MEMORY;
    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) { goto loser; }

    crv = sftk_handleObject(key,session);
    sftk_FreeSession(session);
    *keyHandle = key->handle;
loser:
    if (key) sftk_FreeObject(key);
    return crv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_cdmf2des ( unsigned char *  cdmfkey,
unsigned char *  deskey 
) [static]

Definition at line 137 of file pkcs11c.c.

{
    unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae };
    unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 };
    unsigned char enc_src[8];
    unsigned char enc_dest[8];
    unsigned int leng,i;
    DESContext *descx;
    SECStatus rv;
    
    
    /* zero the parity bits */
    for (i=0; i < 8; i++) {
       enc_src[i] = cdmfkey[i] & 0xfe;
    }

    /* encrypt with key 1 */
    descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE);
    if (descx == NULL) return CKR_HOST_MEMORY;
    rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8);
    DES_DestroyContext(descx,PR_TRUE);
    if (rv != SECSuccess) return CKR_DEVICE_ERROR;

    /* xor source with des, zero the parity bits and depricate the key*/
    for (i=0; i < 8; i++) {
       if (i & 1) {
           enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe;
       } else {
           enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e;
       }
    }

    /* encrypt with key 2 */
    descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE);
    if (descx == NULL) return CKR_HOST_MEMORY;
    rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8);
    DES_DestroyContext(descx,PR_TRUE);
    if (rv != SECSuccess) return CKR_DEVICE_ERROR;

    /* set the corret parity on our new des key */      
    sftk_FormatDESKey(deskey, 8);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_CryptInit ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_OBJECT_HANDLE  hKey,
CK_ATTRIBUTE_TYPE  etype,
SFTKContextType  contextType,
PRBool  isEncrypt 
) [static]

Definition at line 401 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKObject *key;
    SFTKSessionContext *context;
    SFTKAttribute *att;
    CK_RC2_CBC_PARAMS *rc2_param;
#if NSS_SOFTOKEN_DOES_RC5
    CK_RC5_CBC_PARAMS *rc5_param;
    SECItem rc5Key;
#endif
    CK_KEY_TYPE key_type;
    CK_RV crv = CKR_OK;
    unsigned effectiveKeyLength;
    unsigned char newdeskey[24];
    PRBool useNewKey=PR_FALSE;
    int t;

    crv = sftk_MechAllowsOperation(pMechanism->mechanism, etype);
    if (crv != CKR_OK) 
       return crv;

    session = sftk_SessionFromHandle(hSession);
    if (session == NULL) return CKR_SESSION_HANDLE_INVALID;

    crv = sftk_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
                     isEncrypt ?CKO_PUBLIC_KEY:CKO_PRIVATE_KEY, etype);
                                          
    if (crv != CKR_OK) {
       sftk_FreeSession(session);
       return crv;
    }

    context->doPad = PR_FALSE;
    switch(pMechanism->mechanism) {
    case CKM_RSA_PKCS:
    case CKM_RSA_X_509:
       if (key_type != CKK_RSA) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       context->multi = PR_FALSE;
       if (isEncrypt) {
           NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
           if (pubKey == NULL) {
              break;
           }
           context->maxLen = nsslowkey_PublicModulusLen(pubKey);
           context->cipherInfo =  (void *)pubKey;
           context->update = (SFTKCipher) 
              (pMechanism->mechanism == CKM_RSA_X_509
                                   ? RSA_EncryptRaw : RSA_EncryptBlock);
       } else {
           NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
           if (privKey == NULL) {
              break;
           }
           context->maxLen = nsslowkey_PrivateModulusLen(privKey);
           context->cipherInfo =  (void *)privKey;
           context->update = (SFTKCipher) 
              (pMechanism->mechanism == CKM_RSA_X_509
                                   ? RSA_DecryptRaw : RSA_DecryptBlock);
       }
       context->destroy = sftk_Null;
       break;
    case CKM_RC2_CBC_PAD:
       context->doPad = PR_TRUE;
       /* fall thru */
    case CKM_RC2_ECB:
    case CKM_RC2_CBC:
       context->blockSize = 8;
       if (key_type != CKK_RC2) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       att = sftk_FindAttribute(key,CKA_VALUE);
       if (att == NULL) {
           crv = CKR_KEY_HANDLE_INVALID;
           break;
       }
       rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
       effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8;
       context->cipherInfo = 
           RC2_CreateContext((unsigned char*)att->attrib.pValue,
                           att->attrib.ulValueLen, rc2_param->iv,
                           pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 :
                           NSS_RC2_CBC,effectiveKeyLength);
       sftk_FreeAttribute(att);
       if (context->cipherInfo == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }
       context->update = (SFTKCipher) (isEncrypt ? RC2_Encrypt : RC2_Decrypt);
       context->destroy = (SFTKDestroy) RC2_DestroyContext;
       break;
#if NSS_SOFTOKEN_DOES_RC5
    case CKM_RC5_CBC_PAD:
       context->doPad = PR_TRUE;
       /* fall thru */
    case CKM_RC5_ECB:
    case CKM_RC5_CBC:
       if (key_type != CKK_RC5) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       att = sftk_FindAttribute(key,CKA_VALUE);
       if (att == NULL) {
           crv = CKR_KEY_HANDLE_INVALID;
           break;
       }
       rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
       context->blockSize = rc5_param->ulWordsize*2;
       rc5Key.data = (unsigned char*)att->attrib.pValue;
       rc5Key.len = att->attrib.ulValueLen;
       context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds,
          rc5_param->ulWordsize,rc5_param->pIv,
               pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
       sftk_FreeAttribute(att);
       if (context->cipherInfo == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }
       context->update = (SFTKCipher) (isEncrypt ? RC5_Encrypt : RC5_Decrypt);
       context->destroy = (SFTKDestroy) RC5_DestroyContext;
       break;
#endif
    case CKM_RC4:
       if (key_type != CKK_RC4) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       att = sftk_FindAttribute(key,CKA_VALUE);
       if (att == NULL) {
           crv = CKR_KEY_HANDLE_INVALID;
           break;
       }
       context->cipherInfo = 
           RC4_CreateContext((unsigned char*)att->attrib.pValue,
                           att->attrib.ulValueLen);
       sftk_FreeAttribute(att);
       if (context->cipherInfo == NULL) {
           crv = CKR_HOST_MEMORY;  /* WRONG !!! */
           break;
       }
       context->update = (SFTKCipher) (isEncrypt ? RC4_Encrypt : RC4_Decrypt);
       context->destroy = (SFTKDestroy) RC4_DestroyContext;
       break;
    case CKM_CDMF_CBC_PAD:
       context->doPad = PR_TRUE;
       /* fall thru */
    case CKM_CDMF_ECB:
    case CKM_CDMF_CBC:
       if (key_type != CKK_CDMF) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
       if (crv != CKR_OK) break;
       goto finish_des;
    case CKM_DES_ECB:
       if (key_type != CKK_DES) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       t = NSS_DES;
       goto finish_des;
    case CKM_DES_CBC_PAD:
       context->doPad = PR_TRUE;
       /* fall thru */
    case CKM_DES_CBC:
       if (key_type != CKK_DES) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       t = NSS_DES_CBC;
       goto finish_des;
    case CKM_DES3_ECB:
       if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       t = NSS_DES_EDE3;
       goto finish_des;
    case CKM_DES3_CBC_PAD:
       context->doPad = PR_TRUE;
       /* fall thru */
    case CKM_DES3_CBC:
       if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       t = NSS_DES_EDE3_CBC;
finish_des:
       context->blockSize = 8;
       att = sftk_FindAttribute(key,CKA_VALUE);
       if (att == NULL) {
           crv = CKR_KEY_HANDLE_INVALID;
           break;
       }
       if (key_type == CKK_DES2 && 
            (t == NSS_DES_EDE3_CBC || t == NSS_DES_EDE3)) {
           /* extend DES2 key to DES3 key. */
           memcpy(newdeskey, att->attrib.pValue, 16);
           memcpy(newdeskey + 16, newdeskey, 8);
           useNewKey=PR_TRUE;
       } else if (key_type == CKK_CDMF) {
           crv = sftk_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey);
           if (crv != CKR_OK) {
              sftk_FreeAttribute(att);
              break;
           }
           useNewKey=PR_TRUE;
       }
       context->cipherInfo = DES_CreateContext(
              useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
              (unsigned char*)pMechanism->pParameter,t, isEncrypt);
       if (useNewKey) 
           memset(newdeskey, 0, sizeof newdeskey);
       sftk_FreeAttribute(att);
       if (context->cipherInfo == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }
       context->update = (SFTKCipher) (isEncrypt ? DES_Encrypt : DES_Decrypt);
       context->destroy = (SFTKDestroy) DES_DestroyContext;
       break;

    case CKM_AES_CBC_PAD:
       context->doPad = PR_TRUE;
       /* fall thru */
    case CKM_AES_ECB:
    case CKM_AES_CBC:
       context->blockSize = 16;
       if (key_type != CKK_AES) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       att = sftk_FindAttribute(key,CKA_VALUE);
       if (att == NULL) {
           crv = CKR_KEY_HANDLE_INVALID;
           break;
       }
       context->cipherInfo = AES_CreateContext(
           (unsigned char*)att->attrib.pValue,
           (unsigned char*)pMechanism->pParameter,
           pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC,
           isEncrypt, att->attrib.ulValueLen, 16);
       sftk_FreeAttribute(att);
       if (context->cipherInfo == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }
       context->update = (SFTKCipher) (isEncrypt ? AES_Encrypt : AES_Decrypt);
       context->destroy = (SFTKDestroy) AES_DestroyContext;
       break;

    case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
       context->doPad = PR_TRUE;
       /* fall thru */
    case CKM_NETSCAPE_AES_KEY_WRAP:
       context->multi = PR_FALSE;
       context->blockSize = 8;
       if (key_type != CKK_AES) {
           crv = CKR_KEY_TYPE_INCONSISTENT;
           break;
       }
       att = sftk_FindAttribute(key,CKA_VALUE);
       if (att == NULL) {
           crv = CKR_KEY_HANDLE_INVALID;
           break;
       }
       context->cipherInfo = AESKeyWrap_CreateContext(
           (unsigned char*)att->attrib.pValue,
           (unsigned char*)pMechanism->pParameter,
           isEncrypt, att->attrib.ulValueLen);
       sftk_FreeAttribute(att);
       if (context->cipherInfo == NULL) {
           crv = CKR_HOST_MEMORY;
           break;
       }
       context->update = (SFTKCipher) (isEncrypt ? AESKeyWrap_Encrypt 
                                                 : AESKeyWrap_Decrypt);
       context->destroy = (SFTKDestroy) AESKeyWrap_DestroyContext;
       break;

    default:
       crv = CKR_MECHANISM_INVALID;
       break;
    }

    if (crv != CKR_OK) {
        sftk_FreeContext(context);
       sftk_FreeSession(session);
       return crv;
    }
    sftk_SetContextByType(session, contextType, context);
    sftk_FreeSession(session);
    return CKR_OK;
}

Here is the caller graph for this function:

static CK_RV sftk_DeriveSensitiveCheck ( SFTKObject *  baseKey,
SFTKObject *  destKey 
) [static]

Definition at line 4564 of file pkcs11c.c.

{
    PRBool hasSensitive;
    PRBool sensitive = PR_FALSE;
    PRBool hasExtractable;
    PRBool extractable = PR_TRUE;
    CK_RV crv = CKR_OK;
    SFTKAttribute *att;

    hasSensitive = PR_FALSE;
    att = sftk_FindAttribute(destKey,CKA_SENSITIVE);
    if (att) {
        hasSensitive = PR_TRUE;
       sensitive = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
       sftk_FreeAttribute(att);
    }

    hasExtractable = PR_FALSE;
    att = sftk_FindAttribute(destKey,CKA_EXTRACTABLE);
    if (att) {
        hasExtractable = PR_TRUE;
       extractable = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
       sftk_FreeAttribute(att);
    }


    /* don't make a key more accessible */
    if (sftk_isTrue(baseKey,CKA_SENSITIVE) && hasSensitive && 
                                          (sensitive == PR_FALSE)) {
       return CKR_KEY_FUNCTION_NOT_PERMITTED;
    }
    if (!sftk_isTrue(baseKey,CKA_EXTRACTABLE) && hasExtractable && 
                                          (extractable == PR_TRUE)) {
       return CKR_KEY_FUNCTION_NOT_PERMITTED;
    }

    /* inherit parent's sensitivity */
    if (!hasSensitive) {
        att = sftk_FindAttribute(baseKey,CKA_SENSITIVE);
       if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
       crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib));
       sftk_FreeAttribute(att);
       if (crv != CKR_OK) return crv;
    }
    if (!hasExtractable) {
        att = sftk_FindAttribute(baseKey,CKA_EXTRACTABLE);
       if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
       crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib));
       sftk_FreeAttribute(att);
       if (crv != CKR_OK) return crv;
    }

    /* we should inherit the parent's always extractable/ never sensitive info,
     * but handleObject always forces this attributes, so we would need to do
     * something special. */
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_doHMACInit ( SFTKSessionContext *  context,
HASH_HashType  hash,
SFTKObject *  key,
CK_ULONG  mac_size 
) [static]

Definition at line 1303 of file pkcs11c.c.

{
    SFTKAttribute *keyval;
    HMACContext *HMACcontext;
    CK_ULONG *intpointer;
    const SECHashObject *hashObj = HASH_GetRawHashObject(hash);
    PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);

    /* required by FIPS 198 Section 4 */
    if (isFIPS && (mac_size < 4 || mac_size < hashObj->length/2)) {
       return CKR_BUFFER_TOO_SMALL;
    }

    keyval = sftk_FindAttribute(key,CKA_VALUE);
    if (keyval == NULL) return CKR_KEY_SIZE_RANGE;

    HMACcontext = HMAC_Create(hashObj, 
              (const unsigned char*)keyval->attrib.pValue,
              keyval->attrib.ulValueLen, isFIPS);
    context->hashInfo = HMACcontext;
    context->multi = PR_TRUE;
    sftk_FreeAttribute(keyval);
    if (context->hashInfo == NULL) {
       if (PORT_GetError() == SEC_ERROR_INVALID_ARGS) {
           return CKR_KEY_SIZE_RANGE;
       }
       return CKR_HOST_MEMORY;
    }
    context->hashUpdate = (SFTKHash) HMAC_Update;
    context->end = (SFTKEnd) HMAC_Finish;

    context->hashdestroy = (SFTKDestroy) HMAC_Destroy;
    intpointer = (CK_ULONG *) PORT_Alloc(sizeof(CK_ULONG));
    if (intpointer == NULL) {
       return CKR_HOST_MEMORY;
    }
    *intpointer = mac_size;
    context->cipherInfo = (void *) intpointer;
    context->destroy = (SFTKDestroy) sftk_Space;
    context->update = (SFTKCipher) sftk_HMACCopy;
    context->verify = (SFTKVerify) sftk_HMACCmp;
    context->maxLen = hashObj->length;
    HMAC_Begin(HMACcontext);
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_doSSLMACInit ( SFTKSessionContext *  context,
SECOidTag  oid,
SFTKObject *  key,
CK_ULONG  mac_size 
) [static]

Definition at line 1419 of file pkcs11c.c.

{
    SFTKAttribute *keyval;
    SFTKBegin begin;
    int padSize;
    SFTKSSLMACInfo *sslmacinfo;
    CK_RV crv = CKR_MECHANISM_INVALID;

    if (oid == SEC_OID_SHA1) {
       crv = sftk_doSubSHA1(context);
       if (crv != CKR_OK) return crv;
       begin = (SFTKBegin) SHA1_Begin;
       padSize = 40;
    } else {
       crv = sftk_doSubMD5(context);
       if (crv != CKR_OK) return crv;
       begin = (SFTKBegin) MD5_Begin;
       padSize = 48;
    }
    context->multi = PR_TRUE;

    keyval = sftk_FindAttribute(key,CKA_VALUE);
    if (keyval == NULL) return CKR_KEY_SIZE_RANGE;

    context->hashUpdate(context->hashInfo,keyval->attrib.pValue,
                                           keyval->attrib.ulValueLen);
    context->hashUpdate(context->hashInfo,ssl_pad_1,padSize);
    sslmacinfo = (SFTKSSLMACInfo *) PORT_Alloc(sizeof(SFTKSSLMACInfo));
    if (sslmacinfo == NULL) {
        sftk_FreeAttribute(keyval);
       return CKR_HOST_MEMORY;
    }
    sslmacinfo->macSize = mac_size;
    sslmacinfo->hashContext = context->hashInfo;
    PORT_Memcpy(sslmacinfo->key,keyval->attrib.pValue,
                                   keyval->attrib.ulValueLen);
    sslmacinfo->keySize = keyval->attrib.ulValueLen;
    sslmacinfo->begin = begin;
    sslmacinfo->end = context->end;
    sslmacinfo->update = context->hashUpdate;
    sslmacinfo->padSize = padSize;
    sftk_FreeAttribute(keyval);
    context->cipherInfo = (void *) sslmacinfo;
    context->destroy = (SFTKDestroy) sftk_Space;
    context->update = (SFTKCipher) sftk_SSLMACSign;
    context->verify = (SFTKVerify) sftk_SSLMACVerify;
    context->maxLen = mac_size;
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sftk_FreePrivKey ( NSSLOWKEYPrivateKey *  key,
PRBool  freeit 
) [static]

Definition at line 120 of file pkcs11c.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void sftk_freeSSLKeys ( CK_SESSION_HANDLE  session,
CK_SSL3_KEY_MAT_OUT returnedMaterial 
) [static]

Definition at line 4541 of file pkcs11c.c.

{
       if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) {
          NSC_DestroyObject(session,returnedMaterial->hClientMacSecret);
       }
       if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) {
          NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
       }
       if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) {
          NSC_DestroyObject(session, returnedMaterial->hClientKey);
       }
       if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) {
          NSC_DestroyObject(session, returnedMaterial->hServerKey);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_GetContext ( CK_SESSION_HANDLE  handle,
SFTKSessionContext **  contextPtr,
SFTKContextType  type,
PRBool  needMulti,
SFTKSession **  sessionPtr 
) [static]

Definition at line 299 of file pkcs11c.c.

{
    SFTKSession *session;
    SFTKSessionContext *context;

    session = sftk_SessionFromHandle(handle);
    if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
    context = sftk_ReturnContextByType(session,type);
    /* make sure the context is valid */
    if((context==NULL)||(context->type!=type)||(needMulti&&!(context->multi))){
        sftk_FreeSession(session);
       return CKR_OPERATION_NOT_INITIALIZED;
    }
    *contextPtr = context;
    if (sessionPtr != NULL) {
       *sessionPtr = session;
    } else {
       sftk_FreeSession(session);
    }
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus sftk_hashCheckSign ( SFTKHashVerifyInfo *  info,
unsigned char *  sig,
unsigned int  sigLen,
unsigned char *  digest,
unsigned int  digestLen 
) [static]

Definition at line 2121 of file pkcs11c.c.

{
    return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen,
                                          digest, digestLen);
}

Here is the call graph for this function:

static SECStatus sftk_HashSign ( SFTKHashSignInfo *  info,
unsigned char *  sig,
unsigned int sigLen,
unsigned int  maxLen,
unsigned char *  hash,
unsigned int  hashLen 
) [static]

Definition at line 1594 of file pkcs11c.c.

{
    return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen,
                                                 hash,hashLen);
}

Here is the call graph for this function:

static SECStatus sftk_HMACCmp ( CK_ULONG copyLen,
unsigned char *  sig,
unsigned int  sigLen,
unsigned char *  hash,
unsigned int  hashLen 
) [static]

Definition at line 1293 of file pkcs11c.c.

{
    return (PORT_Memcmp(sig,hash,*copyLen) == 0) ? SECSuccess : SECFailure ; 
}

Here is the caller graph for this function:

static SECStatus sftk_HMACCopy ( CK_ULONG copyLen,
unsigned char *  sig,
unsigned int sigLen,
unsigned int  maxLen,
unsigned char *  hash,
unsigned int  hashLen 
) [static]

Definition at line 1282 of file pkcs11c.c.

{
    if (maxLen < *copyLen) return SECFailure;
    PORT_Memcpy(sig,hash,*copyLen);
    *sigLen = *copyLen;
    return SECSuccess;
}

Here is the caller graph for this function:

static CK_RV sftk_InitCBCMac ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_OBJECT_HANDLE  hKey,
CK_ATTRIBUTE_TYPE  keyUsage,
SFTKContextType  contextType 
) [static]

Definition at line 1478 of file pkcs11c.c.

{
    CK_MECHANISM cbc_mechanism;
    CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE;
    CK_RC2_CBC_PARAMS rc2_params;
#if NSS_SOFTOKEN_DOES_RC5
    CK_RC5_CBC_PARAMS rc5_params;
    CK_RC5_MAC_GENERAL_PARAMS *rc5_mac;
#endif
    unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE];
    SFTKSessionContext *context;
    CK_RV crv;
    int blockSize;

    switch (pMechanism->mechanism) {
    case CKM_RC2_MAC_GENERAL:
       mac_bytes = 
           ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
       /* fall through */
    case CKM_RC2_MAC:
       /* this works because ulEffectiveBits is in the same place in both the
        * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */
       rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *)
                            pMechanism->pParameter)->ulEffectiveBits;
       PORT_Memset(rc2_params.iv,0,sizeof(rc2_params.iv));
       cbc_mechanism.mechanism = CKM_RC2_CBC;
       cbc_mechanism.pParameter = &rc2_params;
       cbc_mechanism.ulParameterLen = sizeof(rc2_params);
       blockSize = 8;
       break;
#if NSS_SOFTOKEN_DOES_RC5
    case CKM_RC5_MAC_GENERAL:
       mac_bytes = 
           ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
       /* fall through */
    case CKM_RC5_MAC:
       /* this works because ulEffectiveBits is in the same place in both the
        * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */
       rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter;
       rc5_params.ulWordsize = rc5_mac->ulWordsize;
       rc5_params.ulRounds = rc5_mac->ulRounds;
       rc5_params.pIv = ivBlock;
       blockSize = rc5_mac->ulWordsize*2;
       rc5_params.ulIvLen = blockSize;
       PORT_Memset(ivBlock,0,blockSize);
       cbc_mechanism.mechanism = CKM_RC5_CBC;
       cbc_mechanism.pParameter = &rc5_params;
       cbc_mechanism.ulParameterLen = sizeof(rc5_params);
       break;
#endif
    /* add cast and idea later */
    case CKM_DES_MAC_GENERAL:
       mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
       /* fall through */
    case CKM_DES_MAC:
       blockSize = 8;
       PORT_Memset(ivBlock,0,blockSize);
       cbc_mechanism.mechanism = CKM_DES_CBC;
       cbc_mechanism.pParameter = &ivBlock;
       cbc_mechanism.ulParameterLen = blockSize;
       break;
    case CKM_DES3_MAC_GENERAL:
       mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
       /* fall through */
    case CKM_DES3_MAC:
       blockSize = 8;
       PORT_Memset(ivBlock,0,blockSize);
       cbc_mechanism.mechanism = CKM_DES3_CBC;
       cbc_mechanism.pParameter = &ivBlock;
       cbc_mechanism.ulParameterLen = blockSize;
       break;
    case CKM_CDMF_MAC_GENERAL:
       mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
       /* fall through */
    case CKM_CDMF_MAC:
       blockSize = 8;
       PORT_Memset(ivBlock,0,blockSize);
       cbc_mechanism.mechanism = CKM_CDMF_CBC;
       cbc_mechanism.pParameter = &ivBlock;
       cbc_mechanism.ulParameterLen = blockSize;
       break;
    case CKM_AES_MAC_GENERAL:
       mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
       /* fall through */
    case CKM_AES_MAC:
       blockSize = 16;
       PORT_Memset(ivBlock,0,blockSize);
       cbc_mechanism.mechanism = CKM_AES_CBC;
       cbc_mechanism.pParameter = &ivBlock;
       cbc_mechanism.ulParameterLen = blockSize;
       break;
    default:
       return CKR_FUNCTION_NOT_SUPPORTED;
    }

    crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey, keyUsage,
                                                 contextType, PR_TRUE);
    if (crv != CKR_OK) return crv;
    crv = sftk_GetContext(hSession,&context,contextType,PR_TRUE,NULL);

    /* this shouldn't happen! */
    PORT_Assert(crv == CKR_OK);
    if (crv != CKR_OK) return crv;
    context->blockSize = blockSize;
    if (mac_bytes == SFTK_INVALID_MAC_SIZE) mac_bytes = blockSize/2;
    context->macSize = mac_bytes;
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_InitGeneric ( SFTKSession *  session,
SFTKSessionContext **  contextPtr,
SFTKContextType  ctype,
SFTKObject **  keyPtr,
CK_OBJECT_HANDLE  hKey,
CK_KEY_TYPE keyTypePtr,
CK_OBJECT_CLASS  pubKeyType,
CK_ATTRIBUTE_TYPE  operation 
) [static]

Definition at line 331 of file pkcs11c.c.

{
    SFTKObject *key = NULL;
    SFTKAttribute *att;
    SFTKSessionContext *context;

    /* We can only init if there is not current context active */
    if (sftk_ReturnContextByType(session,ctype) != NULL) {
       return CKR_OPERATION_ACTIVE;
    }

    /* find the key */
    if (keyPtr) {
        key = sftk_ObjectFromHandle(hKey,session);
        if (key == NULL) {
           return CKR_KEY_HANDLE_INVALID;
       }

       /* make sure it's a valid  key for this operation */
       if (((key->objclass != CKO_SECRET_KEY) && (key->objclass != pubKeyType))
                                   || !sftk_isTrue(key,operation)) {
           sftk_FreeObject(key);
           return CKR_KEY_TYPE_INCONSISTENT;
       }
       /* get the key type */
       att = sftk_FindAttribute(key,CKA_KEY_TYPE);
       if (att == NULL) {
           sftk_FreeObject(key);
           return CKR_KEY_TYPE_INCONSISTENT;
       }
       PORT_Assert(att->attrib.ulValueLen == sizeof(CK_KEY_TYPE));
       if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) {
           sftk_FreeAttribute(att);
           sftk_FreeObject(key);
           return CKR_ATTRIBUTE_VALUE_INVALID;
       }
       PORT_Memcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE));
       sftk_FreeAttribute(att);
       *keyPtr = key;
    }

    /* allocate the context structure */
    context = (SFTKSessionContext *)PORT_Alloc(sizeof(SFTKSessionContext));
    if (context == NULL) {
       if (key) sftk_FreeObject(key);
       return CKR_HOST_MEMORY;
    }
    context->type = ctype;
    context->multi = PR_TRUE;
    context->cipherInfo = NULL;
    context->hashInfo = NULL;
    context->doPad = PR_FALSE;
    context->padDataLength = 0;
    context->key = key;
    context->blockSize = 0;

    *contextPtr = context;
    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_MACUpdate ( CK_SESSION_HANDLE  hSession,
CK_BYTE_PTR  pPart,
CK_ULONG  ulPartLen,
SFTKContextType  type 
) [static]

Definition at line 1912 of file pkcs11c.c.

{
    unsigned int outlen;
    SFTKSessionContext *context;
    CK_RV crv;
    SECStatus rv;

    /* make sure we're legal */
    crv = sftk_GetContext(hSession,&context,type,PR_TRUE,NULL);
    if (crv != CKR_OK) return crv;

    if (context->hashInfo) {
       (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen);
       return CKR_OK;
    }

    /* must be block cipher macing */

    /* deal with previous buffered data */
    if (context->padDataLength != 0) {
       int i;
       /* fill in the padded to a full block size */
       for (i=context->padDataLength; (ulPartLen != 0) && 
                                   i < (int)context->blockSize; i++) {
           context->padBuf[i] = *pPart++;
           ulPartLen--;
           context->padDataLength++;
       }

       /* not enough data to encrypt yet? then return */
       if (context->padDataLength != context->blockSize)  return CKR_OK;
       /* encrypt the current padded data */
       rv = (*context->update)(context->cipherInfo,context->macBuf,&outlen,
                     SFTK_MAX_BLOCK_SIZE,context->padBuf,context->blockSize);
       if (rv != SECSuccess) return CKR_DEVICE_ERROR;
    }

    /* save the residual */
    context->padDataLength = ulPartLen % context->blockSize;
    if (context->padDataLength) {
       PORT_Memcpy(context->padBuf,
                  &pPart[ulPartLen-context->padDataLength],
                  context->padDataLength);
       ulPartLen -= context->padDataLength;
    }

    /* if we've exhausted our new buffer, we're done */
    if (ulPartLen == 0) { return CKR_OK; }

    /* run the data through out encrypter */     
    while (ulPartLen) {
       rv = (*context->update)(context->cipherInfo, context->padBuf, &outlen, 
                     SFTK_MAX_BLOCK_SIZE, pPart, context->blockSize);
       if (rv != SECSuccess) return CKR_DEVICE_ERROR;
       /* paranoia.. make sure we exit the loop */
       PORT_Assert(ulPartLen >= context->blockSize);
       if (ulPartLen < context->blockSize) break;
       ulPartLen -= context->blockSize;
    }

    return CKR_OK;
       
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned long sftk_MapKeySize ( CK_KEY_TYPE  keyType)

Definition at line 4626 of file pkcs11c.c.

{
    switch (keyType) {
    case CKK_CDMF:
       return 8;
    case CKK_DES:
       return 8;
    case CKK_DES2:
       return 16;
    case CKK_DES3:
       return 24;
    /* IDEA and CAST need to be added */
    default:
       break;
    }
    return 0;
}

Here is the caller graph for this function:

static CK_RV sftk_mapWrap ( CK_RV  crv) [static]

Definition at line 3987 of file pkcs11c.c.

{ 
    switch (crv) {
    case CKR_ENCRYPTED_DATA_INVALID:  crv = CKR_WRAPPED_KEY_INVALID; break;
    }
    return crv; 
}

Here is the caller graph for this function:

static void sftk_Null ( void data,
PRBool  freeit 
) [static]

Definition at line 94 of file pkcs11c.c.

{
    return;
} 

Here is the caller graph for this function:

static SECItem* sftk_PackagePrivateKey ( SFTKObject *  key,
CK_RV crvp 
) [static]

Definition at line 3834 of file pkcs11c.c.

{
    NSSLOWKEYPrivateKey *lk = NULL;
    NSSLOWKEYPrivateKeyInfo *pki = NULL;
    SFTKAttribute *attribute = NULL;
    PLArenaPool *arena = NULL;
    SECOidTag algorithm = SEC_OID_UNKNOWN;
    void *dummy, *param = NULL;
    SECStatus rv = SECSuccess;
    SECItem *encodedKey = NULL;
#ifdef NSS_ENABLE_ECC
    SECItem *fordebug;
    int savelen;
#endif

    if(!key) {
       *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */
       return NULL;
    }

    attribute = sftk_FindAttribute(key, CKA_KEY_TYPE);
    if(!attribute) {
       *crvp = CKR_KEY_TYPE_INCONSISTENT;
       return NULL;
    }

    lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp);
    sftk_FreeAttribute(attribute);
    if(!lk) {
       return NULL;
    }

    arena = PORT_NewArena(2048);   /* XXX different size? */
    if(!arena) {
       *crvp = CKR_HOST_MEMORY;
       rv = SECFailure;
       goto loser;
    }

    pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, 
                                   sizeof(NSSLOWKEYPrivateKeyInfo));
    if(!pki) {
       *crvp = CKR_HOST_MEMORY;
       rv = SECFailure;
       goto loser;
    }
    pki->arena = arena;

    param = NULL;
    switch(lk->keyType) {
       case NSSLOWKEYRSAKey:
           prepare_low_rsa_priv_key_for_asn1(lk);
           dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
                                   nsslowkey_RSAPrivateKeyTemplate);
           algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
           break;
       case NSSLOWKEYDSAKey:
            prepare_low_dsa_priv_key_export_for_asn1(lk);
           dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
                                   nsslowkey_DSAPrivateKeyExportTemplate);
           prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);
           param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
                                   nsslowkey_PQGParamsTemplate);
           algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
           break;
#ifdef NSS_ENABLE_ECC           
        case NSSLOWKEYECKey:
            prepare_low_ec_priv_key_for_asn1(lk);
           /* Public value is encoded as a bit string so adjust length
            * to be in bits before ASN encoding and readjust 
            * immediately after.
            *
            * Since the SECG specification recommends not including the
            * parameters as part of ECPrivateKey, we zero out the curveOID
            * length before encoding and restore it later.
            */
           lk->u.ec.publicValue.len <<= 3;
           savelen = lk->u.ec.ecParams.curveOID.len;
           lk->u.ec.ecParams.curveOID.len = 0;
           dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
                                   nsslowkey_ECPrivateKeyTemplate);
           lk->u.ec.ecParams.curveOID.len = savelen;
           lk->u.ec.publicValue.len >>= 3;

           fordebug = &pki->privateKey;
           SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
                    fordebug);

           param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);

           algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
           break;
#endif /* NSS_ENABLE_ECC */
       case NSSLOWKEYDHKey:
       default:
           dummy = NULL;
           break;
    }
 
    if(!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {
       *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
       rv = SECFailure;
       goto loser;
    }
    
    rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm, 
                            (SECItem*)param);
    if(rv != SECSuccess) {
       *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
       rv = SECFailure;
       goto loser;
    }

    dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
                              NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
    if(!dummy) {
       *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
       rv = SECFailure;
       goto loser;
    }

    encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki, 
                                nsslowkey_PrivateKeyInfoTemplate);
    *crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR;

#ifdef NSS_ENABLE_ECC
    fordebug = encodedKey;
    SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,
             fordebug);
#endif
loser:
    if(arena) {
       PORT_FreeArena(arena, PR_TRUE);
    }

    if(lk && (lk != key->objectInfo)) {
       nsslowkey_DestroyPrivateKey(lk);
    }
 
    if(param) {
       SECITEM_ZfreeItem((SECItem*)param, PR_TRUE);
    }

    if(rv != SECSuccess) {
       return NULL;
    }

    return encodedKey;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CK_RV sftk_PairwiseConsistencyCheck ( CK_SESSION_HANDLE  hSession,
SFTKObject *  publicKey,
SFTKObject *  privateKey,
CK_KEY_TYPE  keyType 
) [static]

Definition at line 3044 of file pkcs11c.c.

{
    /*
     *                      Key type    Mechanism type
     *                      --------------------------------
     * For encrypt/decrypt: CKK_RSA  => CKM_RSA_PKCS
     *                      others   => CKM_INVALID_MECHANISM
     *
     * For sign/verify:     CKK_RSA  => CKM_RSA_PKCS
     *                      CKK_DSA  => CKM_DSA
     *                      CKK_EC   => CKM_ECDSA
     *                      others   => CKM_INVALID_MECHANISM
     *
     * None of these mechanisms has a parameter.
     */
    CK_MECHANISM mech = {0, NULL, 0};

    CK_ULONG modulusLen;
    PRBool isEncryptable = PR_FALSE;
    PRBool canSignVerify = PR_FALSE;
    PRBool isDerivable = PR_FALSE;
    CK_RV crv;

    /* Variables used for Encrypt/Decrypt functions. */
    unsigned char *known_message = (unsigned char *)"Known Crypto Message";
    unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH];
    CK_ULONG bytes_decrypted;
    unsigned char *ciphertext;
    unsigned char *text_compared;
    CK_ULONG bytes_encrypted;
    CK_ULONG bytes_compared;

    /* Variables used for Signature/Verification functions. */
    /* always uses SHA-1 digest */
    unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!";
    unsigned char *signature;
    CK_ULONG signature_length;

    if (keyType == CKK_RSA) {
       SFTKAttribute *attribute;

       /* Get modulus length of private key. */
       attribute = sftk_FindAttribute(privateKey, CKA_MODULUS);
       if (attribute == NULL) {
           return CKR_DEVICE_ERROR;
       }
       modulusLen = attribute->attrib.ulValueLen;
       if (*(unsigned char *)attribute->attrib.pValue == 0) {
           modulusLen--;
       }
       sftk_FreeAttribute(attribute);
    }

    /**************************************************/
    /* Pairwise Consistency Check of Encrypt/Decrypt. */
    /**************************************************/

    isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT); 

    /*
     * If the decryption attribute is set, attempt to encrypt
     * with the public key and decrypt with the private key.
     */
    if (isEncryptable) {
       if (keyType != CKK_RSA) {
           return CKR_DEVICE_ERROR;
       }
       bytes_encrypted = modulusLen;
       mech.mechanism = CKM_RSA_PKCS;

       /* Allocate space for ciphertext. */
       ciphertext = (unsigned char *) PORT_ZAlloc(bytes_encrypted);
       if (ciphertext == NULL) {
           return CKR_HOST_MEMORY;
       }

       /* Prepare for encryption using the public key. */
       crv = NSC_EncryptInit(hSession, &mech, publicKey->handle);
       if (crv != CKR_OK) {
           PORT_Free(ciphertext);
           return crv;
       }

       /* Encrypt using the public key. */
       crv = NSC_Encrypt(hSession,
                       known_message,
                       PAIRWISE_MESSAGE_LENGTH,
                       ciphertext,
                       &bytes_encrypted);
       if (crv != CKR_OK) {
           PORT_Free(ciphertext);
           return crv;
       }

       /* Always use the smaller of these two values . . . */
       bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH);

       /*
        * If there was a failure, the plaintext
        * goes at the end, therefore . . .
        */
       text_compared = ciphertext + bytes_encrypted - bytes_compared;

       /*
        * Check to ensure that ciphertext does
        * NOT EQUAL known input message text
        * per FIPS PUB 140-2 directive.
        */
       if (PORT_Memcmp(text_compared, known_message,
                     bytes_compared) == 0) {
           /* Set error to Invalid PRIVATE Key. */
           PORT_SetError(SEC_ERROR_INVALID_KEY);
           PORT_Free(ciphertext);
           return CKR_GENERAL_ERROR;
       }

       /* Prepare for decryption using the private key. */
       crv = NSC_DecryptInit(hSession, &mech, privateKey->handle);
       if (crv != CKR_OK) {
           PORT_Free(ciphertext);
           return crv;
       }

       memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH);

       /*
        * Initialize bytes decrypted to be the
        * expected PAIRWISE_MESSAGE_LENGTH.
        */
       bytes_decrypted = PAIRWISE_MESSAGE_LENGTH;

       /*
        * Decrypt using the private key.
        * NOTE:  No need to reset the
        *        value of bytes_encrypted.
        */
       crv = NSC_Decrypt(hSession,
                       ciphertext,
                       bytes_encrypted,
                       plaintext,
                       &bytes_decrypted);

       /* Finished with ciphertext; free it. */
       PORT_Free(ciphertext);

       if (crv != CKR_OK) {
           return crv;
       }

       /*
        * Check to ensure that the output plaintext
        * does EQUAL known input message text.
        */
       if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH) ||
           (PORT_Memcmp(plaintext, known_message,
                      PAIRWISE_MESSAGE_LENGTH) != 0)) {
           /* Set error to Bad PUBLIC Key. */
           PORT_SetError(SEC_ERROR_BAD_KEY);
           return CKR_GENERAL_ERROR;
       }
    }

    /**********************************************/
    /* Pairwise Consistency Check of Sign/Verify. */
    /**********************************************/

    canSignVerify = sftk_isTrue(privateKey, CKA_SIGN);
    
    if (canSignVerify) {
       /* Determine length of signature. */
       switch (keyType) {
       case CKK_RSA:
           signature_length = modulusLen;
           mech.mechanism = CKM_RSA_PKCS;
           break;
       case CKK_DSA:
           signature_length = DSA_SIGNATURE_LEN;
           mech.mechanism = CKM_DSA;
           break;
#ifdef NSS_ENABLE_ECC
       case CKK_EC:
           signature_length = MAX_ECKEY_LEN * 2;
           mech.mechanism = CKM_ECDSA;
           break;
#endif
       default:
           return CKR_DEVICE_ERROR;
       }
       
       /* Allocate space for signature data. */
       signature = (unsigned char *) PORT_ZAlloc(signature_length);
       if (signature == NULL) {
           return CKR_HOST_MEMORY;
       }
       
       /* Sign the known hash using the private key. */
       crv = NSC_SignInit(hSession, &mech, privateKey->handle);
       if (crv != CKR_OK) {
           PORT_Free(signature);
           return crv;
       }

       crv = NSC_Sign(hSession,
                     known_digest,
                     PAIRWISE_DIGEST_LENGTH,
                     signature,
                     &signature_length);
       if (crv != CKR_OK) {
           PORT_Free(signature);
           return crv;
       }
       
       /* Verify the known hash using the public key. */
       crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
       if (crv != CKR_OK) {
           PORT_Free(signature);
           return crv;
       }

       crv = NSC_Verify(hSession,
                      known_digest,
                      PAIRWISE_DIGEST_LENGTH,
                      signature,
                      signature_length);

       /* Free signature data. */
       PORT_Free(signature);

       if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
              (crv == CKR_SIGNATURE_INVALID)) {
           return CKR_GENERAL_ERROR;
       }
       if (crv != CKR_OK) {
           return crv;
       }
    }

    /**********************************************/
    /* Pairwise Consistency Check for Derivation  */
    /**********************************************/

    isDerivable = sftk_isTrue(privateKey, CKA_DERIVE);
    
    if (isDerivable) {
       /* 
        * We are not doing consistency check for Diffie-Hellman Key - 
        * otherwise it would be here
        * This is also true for Elliptic Curve Diffie-Hellman keys
        * NOTE: EC keys are currently subjected to pairwise
        * consistency check for signing/verification.
        */
       /*
        * FIPS 140-2 had the following pairwise consistency test for
        * public and private keys used for key agreement:
        *   If the keys are used to perform key agreement, then the
        *   cryptographic module shall create a second, compatible
        *   key pair.  The cryptographic module shall perform both
        *   sides of the key agreement algorithm and shall compare
        *   the resulting shared values.  If the shared values are
        *   not equal, the test shall fail.
        * This test was removed in Change Notice 3.
        */

    }

    return CKR_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SFTKSessionContext* sftk_ReturnContextByType ( SFTKSession *  session,
SFTKContextType  type 
)

Definition at line 249 of file pkcs11c.c.

{
    switch (type) {
       case SFTK_ENCRYPT:
       case SFTK_DECRYPT:
           return session->enc_context;
       case SFTK_HASH:
           return session->hash_context;
       case SFTK_SIGN:
       case SFTK_SIGN_RECOVER:
       case SFTK_VERIFY:
       case SFTK_VERIFY_RECOVER:
           return session->hash_context;
    }
    return NULL;
}

Here is the caller graph for this function:

void sftk_SetContextByType ( SFTKSession *  session,
SFTKContextType  type,
SFTKSessionContext *  context 
)

Definition at line 270 of file pkcs11c.c.

{
    switch (type) {
       case SFTK_ENCRYPT:
       case SFTK_DECRYPT:
           session->enc_context = context;
           break;
       case SFTK_HASH:
           session->hash_context = context;
           break;
       case SFTK_SIGN:
       case SFTK_SIGN_RECOVER:
       case SFTK_VERIFY:
       case SFTK_VERIFY_RECOVER:
           session->hash_context = context;
           break;
    }
    return;
}

Here is the caller graph for this function:

static void sftk_Space ( void data,
PRBool  freeit 
) [static]

Definition at line 126 of file pkcs11c.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus sftk_SSLMACSign ( SFTKSSLMACInfo *  info,
unsigned char *  sig,
unsigned int sigLen,
unsigned int  maxLen,
unsigned char *  hash,
unsigned int  hashLen 
) [static]

Definition at line 1383 of file pkcs11c.c.

{
    unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
    unsigned int out;

    info->begin(info->hashContext);
    info->update(info->hashContext,info->key,info->keySize);
    info->update(info->hashContext,ssl_pad_2,info->padSize);
    info->update(info->hashContext,hash,hashLen);
    info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH);
    PORT_Memcpy(sig,tmpBuf,info->macSize);
    *sigLen = info->macSize;
    return SECSuccess;
}

Here is the caller graph for this function:

static SECStatus sftk_SSLMACVerify ( SFTKSSLMACInfo *  info,
unsigned char *  sig,
unsigned int  sigLen,
unsigned char *  hash,
unsigned int  hashLen 
) [static]

Definition at line 1400 of file pkcs11c.c.

{
    unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
    unsigned int out;

    info->begin(info->hashContext);
    info->update(info->hashContext,info->key,info->keySize);
    info->update(info->hashContext,ssl_pad_2,info->padSize);
    info->update(info->hashContext,hash,hashLen);
    info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH);
    return (PORT_Memcmp(sig,tmpBuf,info->macSize) == 0) ? 
                                          SECSuccess : SECFailure;
}

Here is the caller graph for this function:

static SECStatus sftk_unwrapPrivateKey ( SFTKObject *  key,
SECItem *  bpki 
) [static]

Definition at line 4129 of file pkcs11c.c.

{
    CK_BBOOL cktrue = CK_TRUE; 
    CK_KEY_TYPE keyType = CKK_RSA;
    SECStatus rv = SECFailure;
    const SEC_ASN1Template *keyTemplate, *paramTemplate;
    void *paramDest = NULL;
    PLArenaPool *arena;
    NSSLOWKEYPrivateKey *lpk = NULL;
    NSSLOWKEYPrivateKeyInfo *pki = NULL;
    CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;

    arena = PORT_NewArena(2048);
    if(!arena) {
       return SECFailure;
    }

    pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, 
                                   sizeof(NSSLOWKEYPrivateKeyInfo));
    if(!pki) {
       PORT_FreeArena(arena, PR_FALSE);
       return SECFailure;
    }

    if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) 
                            != SECSuccess) {
       PORT_FreeArena(arena, PR_TRUE);
       return SECFailure;
    }

    lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena,
                                            sizeof(NSSLOWKEYPrivateKey));
    if(lpk == NULL) {
       goto loser;
    }
    lpk->arena = arena;

    switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
           keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
           paramTemplate = NULL;
           paramDest = NULL;
           lpk->keyType = NSSLOWKEYRSAKey;
           prepare_low_rsa_priv_key_for_asn1(lpk);
           break;
       case SEC_OID_ANSIX9_DSA_SIGNATURE:
           keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
           paramTemplate = nsslowkey_PQGParamsTemplate;
           paramDest = &(lpk->u.dsa.params);
           lpk->keyType = NSSLOWKEYDSAKey;
           prepare_low_dsa_priv_key_export_for_asn1(lpk);
           prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params);
           break;
       /* case NSSLOWKEYDHKey: */
#ifdef NSS_ENABLE_ECC
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
           keyTemplate = nsslowkey_ECPrivateKeyTemplate;
           paramTemplate = NULL;
           paramDest = &(lpk->u.ec.ecParams.DEREncoding);
           lpk->keyType = NSSLOWKEYECKey;
           prepare_low_ec_priv_key_for_asn1(lpk);
           prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams);
           break;
#endif /* NSS_ENABLE_ECC */
       default:
           keyTemplate = NULL;
           paramTemplate = NULL;
           paramDest = NULL;
           break;
    }

    if(!keyTemplate) {
       goto loser;
    }

    /* decode the private key and any algorithm parameters */
    rv =