if (crv != CKR_OK) {
if ((crv != CKR_OK) && (crv != CKR_DEVICE_ERROR)) {
pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,    CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey,     CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize,     void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs){    PK11SymKey *    symKey;    SECItem *       param_free	= NULL;    CK_BBOOL        ckfalse	= CK_FALSE;     CK_BBOOL        cktrue	= CK_TRUE;     CK_OBJECT_CLASS keyClass	= CKO_SECRET_KEY;    CK_KEY_TYPE     keyType	= CKK_GENERIC_SECRET;    CK_ULONG        valueLen	= 0;    CK_MECHANISM    mechanism;    CK_RV           crv;    CK_MECHANISM_INFO mechanism_info;    CK_ATTRIBUTE    keyTemplate[MAX_TEMPL_ATTRS];    CK_ATTRIBUTE *  attrs	= keyTemplate;    unsigned int    templateCount;    if (numAttrs > MAX_TEMPL_ATTRS) {    	PORT_SetError(SEC_ERROR_INVALID_ARGS);	return NULL;    }    /* first copy caller attributes in. */    for (templateCount = 0; templateCount < numAttrs; ++templateCount) {    	*attrs++ = *userAttr++;    }    /* We only add the following attributes to the template if the caller    ** didn't already supply them.    */    if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) {	PK11_SETATTRS(attrs, CKA_CLASS,     &keyClass, sizeof keyClass); 	attrs++;    }    if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) {	keyType = PK11_GetKeyType(target, keySize);	PK11_SETATTRS(attrs, CKA_KEY_TYPE,  &keyType,  sizeof keyType ); 	attrs++;    }    if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) {	PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;    }    /*     * must be last in case we need to use this template to import the key     */    if (keySize > 0 &&    	  !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) {	valueLen = (CK_ULONG)keySize;	PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen); 	attrs++;    }    templateCount = attrs - keyTemplate;    PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));    /* find out if we can do wrap directly. Because the RSA case if *very*     * common, cache the results for it. */    if ((wrapType == CKM_RSA_PKCS) && (slot->hasRSAInfo)) {	mechanism_info.flags = slot->RSAInfoFlags;    } else {	if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);	crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,wrapType,				 &mechanism_info);    	if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);    	if (crv != CKR_OK) {	     mechanism_info.flags = 0;    	}        if (wrapType == CKM_RSA_PKCS) {	    slot->RSAInfoFlags = mechanism_info.flags;	    slot->hasRSAInfo = PR_TRUE;	}    }    /* initialize the mechanism structure */    mechanism.mechanism = wrapType;    /* use NULL IV's for wrapping */    if (param == NULL) param = param_free = PK11_ParamFromIV(wrapType,NULL);    if (param) {	mechanism.pParameter = param->data;	mechanism.ulParameterLen = param->len;    } else {	mechanism.pParameter = NULL;	mechanism.ulParameterLen = 0;    }    if ((mechanism_info.flags & CKF_DECRYPT)  				&& !PK11_DoesMechanism(slot,target)) {	symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, 	                         target, keyTemplate, templateCount, keySize, 				 wincx);	if (symKey) {	    if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);	    return symKey;	}	/* fall through, maybe they incorrectly set CKF_DECRYPT */    }    /* get our key Structure */    symKey = PK11_CreateSymKey(slot,target,wincx);    if (symKey == NULL) {	if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);	return NULL;    }    symKey->size = keySize;    symKey->origin = PK11_OriginUnwrap;    pk11_EnterKeyMonitor(symKey);    crv = PK11_GETTAB(slot)->C_UnwrapKey(symKey->session,&mechanism,wrappingKey,		wrappedKey->data, wrappedKey->len, keyTemplate, templateCount, 							  &symKey->objectID);    pk11_ExitKeyMonitor(symKey);    if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);    if (crv != CKR_OK) {	/* try hand Unwrapping */	PK11_FreeSymKey(symKey);	symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, 	                         target, keyTemplate, templateCount, keySize, 				 wincx);   }   return symKey;}