OPENSSL_assert(keylen <= sizeof key);
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,                         ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md,                         int en_de){	unsigned char *pbuf, *salt, key[EVP_MAX_KEY_LENGTH];	int saltlen, keylen, iter, plen;	PBE2PARAM *pbe2 = NULL;	const EVP_CIPHER *cipher;	PBKDF2PARAM *kdf = NULL;	pbuf = param->value.sequence->data;	plen = param->value.sequence->length;	if(!param || (param->type != V_ASN1_SEQUENCE) ||				   !(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);		return 0;	}	/* See if we recognise the key derivation function */	if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,				EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);		goto err;	}	/* lets see if we recognise the encryption algorithm.	 */	cipher = EVP_get_cipherbyname(			OBJ_nid2sn(OBJ_obj2nid(pbe2->encryption->algorithm)));	if(!cipher) {		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,						EVP_R_UNSUPPORTED_CIPHER);		goto err;	}	/* Fixup cipher based on AlgorithmIdentifier */	EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de);	if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,					EVP_R_CIPHER_PARAMETER_ERROR);		goto err;	}	keylen = EVP_CIPHER_CTX_key_length(ctx);	/* Now decode key derivation function */	pbuf = pbe2->keyfunc->parameter->value.sequence->data;	plen = pbe2->keyfunc->parameter->value.sequence->length;	if(!pbe2->keyfunc->parameter ||		 (pbe2->keyfunc->parameter->type != V_ASN1_SEQUENCE) ||				!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);		goto err;	}	PBE2PARAM_free(pbe2);	pbe2 = NULL;	/* Now check the parameters of the kdf */	if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != keylen)){		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,						EVP_R_UNSUPPORTED_KEYLENGTH);		goto err;	}	if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) {		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);		goto err;	}	if(kdf->salt->type != V_ASN1_OCTET_STRING) {		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,						EVP_R_UNSUPPORTED_SALT_TYPE);		goto err;	}	/* it seems that its all OK */	salt = kdf->salt->value.octet_string->data;	saltlen = kdf->salt->value.octet_string->length;	iter = ASN1_INTEGER_get(kdf->iter);	PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key);	EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);	memset(key, 0, keylen);	PBKDF2PARAM_free(kdf);	return 1;	err:	PBE2PARAM_free(pbe2);	PBKDF2PARAM_free(kdf);	return 0;}