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