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