context->multi = PR_FALSE;
CK_RV NSC_SignInit(CK_SESSION_HANDLE hSession,		 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey){    PK11Session *session;    PK11Object *key;    PK11SessionContext *context;    CK_KEY_TYPE key_type;    CK_RV crv = CKR_OK;    NSSLOWKEYPrivateKey *privKey;    PK11HashSignInfo *info = NULL;    /* Block Cipher MACing Algorithms use a different Context init method..*/    crv = pk11_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, PK11_SIGN);    if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;    /* we're not using a block cipher mac */    session = pk11_SessionFromHandle(hSession);    if (session == NULL) return CKR_SESSION_HANDLE_INVALID;    crv = pk11_InitGeneric(session,&context,PK11_SIGN,&key,hKey,&key_type,						CKO_PRIVATE_KEY,CKA_SIGN);    if (crv != CKR_OK) {	pk11_FreeSession(session);	return crv;    }    context->multi = PR_FALSE;#define INIT_RSA_SIGN_MECH(mmm) \    case CKM_ ## mmm ## _RSA_PKCS: \        context->multi = PR_TRUE; \	crv = pk11_doSub ## mmm (context); \	if (crv != CKR_OK) break; \	context->update = (PK11Cipher) pk11_HashSign; \	info = PORT_New(PK11HashSignInfo); \	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 = (PK11Cipher) RSA_Sign;	goto finish_rsa;    case CKM_RSA_X_509:	context->update = (PK11Cipher)  RSA_SignRaw;finish_rsa:	if (key_type != CKK_RSA) {	    if (info) PORT_Free(info);	    crv = CKR_KEY_TYPE_INCONSISTENT;	    break;	}	context->multi = PR_FALSE;	privKey = pk11_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 = (PK11Destroy)pk11_Space;	} else {	    context->cipherInfo = privKey;	    context->destroy = (PK11Destroy)pk11_Null;	}	context->maxLen = nsslowkey_PrivateModulusLen(privKey);	break;    case CKM_DSA_SHA1:        context->multi = PR_TRUE;	crv = pk11_doSubSHA1(context);	if (crv != CKR_OK) break;	/* fall through */    case CKM_DSA:	if (key_type != CKK_DSA) {	    crv = CKR_KEY_TYPE_INCONSISTENT;	    break;	}	privKey = pk11_GetPrivKey(key,CKK_DSA,&crv);	if (privKey == NULL) {	    break;	}	context->cipherInfo = privKey;	context->update     = (PK11Cipher) nsc_DSA_Sign_Stub;	context->destroy    = (privKey == key->objectInfo) ?		(PK11Destroy) pk11_Null:(PK11Destroy)pk11_FreePrivKey;	context->maxLen     = DSA_SIGNATURE_LEN;	break;#ifdef NSS_ENABLE_ECC    case CKM_ECDSA_SHA1:	context->multi = PR_TRUE;	crv = pk11_doSubSHA1(context);	if (crv != CKR_OK) break;	/* fall through */    case CKM_ECDSA:	if (key_type != CKK_EC) {	    crv = CKR_KEY_TYPE_INCONSISTENT;	    break;	}	privKey = pk11_GetPrivKey(key,CKK_EC,&crv);	if (privKey == NULL) {	    crv = CKR_HOST_MEMORY;	    break;	}	context->cipherInfo = privKey;	context->update     = (PK11Cipher) nsc_ECDSASignStub;	context->destroy    = (privKey == key->objectInfo) ?		(PK11Destroy) pk11_Null:(PK11Destroy)pk11_FreePrivKey;	context->maxLen     = MAX_ECKEY_LEN * 2;	break;#endif /* NSS_ENABLE_ECC */#define INIT_HMAC_MECH(mmm) \    case CKM_ ## mmm ## _HMAC_GENERAL: \	crv = pk11_doHMACInit(context, HASH_Alg ## mmm ,key, \				*(CK_ULONG *)pMechanism->pParameter); \	break; \    case CKM_ ## mmm ## _HMAC: \	crv = pk11_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 = pk11_doHMACInit(context,HASH_AlgSHA1,key,				*(CK_ULONG *)pMechanism->pParameter);	break;    case CKM_SHA_1_HMAC:	crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);	break;    case CKM_SSL3_MD5_MAC:	crv = pk11_doSSLMACInit(context,SEC_OID_MD5,key,					*(CK_ULONG *)pMechanism->pParameter);	break;    case CKM_SSL3_SHA1_MAC:	crv = pk11_doSSLMACInit(context,SEC_OID_SHA1,key,					*(CK_ULONG *)pMechanism->pParameter);	break;    case CKM_TLS_PRF_GENERAL:	crv = pk11_TLSPRFInit(context, key, key_type);	break;    default:	crv = CKR_MECHANISM_INVALID;	break;    }    if (crv != CKR_OK) {        pk11_FreeContext(context);	pk11_FreeSession(session);	return crv;    }    pk11_SetContextByType(session, PK11_SIGN, context);    pk11_FreeSession(session);    return CKR_OK;}