diff options
Diffstat (limited to 'src/lib/libcrypto/evp/evp_enc.c')
| -rw-r--r-- | src/lib/libcrypto/evp/evp_enc.c | 254 |
1 files changed, 63 insertions, 191 deletions
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c index 6e582c458d..30e0ca4d9f 100644 --- a/src/lib/libcrypto/evp/evp_enc.c +++ b/src/lib/libcrypto/evp/evp_enc.c | |||
| @@ -66,13 +66,15 @@ | |||
| 66 | #endif | 66 | #endif |
| 67 | #include "evp_locl.h" | 67 | #include "evp_locl.h" |
| 68 | 68 | ||
| 69 | const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; | 69 | #ifdef OPENSSL_FIPS |
| 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 | ||
| 70 | 76 | ||
| 71 | void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) | 77 | const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; |
| 72 | { | ||
| 73 | memset(ctx,0,sizeof(EVP_CIPHER_CTX)); | ||
| 74 | /* ctx->cipher=NULL; */ | ||
| 75 | } | ||
| 76 | 78 | ||
| 77 | EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) | 79 | EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) |
| 78 | { | 80 | { |
| @@ -90,144 +92,6 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | |||
| 90 | return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); | 92 | return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); |
| 91 | } | 93 | } |
| 92 | 94 | ||
| 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 | { | ||
| 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_INITIALIZATION_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->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"? */ | ||
| 144 | EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_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_FAILURE); | ||
| 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_INITIALIZATION_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 | |||
| 208 | case EVP_CIPH_CBC_MODE: | ||
| 209 | |||
| 210 | OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= | ||
| 211 | (int)sizeof(ctx->iv)); | ||
| 212 | if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); | ||
| 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 | } | ||
| 225 | ctx->buf_len=0; | ||
| 226 | ctx->final_used=0; | ||
| 227 | ctx->block_mask=ctx->cipher->block_size-1; | ||
| 228 | return 1; | ||
| 229 | } | ||
| 230 | |||
| 231 | int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 95 | int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
| 232 | const unsigned char *in, int inl) | 96 | const unsigned char *in, int inl) |
| 233 | { | 97 | { |
| @@ -287,7 +151,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
| 287 | 151 | ||
| 288 | if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) | 152 | if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) |
| 289 | { | 153 | { |
| 290 | if(ctx->cipher->do_cipher(ctx,out,in,inl)) | 154 | if(M_do_cipher(ctx,out,in,inl)) |
| 291 | { | 155 | { |
| 292 | *outl=inl; | 156 | *outl=inl; |
| 293 | return 1; | 157 | return 1; |
| @@ -314,7 +178,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
| 314 | { | 178 | { |
| 315 | j=bl-i; | 179 | j=bl-i; |
| 316 | memcpy(&(ctx->buf[i]),in,j); | 180 | memcpy(&(ctx->buf[i]),in,j); |
| 317 | if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0; | 181 | if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0; |
| 318 | inl-=j; | 182 | inl-=j; |
| 319 | in+=j; | 183 | in+=j; |
| 320 | out+=bl; | 184 | out+=bl; |
| @@ -327,7 +191,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
| 327 | inl-=i; | 191 | inl-=i; |
| 328 | if (inl > 0) | 192 | if (inl > 0) |
| 329 | { | 193 | { |
| 330 | if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0; | 194 | if(!M_do_cipher(ctx,out,in,inl)) return 0; |
| 331 | *outl+=inl; | 195 | *outl+=inl; |
| 332 | } | 196 | } |
| 333 | 197 | ||
| @@ -371,7 +235,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | |||
| 371 | n=b-bl; | 235 | n=b-bl; |
| 372 | for (i=bl; i<b; i++) | 236 | for (i=bl; i<b; i++) |
| 373 | ctx->buf[i]=n; | 237 | ctx->buf[i]=n; |
| 374 | ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b); | 238 | ret=M_do_cipher(ctx,out,ctx->buf,b); |
| 375 | 239 | ||
| 376 | 240 | ||
| 377 | if(ret) | 241 | if(ret) |
| @@ -493,28 +357,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) | |||
| 493 | } | 357 | } |
| 494 | } | 358 | } |
| 495 | 359 | ||
| 496 | int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) | ||
| 497 | { | ||
| 498 | if (c->cipher != NULL) | ||
| 499 | { | ||
| 500 | if(c->cipher->cleanup && !c->cipher->cleanup(c)) | ||
| 501 | return 0; | ||
| 502 | /* Cleanse cipher context data */ | ||
| 503 | if (c->cipher_data) | ||
| 504 | OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); | ||
| 505 | } | ||
| 506 | if (c->cipher_data) | ||
| 507 | OPENSSL_free(c->cipher_data); | ||
| 508 | #ifndef OPENSSL_NO_ENGINE | ||
| 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); | ||
| 513 | #endif | ||
| 514 | memset(c,0,sizeof(EVP_CIPHER_CTX)); | ||
| 515 | return 1; | ||
| 516 | } | ||
| 517 | |||
| 518 | int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) | 360 | int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) |
| 519 | { | 361 | { |
| 520 | if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) | 362 | if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) |
| @@ -536,27 +378,6 @@ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) | |||
| 536 | return 1; | 378 | return 1; |
| 537 | } | 379 | } |
| 538 | 380 | ||
| 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 | } | ||
| 559 | |||
| 560 | int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) | 381 | int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) |
| 561 | { | 382 | { |
| 562 | if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) | 383 | if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) |
| @@ -566,3 +387,54 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) | |||
| 566 | return 1; | 387 | return 1; |
| 567 | } | 388 | } |
| 568 | 389 | ||
| 390 | #ifndef OPENSSL_NO_ENGINE | ||
| 391 | |||
| 392 | #ifdef OPENSSL_FIPS | ||
| 393 | |||
| 394 | static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl) | ||
| 395 | { | ||
| 396 | if(impl) | ||
| 397 | { | ||
| 398 | if (!ENGINE_init(impl)) | ||
| 399 | { | ||
| 400 | EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); | ||
| 401 | return 0; | ||
| 402 | } | ||
| 403 | } | ||
| 404 | else | ||
| 405 | /* Ask if an ENGINE is reserved for this job */ | ||
| 406 | impl = ENGINE_get_cipher_engine((*pcipher)->nid); | ||
| 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_INITIALIZATION_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; | ||
| 430 | } | ||
| 431 | |||
| 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 | ||
