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 #include <openssl/rand.h> 64 #ifndef OPENSSL_NO_ENGINE 65 #include <openssl/engine.h> 66 #endif 67 #include "evp_locl.h" 68 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 76 77 const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; 78 79 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) 80 { 81 EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx); 82 if (ctx) 83 EVP_CIPHER_CTX_init(ctx); 84 return ctx; 85 } 86 87 int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 88 const unsigned char *key, const unsigned char *iv, int enc) 89 { 90 if (cipher) 91 EVP_CIPHER_CTX_init(ctx); 92 return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); 93 } 94 95 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 96 const unsigned char *in, int inl) 97 { 98 if (ctx->encrypt) 99 return EVP_EncryptUpdate(ctx,out,outl,in,inl); 100 else return EVP_DecryptUpdate(ctx,out,outl,in,inl); 101 } 102 103 int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 104 { 105 if (ctx->encrypt) 106 return EVP_EncryptFinal_ex(ctx,out,outl); 107 else return EVP_DecryptFinal_ex(ctx,out,outl); 108 } 109 110 int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 111 { 112 if (ctx->encrypt) 113 return EVP_EncryptFinal(ctx,out,outl); 114 else return EVP_DecryptFinal(ctx,out,outl); 115 } 116 117 int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 118 const unsigned char *key, const unsigned char *iv) 119 { 120 return EVP_CipherInit(ctx, cipher, key, iv, 1); 121 } 122 123 int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, 124 const unsigned char *key, const unsigned char *iv) 125 { 126 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); 127 } 128 129 int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 130 const unsigned char *key, const unsigned char *iv) 131 { 132 return EVP_CipherInit(ctx, cipher, key, iv, 0); 133 } 134 135 int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, 136 const unsigned char *key, const unsigned char *iv) 137 { 138 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); 139 } 140 141 int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 142 const unsigned char *in, int inl) 143 { 144 int i,j,bl; 145 146 if (inl <= 0) 147 { 148 *outl = 0; 149 return inl == 0; 150 } 151 152 if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) 153 { 154 if(M_do_cipher(ctx,out,in,inl)) 155 { 156 *outl=inl; 157 return 1; 158 } 159 else 160 { 161 *outl=0; 162 return 0; 163 } 164 } 165 i=ctx->buf_len; 166 bl=ctx->cipher->block_size; 167 OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); 168 if (i != 0) 169 { 170 if (i+inl < bl) 171 { 172 memcpy(&(ctx->buf[i]),in,inl); 173 ctx->buf_len+=inl; 174 *outl=0; 175 return 1; 176 } 177 else 178 { 179 j=bl-i; 180 memcpy(&(ctx->buf[i]),in,j); 181 if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0; 182 inl-=j; 183 in+=j; 184 out+=bl; 185 *outl=bl; 186 } 187 } 188 else 189 *outl = 0; 190 i=inl&(bl-1); 191 inl-=i; 192 if (inl > 0) 193 { 194 if(!M_do_cipher(ctx,out,in,inl)) return 0; 195 *outl+=inl; 196 } 197 198 if (i != 0) 199 memcpy(ctx->buf,&(in[inl]),i); 200 ctx->buf_len=i; 201 return 1; 202 } 203 204 int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 205 { 206 int ret; 207 ret = EVP_EncryptFinal_ex(ctx, out, outl); 208 return ret; 209 } 210 211 int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 212 { 213 int n,ret; 214 unsigned int i, b, bl; 215 216 b=ctx->cipher->block_size; 217 OPENSSL_assert(b <= sizeof ctx->buf); 218 if (b == 1) 219 { 220 *outl=0; 221 return 1; 222 } 223 bl=ctx->buf_len; 224 if (ctx->flags & EVP_CIPH_NO_PADDING) 225 { 226 if(bl) 227 { 228 EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 229 return 0; 230 } 231 *outl = 0; 232 return 1; 233 } 234 235 n=b-bl; 236 for (i=bl; i<b; i++) 237 ctx->buf[i]=n; 238 ret=M_do_cipher(ctx,out,ctx->buf,b); 239 240 241 if(ret) 242 *outl=b; 243 244 return ret; 245 } 246 247 int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 248 const unsigned char *in, int inl) 249 { 250 int fix_len; 251 unsigned int b; 252 253 if (inl <= 0) 254 { 255 *outl = 0; 256 return inl == 0; 257 } 258 259 if (ctx->flags & EVP_CIPH_NO_PADDING) 260 return EVP_EncryptUpdate(ctx, out, outl, in, inl); 261 262 b=ctx->cipher->block_size; 263 OPENSSL_assert(b <= sizeof ctx->final); 264 265 if(ctx->final_used) 266 { 267 memcpy(out,ctx->final,b); 268 out+=b; 269 fix_len = 1; 270 } 271 else 272 fix_len = 0; 273 274 275 if(!EVP_EncryptUpdate(ctx,out,outl,in,inl)) 276 return 0; 277 278 /* if we have 'decrypted' a multiple of block size, make sure 279 * we have a copy of this last block */ 280 if (b > 1 && !ctx->buf_len) 281 { 282 *outl-=b; 283 ctx->final_used=1; 284 memcpy(ctx->final,&out[*outl],b); 285 } 286 else 287 ctx->final_used = 0; 288 289 if (fix_len) 290 *outl += b; 291 292 return 1; 293 } 294 295 int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 296 { 297 int ret; 298 ret = EVP_DecryptFinal_ex(ctx, out, outl); 299 return ret; 300 } 301 302 int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 303 { 304 int i,n; 305 unsigned int b; 306 307 *outl=0; 308 b=ctx->cipher->block_size; 309 if (ctx->flags & EVP_CIPH_NO_PADDING) 310 { 311 if(ctx->buf_len) 312 { 313 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 314 return 0; 315 } 316 *outl = 0; 317 return 1; 318 } 319 if (b > 1) 320 { 321 if (ctx->buf_len || !ctx->final_used) 322 { 323 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH); 324 return(0); 325 } 326 OPENSSL_assert(b <= sizeof ctx->final); 327 n=ctx->final[b-1]; 328 if (n == 0 || n > (int)b) 329 { 330 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT); 331 return(0); 332 } 333 for (i=0; i<n; i++) 334 { 335 if (ctx->final[--b] != n) 336 { 337 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT); 338 return(0); 339 } 340 } 341 n=ctx->cipher->block_size-n; 342 for (i=0; i<n; i++) 343 out[i]=ctx->final[i]; 344 *outl=n; 345 } 346 else 347 *outl=0; 348 return(1); 349 } 350 351 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) 352 { 353 if (ctx) 354 { 355 EVP_CIPHER_CTX_cleanup(ctx); 356 OPENSSL_free(ctx); 357 } 358 } 359 360 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) 361 { 362 if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 363 return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); 364 if(c->key_len == keylen) return 1; 365 if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) 366 { 367 c->key_len = keylen; 368 return 1; 369 } 370 EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH); 371 return 0; 372 } 373 374 int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) 375 { 376 if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING; 377 else ctx->flags |= EVP_CIPH_NO_PADDING; 378 return 1; 379 } 380 381 int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) 382 { 383 if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) 384 return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); 385 if (RAND_bytes(key, ctx->key_len) <= 0) 386 return 0; 387 return 1; 388 } 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 441