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