evp_enc.c revision 111147
155714Skris/* crypto/evp/evp_enc.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/evp.h>
6268651Skris#include <openssl/err.h>
63111147Snectar#ifndef OPENSSL_NO_ENGINE
64109998Smarkm#include <openssl/engine.h>
65111147Snectar#endif
6668651Skris#include "evp_locl.h"
6755714Skris
6855714Skrisconst char *EVP_version="EVP" OPENSSL_VERSION_PTEXT;
6955714Skris
7055714Skrisvoid EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
7155714Skris	{
7255714Skris	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
7355714Skris	/* ctx->cipher=NULL; */
7455714Skris	}
7555714Skris
76109998Smarkm
7768651Skrisint EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
78109998Smarkm	     const unsigned char *key, const unsigned char *iv, int enc)
7955714Skris	{
80109998Smarkm	if (cipher)
81109998Smarkm		EVP_CIPHER_CTX_init(ctx);
82109998Smarkm	return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
83109998Smarkm	}
84109998Smarkm
85109998Smarkmint EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
86109998Smarkm	     const unsigned char *key, const unsigned char *iv, int enc)
87109998Smarkm	{
88109998Smarkm	if (enc == -1)
89109998Smarkm		enc = ctx->encrypt;
90109998Smarkm	else
91109998Smarkm		{
92109998Smarkm		if (enc)
93109998Smarkm			enc = 1;
94109998Smarkm		ctx->encrypt = enc;
95109998Smarkm		}
96111147Snectar#ifndef OPENSSL_NO_ENGINE
97109998Smarkm	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
98109998Smarkm	 * so this context may already have an ENGINE! Try to avoid releasing
99109998Smarkm	 * the previous handle, re-querying for an ENGINE, and having a
100109998Smarkm	 * reinitialisation, when it may all be unecessary. */
101109998Smarkm	if (ctx->engine && ctx->cipher && (!cipher ||
102109998Smarkm			(cipher && (cipher->nid == ctx->cipher->nid))))
103109998Smarkm		goto skip_to_init;
104111147Snectar#endif
105109998Smarkm	if (cipher)
106109998Smarkm		{
107109998Smarkm		/* Ensure a context left lying around from last time is cleared
108109998Smarkm		 * (the previous check attempted to avoid this if the same
109109998Smarkm		 * ENGINE and EVP_CIPHER could be used). */
110109998Smarkm		EVP_CIPHER_CTX_cleanup(ctx);
111109998Smarkm
112109998Smarkm		/* Restore encrypt field: it is zeroed by cleanup */
113109998Smarkm		ctx->encrypt = enc;
114111147Snectar#ifndef OPENSSL_NO_ENGINE
115109998Smarkm		if(impl)
116109998Smarkm			{
117109998Smarkm			if (!ENGINE_init(impl))
118109998Smarkm				{
119109998Smarkm				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
120109998Smarkm				return 0;
121109998Smarkm				}
122109998Smarkm			}
123109998Smarkm		else
124109998Smarkm			/* Ask if an ENGINE is reserved for this job */
125109998Smarkm			impl = ENGINE_get_cipher_engine(cipher->nid);
126109998Smarkm		if(impl)
127109998Smarkm			{
128109998Smarkm			/* There's an ENGINE for this job ... (apparently) */
129109998Smarkm			const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
130109998Smarkm			if(!c)
131109998Smarkm				{
132109998Smarkm				/* One positive side-effect of US's export
133109998Smarkm				 * control history, is that we should at least
134109998Smarkm				 * be able to avoid using US mispellings of
135109998Smarkm				 * "initialisation"? */
136109998Smarkm				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
137109998Smarkm				return 0;
138109998Smarkm				}
139109998Smarkm			/* We'll use the ENGINE's private cipher definition */
140109998Smarkm			cipher = c;
141109998Smarkm			/* Store the ENGINE functional reference so we know
142109998Smarkm			 * 'cipher' came from an ENGINE and we need to release
143109998Smarkm			 * it when done. */
144109998Smarkm			ctx->engine = impl;
145109998Smarkm			}
146109998Smarkm		else
147109998Smarkm			ctx->engine = NULL;
148111147Snectar#endif
149109998Smarkm
15068651Skris		ctx->cipher=cipher;
151109998Smarkm		ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
15268651Skris		ctx->key_len = cipher->key_len;
153109998Smarkm		ctx->flags = 0;
154109998Smarkm		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
155109998Smarkm			{
156109998Smarkm			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
157109998Smarkm				{
15868651Skris				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
15968651Skris				return 0;
160109998Smarkm				}
16168651Skris			}
16268651Skris		}
163109998Smarkm	else if(!ctx->cipher)
164109998Smarkm		{
16568651Skris		EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET);
16668651Skris		return 0;
167109998Smarkm		}
168111147Snectar#ifndef OPENSSL_NO_ENGINE
169109998Smarkmskip_to_init:
170111147Snectar#endif
171109998Smarkm	/* we assume block size is a power of 2 in *cryptUpdate */
172109998Smarkm	OPENSSL_assert(ctx->cipher->block_size == 1
173109998Smarkm	    || ctx->cipher->block_size == 8
174109998Smarkm	    || ctx->cipher->block_size == 16);
175109998Smarkm
17668651Skris	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
17768651Skris		switch(EVP_CIPHER_CTX_mode(ctx)) {
17855714Skris
17968651Skris			case EVP_CIPH_STREAM_CIPHER:
18068651Skris			case EVP_CIPH_ECB_MODE:
18168651Skris			break;
18268651Skris
18368651Skris			case EVP_CIPH_CFB_MODE:
18468651Skris			case EVP_CIPH_OFB_MODE:
18568651Skris
18668651Skris			ctx->num = 0;
18768651Skris
18868651Skris			case EVP_CIPH_CBC_MODE:
18968651Skris
190109998Smarkm			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof ctx->iv);
19168651Skris			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
19268651Skris			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
19368651Skris			break;
19468651Skris
19568651Skris			default:
19668651Skris			return 0;
19768651Skris			break;
19868651Skris		}
19968651Skris	}
20068651Skris
20168651Skris	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
20268651Skris		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
20368651Skris	}
20468651Skris	ctx->buf_len=0;
205109998Smarkm	ctx->final_used=0;
206109998Smarkm	ctx->block_mask=ctx->cipher->block_size-1;
20768651Skris	return 1;
20868651Skris	}
20968651Skris
21068651Skrisint EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
211109998Smarkm	     const unsigned char *in, int inl)
21255714Skris	{
21355714Skris	if (ctx->encrypt)
21468651Skris		return EVP_EncryptUpdate(ctx,out,outl,in,inl);
21568651Skris	else	return EVP_DecryptUpdate(ctx,out,outl,in,inl);
21655714Skris	}
21755714Skris
218109998Smarkmint EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
219109998Smarkm	{
220109998Smarkm	if (ctx->encrypt)
221109998Smarkm		return EVP_EncryptFinal_ex(ctx,out,outl);
222109998Smarkm	else	return EVP_DecryptFinal_ex(ctx,out,outl);
223109998Smarkm	}
224109998Smarkm
22555714Skrisint EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
22655714Skris	{
22755714Skris	if (ctx->encrypt)
22868651Skris		return EVP_EncryptFinal(ctx,out,outl);
229109998Smarkm	else	return EVP_DecryptFinal(ctx,out,outl);
23055714Skris	}
23155714Skris
23268651Skrisint EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
233109998Smarkm	     const unsigned char *key, const unsigned char *iv)
23455714Skris	{
23568651Skris	return EVP_CipherInit(ctx, cipher, key, iv, 1);
23655714Skris	}
23755714Skris
238109998Smarkmint EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
239109998Smarkm		const unsigned char *key, const unsigned char *iv)
240109998Smarkm	{
241109998Smarkm	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
242109998Smarkm	}
243109998Smarkm
24468651Skrisint EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
245109998Smarkm	     const unsigned char *key, const unsigned char *iv)
24655714Skris	{
247111147Snectar	return EVP_CipherInit(ctx, cipher, key, iv, 0);
24855714Skris	}
24955714Skris
250109998Smarkmint EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
251109998Smarkm	     const unsigned char *key, const unsigned char *iv)
252109998Smarkm	{
253109998Smarkm	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
254109998Smarkm	}
25555714Skris
25668651Skrisint EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
257109998Smarkm	     const unsigned char *in, int inl)
25855714Skris	{
25955714Skris	int i,j,bl;
26055714Skris
261109998Smarkm	OPENSSL_assert(inl > 0);
262109998Smarkm	if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
263109998Smarkm		{
264109998Smarkm		if(ctx->cipher->do_cipher(ctx,out,in,inl))
265109998Smarkm			{
266109998Smarkm			*outl=inl;
267109998Smarkm			return 1;
268109998Smarkm			}
269109998Smarkm		else
270109998Smarkm			{
271109998Smarkm			*outl=0;
272109998Smarkm			return 0;
273109998Smarkm			}
274109998Smarkm		}
27555714Skris	i=ctx->buf_len;
27655714Skris	bl=ctx->cipher->block_size;
277109998Smarkm	OPENSSL_assert(bl <= sizeof ctx->buf);
27855714Skris	if (i != 0)
27955714Skris		{
28055714Skris		if (i+inl < bl)
28155714Skris			{
28255714Skris			memcpy(&(ctx->buf[i]),in,inl);
28355714Skris			ctx->buf_len+=inl;
284109998Smarkm			*outl=0;
28568651Skris			return 1;
28655714Skris			}
28755714Skris		else
28855714Skris			{
28955714Skris			j=bl-i;
290109998Smarkm			memcpy(&(ctx->buf[i]),in,j);
29168651Skris			if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
29255714Skris			inl-=j;
29355714Skris			in+=j;
29455714Skris			out+=bl;
295109998Smarkm			*outl=bl;
29655714Skris			}
29755714Skris		}
298109998Smarkm	else
299109998Smarkm		*outl = 0;
300109998Smarkm	i=inl&(bl-1);
30155714Skris	inl-=i;
30255714Skris	if (inl > 0)
30355714Skris		{
30468651Skris		if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
30555714Skris		*outl+=inl;
30655714Skris		}
30755714Skris
30855714Skris	if (i != 0)
30955714Skris		memcpy(ctx->buf,&(in[inl]),i);
31055714Skris	ctx->buf_len=i;
31168651Skris	return 1;
31255714Skris	}
31355714Skris
31468651Skrisint EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
31555714Skris	{
316109998Smarkm	int ret;
317109998Smarkm	ret = EVP_EncryptFinal_ex(ctx, out, outl);
318109998Smarkm	return ret;
319109998Smarkm	}
32055714Skris
321109998Smarkmint EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
322109998Smarkm	{
323109998Smarkm	int i,n,b,bl,ret;
324109998Smarkm
32555714Skris	b=ctx->cipher->block_size;
326109998Smarkm	OPENSSL_assert(b <= sizeof ctx->buf);
32755714Skris	if (b == 1)
32855714Skris		{
32955714Skris		*outl=0;
33068651Skris		return 1;
33155714Skris		}
33255714Skris	bl=ctx->buf_len;
333109998Smarkm	if (ctx->flags & EVP_CIPH_NO_PADDING)
334109998Smarkm		{
335109998Smarkm		if(bl)
336109998Smarkm			{
337109998Smarkm			EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
338109998Smarkm			return 0;
339109998Smarkm			}
340109998Smarkm		*outl = 0;
341109998Smarkm		return 1;
342109998Smarkm		}
343109998Smarkm
34455714Skris	n=b-bl;
34555714Skris	for (i=bl; i<b; i++)
34655714Skris		ctx->buf[i]=n;
347109998Smarkm	ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
348109998Smarkm
349109998Smarkm
350109998Smarkm	if(ret)
351109998Smarkm		*outl=b;
352109998Smarkm
353109998Smarkm	return ret;
35455714Skris	}
35555714Skris
35668651Skrisint EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
357109998Smarkm	     const unsigned char *in, int inl)
35855714Skris	{
359109998Smarkm	int b, fix_len;
36055714Skris
361109998Smarkm	if (inl == 0)
362109998Smarkm		{
363109998Smarkm		*outl=0;
364109998Smarkm		return 1;
365109998Smarkm		}
36655714Skris
367109998Smarkm	if (ctx->flags & EVP_CIPH_NO_PADDING)
368109998Smarkm		return EVP_EncryptUpdate(ctx, out, outl, in, inl);
369109998Smarkm
37055714Skris	b=ctx->cipher->block_size;
371109998Smarkm	OPENSSL_assert(b <= sizeof ctx->final);
372109998Smarkm
373109998Smarkm	if(ctx->final_used)
37455714Skris		{
375109998Smarkm		memcpy(out,ctx->final,b);
376109998Smarkm		out+=b;
377109998Smarkm		fix_len = 1;
37855714Skris		}
379109998Smarkm	else
380109998Smarkm		fix_len = 0;
38155714Skris
382109998Smarkm
383109998Smarkm	if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
384109998Smarkm		return 0;
385109998Smarkm
38655714Skris	/* if we have 'decrypted' a multiple of block size, make sure
38755714Skris	 * we have a copy of this last block */
388109998Smarkm	if (b > 1 && !ctx->buf_len)
38955714Skris		{
390109998Smarkm		*outl-=b;
391109998Smarkm		ctx->final_used=1;
392109998Smarkm		memcpy(ctx->final,&out[*outl],b);
39355714Skris		}
394109998Smarkm	else
395109998Smarkm		ctx->final_used = 0;
396109998Smarkm
397109998Smarkm	if (fix_len)
398109998Smarkm		*outl += b;
399109998Smarkm
40068651Skris	return 1;
40155714Skris	}
40255714Skris
40355714Skrisint EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
40455714Skris	{
405109998Smarkm	int ret;
406109998Smarkm	ret = EVP_DecryptFinal_ex(ctx, out, outl);
407109998Smarkm	return ret;
408109998Smarkm	}
409109998Smarkm
410109998Smarkmint EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
411109998Smarkm	{
41255714Skris	int i,b;
41355714Skris	int n;
41455714Skris
41555714Skris	*outl=0;
41655714Skris	b=ctx->cipher->block_size;
417109998Smarkm	if (ctx->flags & EVP_CIPH_NO_PADDING)
418109998Smarkm		{
419109998Smarkm		if(ctx->buf_len)
420109998Smarkm			{
421109998Smarkm			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
422109998Smarkm			return 0;
423109998Smarkm			}
424109998Smarkm		*outl = 0;
425109998Smarkm		return 1;
426109998Smarkm		}
42755714Skris	if (b > 1)
42855714Skris		{
429109998Smarkm		if (ctx->buf_len || !ctx->final_used)
43055714Skris			{
43155714Skris			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
43255714Skris			return(0);
43355714Skris			}
434109998Smarkm		OPENSSL_assert(b <= sizeof ctx->final);
435109998Smarkm		n=ctx->final[b-1];
43655714Skris		if (n > b)
43755714Skris			{
43855714Skris			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
43955714Skris			return(0);
44055714Skris			}
44155714Skris		for (i=0; i<n; i++)
44255714Skris			{
443109998Smarkm			if (ctx->final[--b] != n)
44455714Skris				{
44555714Skris				EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
44655714Skris				return(0);
44755714Skris				}
44855714Skris			}
44955714Skris		n=ctx->cipher->block_size-n;
45055714Skris		for (i=0; i<n; i++)
451109998Smarkm			out[i]=ctx->final[i];
45255714Skris		*outl=n;
45355714Skris		}
45455714Skris	else
45555714Skris		*outl=0;
45655714Skris	return(1);
45755714Skris	}
45855714Skris
45968651Skrisint EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
46055714Skris	{
461109998Smarkm	if (c->cipher != NULL)
46268651Skris		{
463109998Smarkm		if(c->cipher->cleanup && !c->cipher->cleanup(c))
464109998Smarkm			return 0;
465109998Smarkm		/* Cleanse cipher context data */
466109998Smarkm		if (c->cipher_data)
467109998Smarkm			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
46868651Skris		}
469109998Smarkm	if (c->cipher_data)
470109998Smarkm		OPENSSL_free(c->cipher_data);
471111147Snectar#ifndef OPENSSL_NO_ENGINE
472109998Smarkm	if (c->engine)
473109998Smarkm		/* The EVP_CIPHER we used belongs to an ENGINE, release the
474109998Smarkm		 * functional reference we held for this reason. */
475109998Smarkm		ENGINE_finish(c->engine);
476111147Snectar#endif
47755714Skris	memset(c,0,sizeof(EVP_CIPHER_CTX));
47868651Skris	return 1;
47955714Skris	}
48055714Skris
48168651Skrisint EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
48268651Skris	{
48368651Skris	if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
48468651Skris		return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
48568651Skris	if(c->key_len == keylen) return 1;
48668651Skris	if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
48768651Skris		{
48868651Skris		c->key_len = keylen;
48968651Skris		return 1;
49068651Skris		}
49168651Skris	EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
49268651Skris	return 0;
49368651Skris	}
49468651Skris
495109998Smarkmint EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
496109998Smarkm	{
497109998Smarkm	if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
498109998Smarkm	else ctx->flags |= EVP_CIPH_NO_PADDING;
499109998Smarkm	return 1;
500109998Smarkm	}
501109998Smarkm
50268651Skrisint EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
50368651Skris{
50468651Skris	int ret;
50568651Skris	if(!ctx->cipher) {
50668651Skris		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
50768651Skris		return 0;
50868651Skris	}
50968651Skris
51068651Skris	if(!ctx->cipher->ctrl) {
51168651Skris		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
51268651Skris		return 0;
51368651Skris	}
51468651Skris
51568651Skris	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
51668651Skris	if(ret == -1) {
51768651Skris		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
51868651Skris		return 0;
51968651Skris	}
52068651Skris	return ret;
52168651Skris}
522