evp_enc.c revision 111147
1/* crypto/evp/evp_enc.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/evp.h>
62#include <openssl/err.h>
63#ifndef OPENSSL_NO_ENGINE
64#include <openssl/engine.h>
65#endif
66#include "evp_locl.h"
67
68const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT;
69
70void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
71	{
72	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
73	/* ctx->cipher=NULL; */
74	}
75
76
77int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
78	     const unsigned char *key, const unsigned char *iv, int enc)
79	{
80	if (cipher)
81		EVP_CIPHER_CTX_init(ctx);
82	return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
83	}
84
85int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
86	     const unsigned char *key, const unsigned char *iv, int enc)
87	{
88	if (enc == -1)
89		enc = ctx->encrypt;
90	else
91		{
92		if (enc)
93			enc = 1;
94		ctx->encrypt = enc;
95		}
96#ifndef OPENSSL_NO_ENGINE
97	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
98	 * so this context may already have an ENGINE! Try to avoid releasing
99	 * the previous handle, re-querying for an ENGINE, and having a
100	 * reinitialisation, when it may all be unecessary. */
101	if (ctx->engine && ctx->cipher && (!cipher ||
102			(cipher && (cipher->nid == ctx->cipher->nid))))
103		goto skip_to_init;
104#endif
105	if (cipher)
106		{
107		/* Ensure a context left lying around from last time is cleared
108		 * (the previous check attempted to avoid this if the same
109		 * ENGINE and EVP_CIPHER could be used). */
110		EVP_CIPHER_CTX_cleanup(ctx);
111
112		/* Restore encrypt field: it is zeroed by cleanup */
113		ctx->encrypt = enc;
114#ifndef OPENSSL_NO_ENGINE
115		if(impl)
116			{
117			if (!ENGINE_init(impl))
118				{
119				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
120				return 0;
121				}
122			}
123		else
124			/* Ask if an ENGINE is reserved for this job */
125			impl = ENGINE_get_cipher_engine(cipher->nid);
126		if(impl)
127			{
128			/* There's an ENGINE for this job ... (apparently) */
129			const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
130			if(!c)
131				{
132				/* One positive side-effect of US's export
133				 * control history, is that we should at least
134				 * be able to avoid using US mispellings of
135				 * "initialisation"? */
136				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
137				return 0;
138				}
139			/* We'll use the ENGINE's private cipher definition */
140			cipher = c;
141			/* Store the ENGINE functional reference so we know
142			 * 'cipher' came from an ENGINE and we need to release
143			 * it when done. */
144			ctx->engine = impl;
145			}
146		else
147			ctx->engine = NULL;
148#endif
149
150		ctx->cipher=cipher;
151		ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
152		ctx->key_len = cipher->key_len;
153		ctx->flags = 0;
154		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
155			{
156			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
157				{
158				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
159				return 0;
160				}
161			}
162		}
163	else if(!ctx->cipher)
164		{
165		EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET);
166		return 0;
167		}
168#ifndef OPENSSL_NO_ENGINE
169skip_to_init:
170#endif
171	/* we assume block size is a power of 2 in *cryptUpdate */
172	OPENSSL_assert(ctx->cipher->block_size == 1
173	    || ctx->cipher->block_size == 8
174	    || ctx->cipher->block_size == 16);
175
176	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
177		switch(EVP_CIPHER_CTX_mode(ctx)) {
178
179			case EVP_CIPH_STREAM_CIPHER:
180			case EVP_CIPH_ECB_MODE:
181			break;
182
183			case EVP_CIPH_CFB_MODE:
184			case EVP_CIPH_OFB_MODE:
185
186			ctx->num = 0;
187
188			case EVP_CIPH_CBC_MODE:
189
190			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof ctx->iv);
191			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
192			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
193			break;
194
195			default:
196			return 0;
197			break;
198		}
199	}
200
201	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
202		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
203	}
204	ctx->buf_len=0;
205	ctx->final_used=0;
206	ctx->block_mask=ctx->cipher->block_size-1;
207	return 1;
208	}
209
210int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
211	     const unsigned char *in, int inl)
212	{
213	if (ctx->encrypt)
214		return EVP_EncryptUpdate(ctx,out,outl,in,inl);
215	else	return EVP_DecryptUpdate(ctx,out,outl,in,inl);
216	}
217
218int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
219	{
220	if (ctx->encrypt)
221		return EVP_EncryptFinal_ex(ctx,out,outl);
222	else	return EVP_DecryptFinal_ex(ctx,out,outl);
223	}
224
225int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
226	{
227	if (ctx->encrypt)
228		return EVP_EncryptFinal(ctx,out,outl);
229	else	return EVP_DecryptFinal(ctx,out,outl);
230	}
231
232int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
233	     const unsigned char *key, const unsigned char *iv)
234	{
235	return EVP_CipherInit(ctx, cipher, key, iv, 1);
236	}
237
238int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
239		const unsigned char *key, const unsigned char *iv)
240	{
241	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
242	}
243
244int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
245	     const unsigned char *key, const unsigned char *iv)
246	{
247	return EVP_CipherInit(ctx, cipher, key, iv, 0);
248	}
249
250int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
251	     const unsigned char *key, const unsigned char *iv)
252	{
253	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
254	}
255
256int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
257	     const unsigned char *in, int inl)
258	{
259	int i,j,bl;
260
261	OPENSSL_assert(inl > 0);
262	if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
263		{
264		if(ctx->cipher->do_cipher(ctx,out,in,inl))
265			{
266			*outl=inl;
267			return 1;
268			}
269		else
270			{
271			*outl=0;
272			return 0;
273			}
274		}
275	i=ctx->buf_len;
276	bl=ctx->cipher->block_size;
277	OPENSSL_assert(bl <= sizeof ctx->buf);
278	if (i != 0)
279		{
280		if (i+inl < bl)
281			{
282			memcpy(&(ctx->buf[i]),in,inl);
283			ctx->buf_len+=inl;
284			*outl=0;
285			return 1;
286			}
287		else
288			{
289			j=bl-i;
290			memcpy(&(ctx->buf[i]),in,j);
291			if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
292			inl-=j;
293			in+=j;
294			out+=bl;
295			*outl=bl;
296			}
297		}
298	else
299		*outl = 0;
300	i=inl&(bl-1);
301	inl-=i;
302	if (inl > 0)
303		{
304		if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
305		*outl+=inl;
306		}
307
308	if (i != 0)
309		memcpy(ctx->buf,&(in[inl]),i);
310	ctx->buf_len=i;
311	return 1;
312	}
313
314int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
315	{
316	int ret;
317	ret = EVP_EncryptFinal_ex(ctx, out, outl);
318	return ret;
319	}
320
321int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
322	{
323	int i,n,b,bl,ret;
324
325	b=ctx->cipher->block_size;
326	OPENSSL_assert(b <= sizeof ctx->buf);
327	if (b == 1)
328		{
329		*outl=0;
330		return 1;
331		}
332	bl=ctx->buf_len;
333	if (ctx->flags & EVP_CIPH_NO_PADDING)
334		{
335		if(bl)
336			{
337			EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
338			return 0;
339			}
340		*outl = 0;
341		return 1;
342		}
343
344	n=b-bl;
345	for (i=bl; i<b; i++)
346		ctx->buf[i]=n;
347	ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
348
349
350	if(ret)
351		*outl=b;
352
353	return ret;
354	}
355
356int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
357	     const unsigned char *in, int inl)
358	{
359	int b, fix_len;
360
361	if (inl == 0)
362		{
363		*outl=0;
364		return 1;
365		}
366
367	if (ctx->flags & EVP_CIPH_NO_PADDING)
368		return EVP_EncryptUpdate(ctx, out, outl, in, inl);
369
370	b=ctx->cipher->block_size;
371	OPENSSL_assert(b <= sizeof ctx->final);
372
373	if(ctx->final_used)
374		{
375		memcpy(out,ctx->final,b);
376		out+=b;
377		fix_len = 1;
378		}
379	else
380		fix_len = 0;
381
382
383	if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
384		return 0;
385
386	/* if we have 'decrypted' a multiple of block size, make sure
387	 * we have a copy of this last block */
388	if (b > 1 && !ctx->buf_len)
389		{
390		*outl-=b;
391		ctx->final_used=1;
392		memcpy(ctx->final,&out[*outl],b);
393		}
394	else
395		ctx->final_used = 0;
396
397	if (fix_len)
398		*outl += b;
399
400	return 1;
401	}
402
403int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
404	{
405	int ret;
406	ret = EVP_DecryptFinal_ex(ctx, out, outl);
407	return ret;
408	}
409
410int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
411	{
412	int i,b;
413	int n;
414
415	*outl=0;
416	b=ctx->cipher->block_size;
417	if (ctx->flags & EVP_CIPH_NO_PADDING)
418		{
419		if(ctx->buf_len)
420			{
421			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
422			return 0;
423			}
424		*outl = 0;
425		return 1;
426		}
427	if (b > 1)
428		{
429		if (ctx->buf_len || !ctx->final_used)
430			{
431			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
432			return(0);
433			}
434		OPENSSL_assert(b <= sizeof ctx->final);
435		n=ctx->final[b-1];
436		if (n > b)
437			{
438			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
439			return(0);
440			}
441		for (i=0; i<n; i++)
442			{
443			if (ctx->final[--b] != n)
444				{
445				EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
446				return(0);
447				}
448			}
449		n=ctx->cipher->block_size-n;
450		for (i=0; i<n; i++)
451			out[i]=ctx->final[i];
452		*outl=n;
453		}
454	else
455		*outl=0;
456	return(1);
457	}
458
459int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
460	{
461	if (c->cipher != NULL)
462		{
463		if(c->cipher->cleanup && !c->cipher->cleanup(c))
464			return 0;
465		/* Cleanse cipher context data */
466		if (c->cipher_data)
467			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
468		}
469	if (c->cipher_data)
470		OPENSSL_free(c->cipher_data);
471#ifndef OPENSSL_NO_ENGINE
472	if (c->engine)
473		/* The EVP_CIPHER we used belongs to an ENGINE, release the
474		 * functional reference we held for this reason. */
475		ENGINE_finish(c->engine);
476#endif
477	memset(c,0,sizeof(EVP_CIPHER_CTX));
478	return 1;
479	}
480
481int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
482	{
483	if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
484		return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
485	if(c->key_len == keylen) return 1;
486	if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
487		{
488		c->key_len = keylen;
489		return 1;
490		}
491	EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
492	return 0;
493	}
494
495int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
496	{
497	if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
498	else ctx->flags |= EVP_CIPH_NO_PADDING;
499	return 1;
500	}
501
502int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
503{
504	int ret;
505	if(!ctx->cipher) {
506		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
507		return 0;
508	}
509
510	if(!ctx->cipher->ctrl) {
511		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
512		return 0;
513	}
514
515	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
516	if(ret == -1) {
517		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
518		return 0;
519	}
520	return ret;
521}
522