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