if(enc && (enc != -1)) enc = 1;
if (enc == -1) enc = ctx->encrypt; else { if (enc) enc = 1; ctx->encrypt = enc; }
int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,	     const unsigned char *key, const unsigned char *iv, int enc)	{	if(enc && (enc != -1)) enc = 1;	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts	 * so this context may already have an ENGINE! Try to avoid releasing	 * the previous handle, re-querying for an ENGINE, and having a	 * reinitialisation, when it may all be unecessary. */	if (ctx->engine && ctx->cipher && (!cipher ||			(cipher && (cipher->nid == ctx->cipher->nid))))		goto skip_to_init;	if (cipher)		{		/* Ensure an ENGINE left lying around from last time is cleared		 * (the previous check attempted to avoid this if the same		 * ENGINE and EVP_CIPHER could be used). */		if(ctx->engine)			ENGINE_finish(ctx->engine);		if(impl)			{			if (!ENGINE_init(impl))				{				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);				return 0;				}			}		else			/* Ask if an ENGINE is reserved for this job */			impl = ENGINE_get_cipher_engine(cipher->nid);		if(impl)			{			/* There's an ENGINE for this job ... (apparently) */			const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);			if(!c)				{				/* One positive side-effect of US's export				 * control history, is that we should at least				 * be able to avoid using US mispellings of				 * "initialisation"? */				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);				return 0;				}			/* We'll use the ENGINE's private cipher definition */			cipher = c;			/* Store the ENGINE functional reference so we know			 * 'cipher' came from an ENGINE and we need to release			 * it when done. */			ctx->engine = impl;			}		else			ctx->engine = NULL;		ctx->cipher=cipher;		ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);		ctx->key_len = cipher->key_len;		ctx->flags = 0;		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)			{			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))				{				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);				return 0;				}			}		}	else if(!ctx->cipher)		{		EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET);		return 0;		}skip_to_init:	/* we assume block size is a power of 2 in *cryptUpdate */	assert(ctx->cipher->block_size == 1	       || ctx->cipher->block_size == 8	       || ctx->cipher->block_size == 16);	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {		switch(EVP_CIPHER_CTX_mode(ctx)) {			case EVP_CIPH_STREAM_CIPHER:			case EVP_CIPH_ECB_MODE:			break;			case EVP_CIPH_CFB_MODE:			case EVP_CIPH_OFB_MODE:			ctx->num = 0;			case EVP_CIPH_CBC_MODE:			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));			break;			default:			return 0;			break;		}	}	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;	}	if(enc != -1) ctx->encrypt=enc;	ctx->buf_len=0;	ctx->final_used=0;	ctx->block_mask=ctx->cipher->block_size-1;	return 1;	}