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 #include <openssl/rand.h>
64 #ifndef OPENSSL_NO_ENGINE
65 #include <openssl/engine.h>
66 #endif
67 #ifdef OPENSSL_FIPS
68 #include <openssl/fips.h>
69 #endif
70 #include "evp_locl.h"
71
72 #ifdef OPENSSL_FIPS
73 #define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl)
74 #else
75 #define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
76 #endif
77
78
79 const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
80
EVP_CIPHER_CTX_init(EVP_CIPHER_CTX * ctx)81 void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
82 {
83 memset(ctx,0,sizeof(EVP_CIPHER_CTX));
84 /* ctx->cipher=NULL; */
85 }
86
EVP_CIPHER_CTX_new(void)87 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
88 {
89 EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
90 if (ctx)
91 EVP_CIPHER_CTX_init(ctx);
92 return ctx;
93 }
94
EVP_CipherInit(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,const unsigned char * key,const unsigned char * iv,int enc)95 int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
96 const unsigned char *key, const unsigned char *iv, int enc)
97 {
98 if (cipher)
99 EVP_CIPHER_CTX_init(ctx);
100 return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
101 }
102
EVP_CipherInit_ex(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,ENGINE * impl,const unsigned char * key,const unsigned char * iv,int enc)103 int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
104 const unsigned char *key, const unsigned char *iv, int enc)
105 {
106 if (enc == -1)
107 enc = ctx->encrypt;
108 else
109 {
110 if (enc)
111 enc = 1;
112 ctx->encrypt = enc;
113 }
114 #ifndef OPENSSL_NO_ENGINE
115 /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
116 * so this context may already have an ENGINE! Try to avoid releasing
117 * the previous handle, re-querying for an ENGINE, and having a
118 * reinitialisation, when it may all be unecessary. */
119 if (ctx->engine && ctx->cipher && (!cipher ||
120 (cipher && (cipher->nid == ctx->cipher->nid))))
121 goto skip_to_init;
122 #endif
123 if (cipher)
124 {
125 /* Ensure a context left lying around from last time is cleared
126 * (the previous check attempted to avoid this if the same
127 * ENGINE and EVP_CIPHER could be used). */
128 if (ctx->cipher)
129 {
130 unsigned long flags = ctx->flags;
131 EVP_CIPHER_CTX_cleanup(ctx);
132 /* Restore encrypt and flags */
133 ctx->encrypt = enc;
134 ctx->flags = flags;
135 }
136 #ifndef OPENSSL_NO_ENGINE
137 if(impl)
138 {
139 if (!ENGINE_init(impl))
140 {
141 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
142 return 0;
143 }
144 }
145 else
146 /* Ask if an ENGINE is reserved for this job */
147 impl = ENGINE_get_cipher_engine(cipher->nid);
148 if(impl)
149 {
150 /* There's an ENGINE for this job ... (apparently) */
151 const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
152 if(!c)
153 {
154 /* One positive side-effect of US's export
155 * control history, is that we should at least
156 * be able to avoid using US mispellings of
157 * "initialisation"? */
158 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
159 return 0;
160 }
161 /* We'll use the ENGINE's private cipher definition */
162 cipher = c;
163 /* Store the ENGINE functional reference so we know
164 * 'cipher' came from an ENGINE and we need to release
165 * it when done. */
166 ctx->engine = impl;
167 }
168 else
169 ctx->engine = NULL;
170 #endif
171
172 #ifdef OPENSSL_FIPS
173 if (FIPS_mode())
174 return FIPS_cipherinit(ctx, cipher, key, iv, enc);
175 #endif
176 ctx->cipher=cipher;
177 if (ctx->cipher->ctx_size)
178 {
179 ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
180 if (!ctx->cipher_data)
181 {
182 EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
183 return 0;
184 }
185 }
186 else
187 {
188 ctx->cipher_data = NULL;
189 }
190 ctx->key_len = cipher->key_len;
191 ctx->flags = 0;
192 if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
193 {
194 if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
195 {
196 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
197 return 0;
198 }
199 }
200 }
201 else if(!ctx->cipher)
202 {
203 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
204 return 0;
205 }
206 #ifndef OPENSSL_NO_ENGINE
207 skip_to_init:
208 #endif
209 #ifdef OPENSSL_FIPS
210 if (FIPS_mode())
211 return FIPS_cipherinit(ctx, cipher, key, iv, enc);
212 #endif
213 /* we assume block size is a power of 2 in *cryptUpdate */
214 OPENSSL_assert(ctx->cipher->block_size == 1
215 || ctx->cipher->block_size == 8
216 || ctx->cipher->block_size == 16);
217
218 if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
219 switch(EVP_CIPHER_CTX_mode(ctx)) {
220
221 case EVP_CIPH_STREAM_CIPHER:
222 case EVP_CIPH_ECB_MODE:
223 break;
224
225 case EVP_CIPH_CFB_MODE:
226 case EVP_CIPH_OFB_MODE:
227
228 ctx->num = 0;
229 /* fall-through */
230
231 case EVP_CIPH_CBC_MODE:
232
233 OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
234 (int)sizeof(ctx->iv));
235 if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
236 memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
237 break;
238
239 case EVP_CIPH_CTR_MODE:
240 ctx->num = 0;
241 /* Don't reuse IV for CTR mode */
242 if(iv)
243 memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
244 break;
245
246 default:
247 return 0;
248 break;
249 }
250 }
251
252 if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
253 if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
254 }
255 ctx->buf_len=0;
256 ctx->final_used=0;
257 ctx->block_mask=ctx->cipher->block_size-1;
258 return 1;
259 }
260
EVP_CipherUpdate(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl,const unsigned char * in,int inl)261 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
262 const unsigned char *in, int inl)
263 {
264 if (ctx->encrypt)
265 return EVP_EncryptUpdate(ctx,out,outl,in,inl);
266 else return EVP_DecryptUpdate(ctx,out,outl,in,inl);
267 }
268
EVP_CipherFinal_ex(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl)269 int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
270 {
271 if (ctx->encrypt)
272 return EVP_EncryptFinal_ex(ctx,out,outl);
273 else return EVP_DecryptFinal_ex(ctx,out,outl);
274 }
275
EVP_CipherFinal(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl)276 int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
277 {
278 if (ctx->encrypt)
279 return EVP_EncryptFinal(ctx,out,outl);
280 else return EVP_DecryptFinal(ctx,out,outl);
281 }
282
EVP_EncryptInit(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,const unsigned char * key,const unsigned char * iv)283 int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
284 const unsigned char *key, const unsigned char *iv)
285 {
286 return EVP_CipherInit(ctx, cipher, key, iv, 1);
287 }
288
EVP_EncryptInit_ex(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,ENGINE * impl,const unsigned char * key,const unsigned char * iv)289 int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
290 const unsigned char *key, const unsigned char *iv)
291 {
292 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
293 }
294
EVP_DecryptInit(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,const unsigned char * key,const unsigned char * iv)295 int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
296 const unsigned char *key, const unsigned char *iv)
297 {
298 return EVP_CipherInit(ctx, cipher, key, iv, 0);
299 }
300
EVP_DecryptInit_ex(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,ENGINE * impl,const unsigned char * key,const unsigned char * iv)301 int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
302 const unsigned char *key, const unsigned char *iv)
303 {
304 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
305 }
306
EVP_EncryptUpdate(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl,const unsigned char * in,int inl)307 int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
308 const unsigned char *in, int inl)
309 {
310 int i,j,bl;
311
312 if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
313 {
314 i = M_do_cipher(ctx, out, in, inl);
315 if (i < 0)
316 return 0;
317 else
318 *outl = i;
319 return 1;
320 }
321
322 if (inl <= 0)
323 {
324 *outl = 0;
325 return inl == 0;
326 }
327
328 if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
329 {
330 if(M_do_cipher(ctx,out,in,inl))
331 {
332 *outl=inl;
333 return 1;
334 }
335 else
336 {
337 *outl=0;
338 return 0;
339 }
340 }
341 i=ctx->buf_len;
342 bl=ctx->cipher->block_size;
343 OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
344 if (i != 0)
345 {
346 if (i+inl < bl)
347 {
348 memcpy(&(ctx->buf[i]),in,inl);
349 ctx->buf_len+=inl;
350 *outl=0;
351 return 1;
352 }
353 else
354 {
355 j=bl-i;
356 memcpy(&(ctx->buf[i]),in,j);
357 if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
358 inl-=j;
359 in+=j;
360 out+=bl;
361 *outl=bl;
362 }
363 }
364 else
365 *outl = 0;
366 i=inl&(bl-1);
367 inl-=i;
368 if (inl > 0)
369 {
370 if(!M_do_cipher(ctx,out,in,inl)) return 0;
371 *outl+=inl;
372 }
373
374 if (i != 0)
375 memcpy(ctx->buf,&(in[inl]),i);
376 ctx->buf_len=i;
377 return 1;
378 }
379
EVP_EncryptFinal(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl)380 int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
381 {
382 int ret;
383 ret = EVP_EncryptFinal_ex(ctx, out, outl);
384 return ret;
385 }
386
EVP_EncryptFinal_ex(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl)387 int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
388 {
389 int n,ret;
390 unsigned int i, b, bl;
391
392 if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
393 {
394 ret = M_do_cipher(ctx, out, NULL, 0);
395 if (ret < 0)
396 return 0;
397 else
398 *outl = ret;
399 return 1;
400 }
401
402 b=ctx->cipher->block_size;
403 OPENSSL_assert(b <= sizeof ctx->buf);
404 if (b == 1)
405 {
406 *outl=0;
407 return 1;
408 }
409 bl=ctx->buf_len;
410 if (ctx->flags & EVP_CIPH_NO_PADDING)
411 {
412 if(bl)
413 {
414 EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
415 return 0;
416 }
417 *outl = 0;
418 return 1;
419 }
420
421 n=b-bl;
422 for (i=bl; i<b; i++)
423 ctx->buf[i]=n;
424 ret=M_do_cipher(ctx,out,ctx->buf,b);
425
426
427 if(ret)
428 *outl=b;
429
430 return ret;
431 }
432
EVP_DecryptUpdate(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl,const unsigned char * in,int inl)433 int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
434 const unsigned char *in, int inl)
435 {
436 int fix_len;
437 unsigned int b;
438
439 if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
440 {
441 fix_len = M_do_cipher(ctx, out, in, inl);
442 if (fix_len < 0)
443 {
444 *outl = 0;
445 return 0;
446 }
447 else
448 *outl = fix_len;
449 return 1;
450 }
451
452 if (inl <= 0)
453 {
454 *outl = 0;
455 return inl == 0;
456 }
457
458 if (ctx->flags & EVP_CIPH_NO_PADDING)
459 return EVP_EncryptUpdate(ctx, out, outl, in, inl);
460
461 b=ctx->cipher->block_size;
462 OPENSSL_assert(b <= sizeof ctx->final);
463
464 if(ctx->final_used)
465 {
466 memcpy(out,ctx->final,b);
467 out+=b;
468 fix_len = 1;
469 }
470 else
471 fix_len = 0;
472
473
474 if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
475 return 0;
476
477 /* if we have 'decrypted' a multiple of block size, make sure
478 * we have a copy of this last block */
479 if (b > 1 && !ctx->buf_len)
480 {
481 *outl-=b;
482 ctx->final_used=1;
483 memcpy(ctx->final,&out[*outl],b);
484 }
485 else
486 ctx->final_used = 0;
487
488 if (fix_len)
489 *outl += b;
490
491 return 1;
492 }
493
EVP_DecryptFinal(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl)494 int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
495 {
496 int ret;
497 ret = EVP_DecryptFinal_ex(ctx, out, outl);
498 return ret;
499 }
500
EVP_DecryptFinal_ex(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl)501 int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
502 {
503 int i,n;
504 unsigned int b;
505 *outl=0;
506
507 if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
508 {
509 i = M_do_cipher(ctx, out, NULL, 0);
510 if (i < 0)
511 return 0;
512 else
513 *outl = i;
514 return 1;
515 }
516
517 b=ctx->cipher->block_size;
518 if (ctx->flags & EVP_CIPH_NO_PADDING)
519 {
520 if(ctx->buf_len)
521 {
522 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
523 return 0;
524 }
525 *outl = 0;
526 return 1;
527 }
528 if (b > 1)
529 {
530 if (ctx->buf_len || !ctx->final_used)
531 {
532 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
533 return(0);
534 }
535 OPENSSL_assert(b <= sizeof ctx->final);
536 n=ctx->final[b-1];
537 if (n == 0 || n > (int)b)
538 {
539 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
540 return(0);
541 }
542 for (i=0; i<n; i++)
543 {
544 if (ctx->final[--b] != n)
545 {
546 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
547 return(0);
548 }
549 }
550 n=ctx->cipher->block_size-n;
551 for (i=0; i<n; i++)
552 out[i]=ctx->final[i];
553 *outl=n;
554 }
555 else
556 *outl=0;
557 return(1);
558 }
559
EVP_CIPHER_CTX_free(EVP_CIPHER_CTX * ctx)560 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
561 {
562 if (ctx)
563 {
564 EVP_CIPHER_CTX_cleanup(ctx);
565 OPENSSL_free(ctx);
566 }
567 }
568
EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX * c)569 int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
570 {
571 #ifndef OPENSSL_FIPS
572 if (c->cipher != NULL)
573 {
574 if(c->cipher->cleanup && !c->cipher->cleanup(c))
575 return 0;
576 /* Cleanse cipher context data */
577 if (c->cipher_data)
578 OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
579 }
580 if (c->cipher_data)
581 OPENSSL_free(c->cipher_data);
582 #endif
583 #ifndef OPENSSL_NO_ENGINE
584 if (c->engine)
585 /* The EVP_CIPHER we used belongs to an ENGINE, release the
586 * functional reference we held for this reason. */
587 ENGINE_finish(c->engine);
588 #endif
589 #ifdef OPENSSL_FIPS
590 FIPS_cipher_ctx_cleanup(c);
591 #endif
592 memset(c,0,sizeof(EVP_CIPHER_CTX));
593 return 1;
594 }
595
EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX * c,int keylen)596 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
597 {
598 if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
599 return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
600 if(c->key_len == keylen) return 1;
601 if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
602 {
603 c->key_len = keylen;
604 return 1;
605 }
606 EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
607 return 0;
608 }
609
EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX * ctx,int pad)610 int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
611 {
612 if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
613 else ctx->flags |= EVP_CIPH_NO_PADDING;
614 return 1;
615 }
616
EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX * ctx,int type,int arg,void * ptr)617 int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
618 {
619 int ret;
620 if(!ctx->cipher) {
621 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
622 return 0;
623 }
624
625 if(!ctx->cipher->ctrl) {
626 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
627 return 0;
628 }
629
630 ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
631 if(ret == -1) {
632 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
633 return 0;
634 }
635 return ret;
636 }
637
EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX * ctx,unsigned char * key)638 int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
639 {
640 if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
641 return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
642 if (RAND_bytes(key, ctx->key_len) <= 0)
643 return 0;
644 return 1;
645 }
646
EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX * out,const EVP_CIPHER_CTX * in)647 int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
648 {
649 if ((in == NULL) || (in->cipher == NULL))
650 {
651 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
652 return 0;
653 }
654 #ifndef OPENSSL_NO_ENGINE
655 /* Make sure it's safe to copy a cipher context using an ENGINE */
656 if (in->engine && !ENGINE_init(in->engine))
657 {
658 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB);
659 return 0;
660 }
661 #endif
662
663 EVP_CIPHER_CTX_cleanup(out);
664 memcpy(out,in,sizeof *out);
665
666 if (in->cipher_data && in->cipher->ctx_size)
667 {
668 out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
669 if (!out->cipher_data)
670 {
671 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
672 return 0;
673 }
674 memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
675 }
676
677 if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
678 return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
679 return 1;
680 }
681
682