OLD | NEW |
1 /* crypto/evp/evp_enc.c */ | 1 /* crypto/evp/evp_enc.c */ |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
8 * | 8 * |
9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 #include <stdio.h> | 59 #include <stdio.h> |
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/rand.h> | 63 #include <openssl/rand.h> |
64 #ifndef OPENSSL_NO_ENGINE | 64 #ifndef OPENSSL_NO_ENGINE |
65 #include <openssl/engine.h> | 65 #include <openssl/engine.h> |
66 #endif | 66 #endif |
67 #include "evp_locl.h" | 67 #include "evp_locl.h" |
68 | 68 |
69 #ifdef OPENSSL_FIPS | 69 const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; |
70 » #define M_do_cipher(ctx, out, in, inl) \ | |
71 » » EVP_Cipher(ctx,out,in,inl) | |
72 #else | |
73 » #define M_do_cipher(ctx, out, in, inl) \ | |
74 » » ctx->cipher->do_cipher(ctx,out,in,inl) | |
75 #endif | |
76 | 70 |
77 const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; | 71 void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) |
| 72 » { |
| 73 » memset(ctx,0,sizeof(EVP_CIPHER_CTX)); |
| 74 » /* ctx->cipher=NULL; */ |
| 75 » } |
78 | 76 |
79 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) | 77 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) |
80 { | 78 { |
81 EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx); | 79 EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx); |
82 if (ctx) | 80 if (ctx) |
83 EVP_CIPHER_CTX_init(ctx); | 81 EVP_CIPHER_CTX_init(ctx); |
84 return ctx; | 82 return ctx; |
85 } | 83 } |
86 | 84 |
87 int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | 85 int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
88 const unsigned char *key, const unsigned char *iv, int enc) | 86 const unsigned char *key, const unsigned char *iv, int enc) |
89 { | 87 { |
90 if (cipher) | 88 if (cipher) |
91 EVP_CIPHER_CTX_init(ctx); | 89 EVP_CIPHER_CTX_init(ctx); |
92 return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); | 90 return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); |
93 } | 91 } |
94 | 92 |
| 93 int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
l, |
| 94 const unsigned char *key, const unsigned char *iv, int enc) |
| 95 { |
| 96 if (enc == -1) |
| 97 enc = ctx->encrypt; |
| 98 else |
| 99 { |
| 100 if (enc) |
| 101 enc = 1; |
| 102 ctx->encrypt = enc; |
| 103 } |
| 104 #ifndef OPENSSL_NO_ENGINE |
| 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; |
| 112 #endif |
| 113 if (cipher) |
| 114 { |
| 115 /* Ensure a context left lying around from last time is cleared |
| 116 * (the previous check attempted to avoid this if the same |
| 117 * ENGINE and EVP_CIPHER could be used). */ |
| 118 EVP_CIPHER_CTX_cleanup(ctx); |
| 119 |
| 120 /* Restore encrypt field: it is zeroed by cleanup */ |
| 121 ctx->encrypt = enc; |
| 122 #ifndef OPENSSL_NO_ENGINE |
| 123 if(impl) |
| 124 { |
| 125 if (!ENGINE_init(impl)) |
| 126 { |
| 127 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZA
TION_ERROR); |
| 128 return 0; |
| 129 } |
| 130 } |
| 131 else |
| 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->ni
d); |
| 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"? */ |
| 144 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZA
TION_ERROR); |
| 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; |
| 156 #endif |
| 157 |
| 158 ctx->cipher=cipher; |
| 159 if (ctx->cipher->ctx_size) |
| 160 { |
| 161 ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); |
| 162 if (!ctx->cipher_data) |
| 163 { |
| 164 EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAI
LURE); |
| 165 return 0; |
| 166 } |
| 167 } |
| 168 else |
| 169 { |
| 170 ctx->cipher_data = NULL; |
| 171 } |
| 172 ctx->key_len = cipher->key_len; |
| 173 ctx->flags = 0; |
| 174 if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) |
| 175 { |
| 176 if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) |
| 177 { |
| 178 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZA
TION_ERROR); |
| 179 return 0; |
| 180 } |
| 181 } |
| 182 } |
| 183 else if(!ctx->cipher) |
| 184 { |
| 185 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); |
| 186 return 0; |
| 187 } |
| 188 #ifndef OPENSSL_NO_ENGINE |
| 189 skip_to_init: |
| 190 #endif |
| 191 /* we assume block size is a power of 2 in *cryptUpdate */ |
| 192 OPENSSL_assert(ctx->cipher->block_size == 1 |
| 193 || ctx->cipher->block_size == 8 |
| 194 || ctx->cipher->block_size == 16); |
| 195 |
| 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 /* fall-through */ |
| 208 |
| 209 case EVP_CIPH_CBC_MODE: |
| 210 |
| 211 OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= |
| 212 (int)sizeof(ctx->iv)); |
| 213 if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx
)); |
| 214 memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx))
; |
| 215 break; |
| 216 |
| 217 default: |
| 218 return 0; |
| 219 break; |
| 220 } |
| 221 } |
| 222 |
| 223 if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { |
| 224 if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; |
| 225 } |
| 226 ctx->buf_len=0; |
| 227 ctx->final_used=0; |
| 228 ctx->block_mask=ctx->cipher->block_size-1; |
| 229 return 1; |
| 230 } |
| 231 |
95 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 232 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
96 const unsigned char *in, int inl) | 233 const unsigned char *in, int inl) |
97 { | 234 { |
98 if (ctx->encrypt) | 235 if (ctx->encrypt) |
99 return EVP_EncryptUpdate(ctx,out,outl,in,inl); | 236 return EVP_EncryptUpdate(ctx,out,outl,in,inl); |
100 else return EVP_DecryptUpdate(ctx,out,outl,in,inl); | 237 else return EVP_DecryptUpdate(ctx,out,outl,in,inl); |
101 } | 238 } |
102 | 239 |
103 int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | 240 int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
104 { | 241 { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 int i,j,bl; | 281 int i,j,bl; |
145 | 282 |
146 if (inl <= 0) | 283 if (inl <= 0) |
147 { | 284 { |
148 *outl = 0; | 285 *outl = 0; |
149 return inl == 0; | 286 return inl == 0; |
150 } | 287 } |
151 | 288 |
152 if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) | 289 if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) |
153 { | 290 { |
154 » » if(M_do_cipher(ctx,out,in,inl)) | 291 » » if(ctx->cipher->do_cipher(ctx,out,in,inl)) |
155 { | 292 { |
156 *outl=inl; | 293 *outl=inl; |
157 return 1; | 294 return 1; |
158 } | 295 } |
159 else | 296 else |
160 { | 297 { |
161 *outl=0; | 298 *outl=0; |
162 return 0; | 299 return 0; |
163 } | 300 } |
164 } | 301 } |
165 i=ctx->buf_len; | 302 i=ctx->buf_len; |
166 bl=ctx->cipher->block_size; | 303 bl=ctx->cipher->block_size; |
167 OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); | 304 OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); |
168 if (i != 0) | 305 if (i != 0) |
169 { | 306 { |
170 if (i+inl < bl) | 307 if (i+inl < bl) |
171 { | 308 { |
172 memcpy(&(ctx->buf[i]),in,inl); | 309 memcpy(&(ctx->buf[i]),in,inl); |
173 ctx->buf_len+=inl; | 310 ctx->buf_len+=inl; |
174 *outl=0; | 311 *outl=0; |
175 return 1; | 312 return 1; |
176 } | 313 } |
177 else | 314 else |
178 { | 315 { |
179 j=bl-i; | 316 j=bl-i; |
180 memcpy(&(ctx->buf[i]),in,j); | 317 memcpy(&(ctx->buf[i]),in,j); |
181 » » » if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0; | 318 » » » if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return
0; |
182 inl-=j; | 319 inl-=j; |
183 in+=j; | 320 in+=j; |
184 out+=bl; | 321 out+=bl; |
185 *outl=bl; | 322 *outl=bl; |
186 } | 323 } |
187 } | 324 } |
188 else | 325 else |
189 *outl = 0; | 326 *outl = 0; |
190 i=inl&(bl-1); | 327 i=inl&(bl-1); |
191 inl-=i; | 328 inl-=i; |
192 if (inl > 0) | 329 if (inl > 0) |
193 { | 330 { |
194 » » if(!M_do_cipher(ctx,out,in,inl)) return 0; | 331 » » if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0; |
195 *outl+=inl; | 332 *outl+=inl; |
196 } | 333 } |
197 | 334 |
198 if (i != 0) | 335 if (i != 0) |
199 memcpy(ctx->buf,&(in[inl]),i); | 336 memcpy(ctx->buf,&(in[inl]),i); |
200 ctx->buf_len=i; | 337 ctx->buf_len=i; |
201 return 1; | 338 return 1; |
202 } | 339 } |
203 | 340 |
204 int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | 341 int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
(...skipping 23 matching lines...) Expand all Loading... |
228 EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE
_OF_BLOCK_LENGTH); | 365 EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE
_OF_BLOCK_LENGTH); |
229 return 0; | 366 return 0; |
230 } | 367 } |
231 *outl = 0; | 368 *outl = 0; |
232 return 1; | 369 return 1; |
233 } | 370 } |
234 | 371 |
235 n=b-bl; | 372 n=b-bl; |
236 for (i=bl; i<b; i++) | 373 for (i=bl; i<b; i++) |
237 ctx->buf[i]=n; | 374 ctx->buf[i]=n; |
238 » ret=M_do_cipher(ctx,out,ctx->buf,b); | 375 » ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b); |
239 | 376 |
240 | 377 |
241 if(ret) | 378 if(ret) |
242 *outl=b; | 379 *outl=b; |
243 | 380 |
244 return ret; | 381 return ret; |
245 } | 382 } |
246 | 383 |
247 int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 384 int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
248 const unsigned char *in, int inl) | 385 const unsigned char *in, int inl) |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 | 487 |
351 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) | 488 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) |
352 { | 489 { |
353 if (ctx) | 490 if (ctx) |
354 { | 491 { |
355 EVP_CIPHER_CTX_cleanup(ctx); | 492 EVP_CIPHER_CTX_cleanup(ctx); |
356 OPENSSL_free(ctx); | 493 OPENSSL_free(ctx); |
357 } | 494 } |
358 } | 495 } |
359 | 496 |
| 497 int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) |
| 498 { |
| 499 if (c->cipher != NULL) |
| 500 { |
| 501 if(c->cipher->cleanup && !c->cipher->cleanup(c)) |
| 502 return 0; |
| 503 /* Cleanse cipher context data */ |
| 504 if (c->cipher_data) |
| 505 OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); |
| 506 } |
| 507 if (c->cipher_data) |
| 508 OPENSSL_free(c->cipher_data); |
| 509 #ifndef OPENSSL_NO_ENGINE |
| 510 if (c->engine) |
| 511 /* The EVP_CIPHER we used belongs to an ENGINE, release the |
| 512 * functional reference we held for this reason. */ |
| 513 ENGINE_finish(c->engine); |
| 514 #endif |
| 515 memset(c,0,sizeof(EVP_CIPHER_CTX)); |
| 516 return 1; |
| 517 } |
| 518 |
360 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) | 519 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) |
361 { | 520 { |
362 if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) | 521 if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) |
363 return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, N
ULL); | 522 return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, N
ULL); |
364 if(c->key_len == keylen) return 1; | 523 if(c->key_len == keylen) return 1; |
365 if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) | 524 if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) |
366 { | 525 { |
367 c->key_len = keylen; | 526 c->key_len = keylen; |
368 return 1; | 527 return 1; |
369 } | 528 } |
370 EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH); | 529 EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH); |
371 return 0; | 530 return 0; |
372 } | 531 } |
373 | 532 |
374 int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) | 533 int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) |
375 { | 534 { |
376 if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING; | 535 if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING; |
377 else ctx->flags |= EVP_CIPH_NO_PADDING; | 536 else ctx->flags |= EVP_CIPH_NO_PADDING; |
378 return 1; | 537 return 1; |
379 } | 538 } |
380 | 539 |
| 540 int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) |
| 541 { |
| 542 int ret; |
| 543 if(!ctx->cipher) { |
| 544 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); |
| 545 return 0; |
| 546 } |
| 547 |
| 548 if(!ctx->cipher->ctrl) { |
| 549 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); |
| 550 return 0; |
| 551 } |
| 552 |
| 553 ret = ctx->cipher->ctrl(ctx, type, arg, ptr); |
| 554 if(ret == -1) { |
| 555 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLE
MENTED); |
| 556 return 0; |
| 557 } |
| 558 return ret; |
| 559 } |
| 560 |
381 int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) | 561 int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) |
382 { | 562 { |
383 if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) | 563 if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) |
384 return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); | 564 return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); |
385 if (RAND_bytes(key, ctx->key_len) <= 0) | 565 if (RAND_bytes(key, ctx->key_len) <= 0) |
386 return 0; | 566 return 0; |
387 return 1; | 567 return 1; |
388 } | 568 } |
389 | 569 |
| 570 int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) |
| 571 { |
| 572 if ((in == NULL) || (in->cipher == NULL)) |
| 573 { |
| 574 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED); |
| 575 return 0; |
| 576 } |
390 #ifndef OPENSSL_NO_ENGINE | 577 #ifndef OPENSSL_NO_ENGINE |
| 578 /* Make sure it's safe to copy a cipher context using an ENGINE */ |
| 579 if (in->engine && !ENGINE_init(in->engine)) |
| 580 { |
| 581 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB); |
| 582 return 0; |
| 583 } |
| 584 #endif |
391 | 585 |
392 #ifdef OPENSSL_FIPS | 586 » EVP_CIPHER_CTX_cleanup(out); |
| 587 » memcpy(out,in,sizeof *out); |
393 | 588 |
394 static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciphe
r, ENGINE *impl) | 589 » if (in->cipher_data && in->cipher->ctx_size) |
395 » { | |
396 » if(impl) | |
397 { | 590 { |
398 » » if (!ENGINE_init(impl)) | 591 » » out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size); |
| 592 » » if (!out->cipher_data) |
399 { | 593 { |
400 » » » EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATIO
N_ERROR); | 594 » » » EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE); |
401 return 0; | 595 return 0; |
402 } | 596 } |
| 597 memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size); |
403 } | 598 } |
404 » else | 599 |
405 » » /* Ask if an ENGINE is reserved for this job */ | 600 » if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) |
406 » » impl = ENGINE_get_cipher_engine((*pcipher)->nid); | 601 » » return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0,
out); |
407 » if(impl) | |
408 » » { | |
409 » » /* There's an ENGINE for this job ... (apparently) */ | |
410 » » const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid); | |
411 » » if(!c) | |
412 » » » { | |
413 » » » /* One positive side-effect of US's export | |
414 » » » * control history, is that we should at least | |
415 » » » * be able to avoid using US mispellings of | |
416 » » » * "initialisation"? */ | |
417 » » » EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATIO
N_ERROR); | |
418 » » » return 0; | |
419 » » » } | |
420 » » /* We'll use the ENGINE's private cipher definition */ | |
421 » » *pcipher = c; | |
422 » » /* Store the ENGINE functional reference so we know | |
423 » » * 'cipher' came from an ENGINE and we need to release | |
424 » » * it when done. */ | |
425 » » ctx->engine = impl; | |
426 » » } | |
427 » else | |
428 » » ctx->engine = NULL; | |
429 return 1; | 602 return 1; |
430 } | 603 } |
431 | 604 |
432 void int_EVP_CIPHER_init_engine_callbacks(void) | |
433 { | |
434 int_EVP_CIPHER_set_engine_callbacks( | |
435 ENGINE_finish, do_evp_enc_engine_full); | |
436 } | |
437 | |
438 #endif | |
439 | |
440 #endif | |
OLD | NEW |