diff options
Diffstat (limited to 'src/lib/libcrypto/evp/evp_enc.c')
-rw-r--r-- | src/lib/libcrypto/evp/evp_enc.c | 290 |
1 files changed, 229 insertions, 61 deletions
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c index e2687f9879..d28a7d266e 100644 --- a/src/lib/libcrypto/evp/evp_enc.c +++ b/src/lib/libcrypto/evp/evp_enc.c | |||
@@ -60,8 +60,11 @@ | |||
60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
61 | #include <openssl/evp.h> | 61 | #include <openssl/evp.h> |
62 | #include <openssl/err.h> | 62 | #include <openssl/err.h> |
63 | #include <openssl/engine.h> | ||
63 | #include "evp_locl.h" | 64 | #include "evp_locl.h" |
64 | 65 | ||
66 | #include <assert.h> | ||
67 | |||
65 | const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT; | 68 | const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT; |
66 | 69 | ||
67 | void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) | 70 | void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) |
@@ -70,23 +73,97 @@ void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) | |||
70 | /* ctx->cipher=NULL; */ | 73 | /* ctx->cipher=NULL; */ |
71 | } | 74 | } |
72 | 75 | ||
76 | |||
73 | int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | 77 | int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
74 | unsigned char *key, unsigned char *iv, int enc) | 78 | const unsigned char *key, const unsigned char *iv, int enc) |
75 | { | 79 | { |
76 | if(enc && (enc != -1)) enc = 1; | 80 | if (cipher) |
77 | if (cipher) { | 81 | EVP_CIPHER_CTX_init(ctx); |
82 | return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); | ||
83 | } | ||
84 | |||
85 | int 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 | /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts | ||
97 | * so this context may already have an ENGINE! Try to avoid releasing | ||
98 | * the previous handle, re-querying for an ENGINE, and having a | ||
99 | * reinitialisation, when it may all be unecessary. */ | ||
100 | if (ctx->engine && ctx->cipher && (!cipher || | ||
101 | (cipher && (cipher->nid == ctx->cipher->nid)))) | ||
102 | goto skip_to_init; | ||
103 | if (cipher) | ||
104 | { | ||
105 | /* Ensure an ENGINE left lying around from last time is cleared | ||
106 | * (the previous check attempted to avoid this if the same | ||
107 | * ENGINE and EVP_CIPHER could be used). */ | ||
108 | if(ctx->engine) | ||
109 | ENGINE_finish(ctx->engine); | ||
110 | if(impl) | ||
111 | { | ||
112 | if (!ENGINE_init(impl)) | ||
113 | { | ||
114 | EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR); | ||
115 | return 0; | ||
116 | } | ||
117 | } | ||
118 | else | ||
119 | /* Ask if an ENGINE is reserved for this job */ | ||
120 | impl = ENGINE_get_cipher_engine(cipher->nid); | ||
121 | if(impl) | ||
122 | { | ||
123 | /* There's an ENGINE for this job ... (apparently) */ | ||
124 | const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); | ||
125 | if(!c) | ||
126 | { | ||
127 | /* One positive side-effect of US's export | ||
128 | * control history, is that we should at least | ||
129 | * be able to avoid using US mispellings of | ||
130 | * "initialisation"? */ | ||
131 | EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR); | ||
132 | return 0; | ||
133 | } | ||
134 | /* We'll use the ENGINE's private cipher definition */ | ||
135 | cipher = c; | ||
136 | /* Store the ENGINE functional reference so we know | ||
137 | * 'cipher' came from an ENGINE and we need to release | ||
138 | * it when done. */ | ||
139 | ctx->engine = impl; | ||
140 | } | ||
141 | else | ||
142 | ctx->engine = NULL; | ||
78 | ctx->cipher=cipher; | 143 | ctx->cipher=cipher; |
144 | ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); | ||
79 | ctx->key_len = cipher->key_len; | 145 | ctx->key_len = cipher->key_len; |
80 | if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { | 146 | ctx->flags = 0; |
81 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { | 147 | if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) |
148 | { | ||
149 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) | ||
150 | { | ||
82 | EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR); | 151 | EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR); |
83 | return 0; | 152 | return 0; |
153 | } | ||
84 | } | 154 | } |
85 | } | 155 | } |
86 | } else if(!ctx->cipher) { | 156 | else if(!ctx->cipher) |
157 | { | ||
87 | EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET); | 158 | EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET); |
88 | return 0; | 159 | return 0; |
89 | } | 160 | } |
161 | skip_to_init: | ||
162 | /* we assume block size is a power of 2 in *cryptUpdate */ | ||
163 | assert(ctx->cipher->block_size == 1 | ||
164 | || ctx->cipher->block_size == 8 | ||
165 | || ctx->cipher->block_size == 16); | ||
166 | |||
90 | if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { | 167 | if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { |
91 | switch(EVP_CIPHER_CTX_mode(ctx)) { | 168 | switch(EVP_CIPHER_CTX_mode(ctx)) { |
92 | 169 | ||
@@ -114,68 +191,101 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | |||
114 | if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { | 191 | if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { |
115 | if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; | 192 | if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; |
116 | } | 193 | } |
117 | if(enc != -1) ctx->encrypt=enc; | ||
118 | ctx->buf_len=0; | 194 | ctx->buf_len=0; |
195 | ctx->final_used=0; | ||
196 | ctx->block_mask=ctx->cipher->block_size-1; | ||
119 | return 1; | 197 | return 1; |
120 | } | 198 | } |
121 | 199 | ||
122 | int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 200 | int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
123 | unsigned char *in, int inl) | 201 | const unsigned char *in, int inl) |
124 | { | 202 | { |
125 | if (ctx->encrypt) | 203 | if (ctx->encrypt) |
126 | return EVP_EncryptUpdate(ctx,out,outl,in,inl); | 204 | return EVP_EncryptUpdate(ctx,out,outl,in,inl); |
127 | else return EVP_DecryptUpdate(ctx,out,outl,in,inl); | 205 | else return EVP_DecryptUpdate(ctx,out,outl,in,inl); |
128 | } | 206 | } |
129 | 207 | ||
208 | int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | ||
209 | { | ||
210 | if (ctx->encrypt) | ||
211 | return EVP_EncryptFinal_ex(ctx,out,outl); | ||
212 | else return EVP_DecryptFinal_ex(ctx,out,outl); | ||
213 | } | ||
214 | |||
130 | int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | 215 | int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
131 | { | 216 | { |
132 | if (ctx->encrypt) | 217 | if (ctx->encrypt) |
133 | return EVP_EncryptFinal(ctx,out,outl); | 218 | return EVP_EncryptFinal(ctx,out,outl); |
134 | else return(EVP_DecryptFinal(ctx,out,outl)); | 219 | else return EVP_DecryptFinal(ctx,out,outl); |
135 | } | 220 | } |
136 | 221 | ||
137 | int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | 222 | int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
138 | unsigned char *key, unsigned char *iv) | 223 | const unsigned char *key, const unsigned char *iv) |
139 | { | 224 | { |
140 | return EVP_CipherInit(ctx, cipher, key, iv, 1); | 225 | return EVP_CipherInit(ctx, cipher, key, iv, 1); |
141 | } | 226 | } |
142 | 227 | ||
228 | int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, | ||
229 | const unsigned char *key, const unsigned char *iv) | ||
230 | { | ||
231 | return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); | ||
232 | } | ||
233 | |||
143 | int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | 234 | int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
144 | unsigned char *key, unsigned char *iv) | 235 | const unsigned char *key, const unsigned char *iv) |
145 | { | 236 | { |
146 | return EVP_CipherInit(ctx, cipher, key, iv, 0); | 237 | return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0); |
147 | } | 238 | } |
148 | 239 | ||
240 | int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, | ||
241 | const unsigned char *key, const unsigned char *iv) | ||
242 | { | ||
243 | return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); | ||
244 | } | ||
149 | 245 | ||
150 | int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 246 | int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
151 | unsigned char *in, int inl) | 247 | const unsigned char *in, int inl) |
152 | { | 248 | { |
153 | int i,j,bl; | 249 | int i,j,bl; |
154 | 250 | ||
251 | if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) | ||
252 | { | ||
253 | if(ctx->cipher->do_cipher(ctx,out,in,inl)) | ||
254 | { | ||
255 | *outl=inl; | ||
256 | return 1; | ||
257 | } | ||
258 | else | ||
259 | { | ||
260 | *outl=0; | ||
261 | return 0; | ||
262 | } | ||
263 | } | ||
155 | i=ctx->buf_len; | 264 | i=ctx->buf_len; |
156 | bl=ctx->cipher->block_size; | 265 | bl=ctx->cipher->block_size; |
157 | *outl=0; | ||
158 | if ((inl == 0) && (i != bl)) return 1; | ||
159 | if (i != 0) | 266 | if (i != 0) |
160 | { | 267 | { |
161 | if (i+inl < bl) | 268 | if (i+inl < bl) |
162 | { | 269 | { |
163 | memcpy(&(ctx->buf[i]),in,inl); | 270 | memcpy(&(ctx->buf[i]),in,inl); |
164 | ctx->buf_len+=inl; | 271 | ctx->buf_len+=inl; |
272 | *outl=0; | ||
165 | return 1; | 273 | return 1; |
166 | } | 274 | } |
167 | else | 275 | else |
168 | { | 276 | { |
169 | j=bl-i; | 277 | j=bl-i; |
170 | if (j != 0) memcpy(&(ctx->buf[i]),in,j); | 278 | memcpy(&(ctx->buf[i]),in,j); |
171 | if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0; | 279 | if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0; |
172 | inl-=j; | 280 | inl-=j; |
173 | in+=j; | 281 | in+=j; |
174 | out+=bl; | 282 | out+=bl; |
175 | *outl+=bl; | 283 | *outl=bl; |
176 | } | 284 | } |
177 | } | 285 | } |
178 | i=inl%bl; /* how much is left */ | 286 | else |
287 | *outl = 0; | ||
288 | i=inl&(bl-1); | ||
179 | inl-=i; | 289 | inl-=i; |
180 | if (inl > 0) | 290 | if (inl > 0) |
181 | { | 291 | { |
@@ -191,107 +301,153 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
191 | 301 | ||
192 | int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | 302 | int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
193 | { | 303 | { |
194 | int i,n,b,bl; | 304 | int ret; |
305 | ret = EVP_EncryptFinal_ex(ctx, out, outl); | ||
306 | EVP_CIPHER_CTX_cleanup(ctx); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | ||
311 | { | ||
312 | int i,n,b,bl,ret; | ||
195 | 313 | ||
196 | b=ctx->cipher->block_size; | 314 | b=ctx->cipher->block_size; |
197 | if (b == 1) | 315 | if (b == 1) |
198 | { | 316 | { |
317 | EVP_CIPHER_CTX_cleanup(ctx); | ||
199 | *outl=0; | 318 | *outl=0; |
200 | return 1; | 319 | return 1; |
201 | } | 320 | } |
202 | bl=ctx->buf_len; | 321 | bl=ctx->buf_len; |
322 | if (ctx->flags & EVP_CIPH_NO_PADDING) | ||
323 | { | ||
324 | EVP_CIPHER_CTX_cleanup(ctx); | ||
325 | if(bl) | ||
326 | { | ||
327 | EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); | ||
328 | return 0; | ||
329 | } | ||
330 | *outl = 0; | ||
331 | return 1; | ||
332 | } | ||
333 | |||
203 | n=b-bl; | 334 | n=b-bl; |
204 | for (i=bl; i<b; i++) | 335 | for (i=bl; i<b; i++) |
205 | ctx->buf[i]=n; | 336 | ctx->buf[i]=n; |
206 | if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,b)) return 0; | 337 | ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b); |
207 | *outl=b; | 338 | |
208 | return 1; | 339 | EVP_CIPHER_CTX_cleanup(ctx); |
340 | |||
341 | if(ret) | ||
342 | *outl=b; | ||
343 | |||
344 | return ret; | ||
209 | } | 345 | } |
210 | 346 | ||
211 | int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 347 | int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
212 | unsigned char *in, int inl) | 348 | const unsigned char *in, int inl) |
213 | { | 349 | { |
214 | int b,bl,n; | 350 | int b, fix_len; |
215 | int keep_last=0; | ||
216 | 351 | ||
217 | *outl=0; | 352 | if (inl == 0) |
218 | if (inl == 0) return 1; | 353 | { |
354 | *outl=0; | ||
355 | return 1; | ||
356 | } | ||
357 | |||
358 | if (ctx->flags & EVP_CIPH_NO_PADDING) | ||
359 | return EVP_EncryptUpdate(ctx, out, outl, in, inl); | ||
219 | 360 | ||
220 | b=ctx->cipher->block_size; | 361 | b=ctx->cipher->block_size; |
221 | if (b > 1) | 362 | |
363 | if(ctx->final_used) | ||
222 | { | 364 | { |
223 | /* Is the input a multiple of the block size? */ | 365 | memcpy(out,ctx->final,b); |
224 | bl=ctx->buf_len; | 366 | out+=b; |
225 | n=inl+bl; | 367 | fix_len = 1; |
226 | if (n%b == 0) | ||
227 | { | ||
228 | if (inl < b) /* must be 'just one' buff */ | ||
229 | { | ||
230 | memcpy(&(ctx->buf[bl]),in,inl); | ||
231 | ctx->buf_len=b; | ||
232 | *outl=0; | ||
233 | return 1; | ||
234 | } | ||
235 | keep_last=1; | ||
236 | inl-=b; /* don't do the last block */ | ||
237 | } | ||
238 | } | 368 | } |
239 | if(!EVP_EncryptUpdate(ctx,out,outl,in,inl)) return 0; | 369 | else |
370 | fix_len = 0; | ||
371 | |||
372 | |||
373 | if(!EVP_EncryptUpdate(ctx,out,outl,in,inl)) | ||
374 | return 0; | ||
240 | 375 | ||
241 | /* if we have 'decrypted' a multiple of block size, make sure | 376 | /* if we have 'decrypted' a multiple of block size, make sure |
242 | * we have a copy of this last block */ | 377 | * we have a copy of this last block */ |
243 | if (keep_last) | 378 | if (b > 1 && !ctx->buf_len) |
244 | { | 379 | { |
245 | memcpy(&(ctx->buf[0]),&(in[inl]),b); | 380 | *outl-=b; |
246 | #ifdef DEBUG | 381 | ctx->final_used=1; |
247 | if (ctx->buf_len != 0) | 382 | memcpy(ctx->final,&out[*outl],b); |
248 | { | ||
249 | abort(); | ||
250 | } | ||
251 | #endif | ||
252 | ctx->buf_len=b; | ||
253 | } | 383 | } |
384 | else | ||
385 | ctx->final_used = 0; | ||
386 | |||
387 | if (fix_len) | ||
388 | *outl += b; | ||
389 | |||
254 | return 1; | 390 | return 1; |
255 | } | 391 | } |
256 | 392 | ||
257 | int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | 393 | int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
258 | { | 394 | { |
395 | int ret; | ||
396 | ret = EVP_DecryptFinal_ex(ctx, out, outl); | ||
397 | EVP_CIPHER_CTX_cleanup(ctx); | ||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | ||
402 | { | ||
259 | int i,b; | 403 | int i,b; |
260 | int n; | 404 | int n; |
261 | 405 | ||
262 | *outl=0; | 406 | *outl=0; |
263 | b=ctx->cipher->block_size; | 407 | b=ctx->cipher->block_size; |
408 | if (ctx->flags & EVP_CIPH_NO_PADDING) | ||
409 | { | ||
410 | EVP_CIPHER_CTX_cleanup(ctx); | ||
411 | if(ctx->buf_len) | ||
412 | { | ||
413 | EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); | ||
414 | return 0; | ||
415 | } | ||
416 | *outl = 0; | ||
417 | return 1; | ||
418 | } | ||
264 | if (b > 1) | 419 | if (b > 1) |
265 | { | 420 | { |
266 | if (ctx->buf_len != b) | 421 | if (ctx->buf_len || !ctx->final_used) |
267 | { | 422 | { |
423 | EVP_CIPHER_CTX_cleanup(ctx); | ||
268 | EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH); | 424 | EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH); |
269 | return(0); | 425 | return(0); |
270 | } | 426 | } |
271 | if(!EVP_EncryptUpdate(ctx,ctx->buf,&n,ctx->buf,0)) return 0; | 427 | n=ctx->final[b-1]; |
272 | if (n != b) | ||
273 | return(0); | ||
274 | n=ctx->buf[b-1]; | ||
275 | if (n > b) | 428 | if (n > b) |
276 | { | 429 | { |
430 | EVP_CIPHER_CTX_cleanup(ctx); | ||
277 | EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); | 431 | EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); |
278 | return(0); | 432 | return(0); |
279 | } | 433 | } |
280 | for (i=0; i<n; i++) | 434 | for (i=0; i<n; i++) |
281 | { | 435 | { |
282 | if (ctx->buf[--b] != n) | 436 | if (ctx->final[--b] != n) |
283 | { | 437 | { |
438 | EVP_CIPHER_CTX_cleanup(ctx); | ||
284 | EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); | 439 | EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); |
285 | return(0); | 440 | return(0); |
286 | } | 441 | } |
287 | } | 442 | } |
288 | n=ctx->cipher->block_size-n; | 443 | n=ctx->cipher->block_size-n; |
289 | for (i=0; i<n; i++) | 444 | for (i=0; i<n; i++) |
290 | out[i]=ctx->buf[i]; | 445 | out[i]=ctx->final[i]; |
291 | *outl=n; | 446 | *outl=n; |
292 | } | 447 | } |
293 | else | 448 | else |
294 | *outl=0; | 449 | *outl=0; |
450 | EVP_CIPHER_CTX_cleanup(ctx); | ||
295 | return(1); | 451 | return(1); |
296 | } | 452 | } |
297 | 453 | ||
@@ -301,6 +457,11 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) | |||
301 | { | 457 | { |
302 | if(!c->cipher->cleanup(c)) return 0; | 458 | if(!c->cipher->cleanup(c)) return 0; |
303 | } | 459 | } |
460 | OPENSSL_free(c->cipher_data); | ||
461 | if (c->engine) | ||
462 | /* The EVP_CIPHER we used belongs to an ENGINE, release the | ||
463 | * functional reference we held for this reason. */ | ||
464 | ENGINE_finish(c->engine); | ||
304 | memset(c,0,sizeof(EVP_CIPHER_CTX)); | 465 | memset(c,0,sizeof(EVP_CIPHER_CTX)); |
305 | return 1; | 466 | return 1; |
306 | } | 467 | } |
@@ -319,6 +480,13 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) | |||
319 | return 0; | 480 | return 0; |
320 | } | 481 | } |
321 | 482 | ||
483 | int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) | ||
484 | { | ||
485 | if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING; | ||
486 | else ctx->flags |= EVP_CIPH_NO_PADDING; | ||
487 | return 1; | ||
488 | } | ||
489 | |||
322 | int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) | 490 | int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) |
323 | { | 491 | { |
324 | int ret; | 492 | int ret; |