evp_enc.c revision 296465
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 77const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT; 78 79EVP_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 87int 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 95int 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 101 return EVP_DecryptUpdate(ctx, out, outl, in, inl); 102} 103 104int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 105{ 106 if (ctx->encrypt) 107 return EVP_EncryptFinal_ex(ctx, out, outl); 108 else 109 return EVP_DecryptFinal_ex(ctx, out, outl); 110} 111 112int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 113{ 114 if (ctx->encrypt) 115 return EVP_EncryptFinal(ctx, out, outl); 116 else 117 return EVP_DecryptFinal(ctx, out, outl); 118} 119 120int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 121 const unsigned char *key, const unsigned char *iv) 122{ 123 return EVP_CipherInit(ctx, cipher, key, iv, 1); 124} 125 126int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 127 ENGINE *impl, const unsigned char *key, 128 const unsigned char *iv) 129{ 130 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); 131} 132 133int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 134 const unsigned char *key, const unsigned char *iv) 135{ 136 return EVP_CipherInit(ctx, cipher, key, iv, 0); 137} 138 139int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 140 ENGINE *impl, const unsigned char *key, 141 const unsigned char *iv) 142{ 143 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); 144} 145 146int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 147 const unsigned char *in, int inl) 148{ 149 int i, j, bl; 150 151 if (inl <= 0) { 152 *outl = 0; 153 return inl == 0; 154 } 155 156 if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) { 157 if (M_do_cipher(ctx, out, in, inl)) { 158 *outl = inl; 159 return 1; 160 } else { 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 if (i + inl < bl) { 170 memcpy(&(ctx->buf[i]), in, inl); 171 ctx->buf_len += inl; 172 *outl = 0; 173 return 1; 174 } else { 175 j = bl - i; 176 memcpy(&(ctx->buf[i]), in, j); 177 if (!M_do_cipher(ctx, out, ctx->buf, bl)) 178 return 0; 179 inl -= j; 180 in += j; 181 out += bl; 182 *outl = bl; 183 } 184 } else 185 *outl = 0; 186 i = inl & (bl - 1); 187 inl -= i; 188 if (inl > 0) { 189 if (!M_do_cipher(ctx, out, in, inl)) 190 return 0; 191 *outl += inl; 192 } 193 194 if (i != 0) 195 memcpy(ctx->buf, &(in[inl]), i); 196 ctx->buf_len = i; 197 return 1; 198} 199 200int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 201{ 202 int ret; 203 ret = EVP_EncryptFinal_ex(ctx, out, outl); 204 return ret; 205} 206 207int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 208{ 209 int n, ret; 210 unsigned int i, b, bl; 211 212 b = ctx->cipher->block_size; 213 OPENSSL_assert(b <= sizeof ctx->buf); 214 if (b == 1) { 215 *outl = 0; 216 return 1; 217 } 218 bl = ctx->buf_len; 219 if (ctx->flags & EVP_CIPH_NO_PADDING) { 220 if (bl) { 221 EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, 222 EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 223 return 0; 224 } 225 *outl = 0; 226 return 1; 227 } 228 229 n = b - bl; 230 for (i = bl; i < b; i++) 231 ctx->buf[i] = n; 232 ret = M_do_cipher(ctx, out, ctx->buf, b); 233 234 if (ret) 235 *outl = b; 236 237 return ret; 238} 239 240int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 241 const unsigned char *in, int inl) 242{ 243 int fix_len; 244 unsigned int b; 245 246 if (inl <= 0) { 247 *outl = 0; 248 return inl == 0; 249 } 250 251 if (ctx->flags & EVP_CIPH_NO_PADDING) 252 return EVP_EncryptUpdate(ctx, out, outl, in, inl); 253 254 b = ctx->cipher->block_size; 255 OPENSSL_assert(b <= sizeof ctx->final); 256 257 if (ctx->final_used) { 258 memcpy(out, ctx->final, b); 259 out += b; 260 fix_len = 1; 261 } else 262 fix_len = 0; 263 264 if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) 265 return 0; 266 267 /* 268 * if we have 'decrypted' a multiple of block size, make sure we have a 269 * copy of this last block 270 */ 271 if (b > 1 && !ctx->buf_len) { 272 *outl -= b; 273 ctx->final_used = 1; 274 memcpy(ctx->final, &out[*outl], b); 275 } else 276 ctx->final_used = 0; 277 278 if (fix_len) 279 *outl += b; 280 281 return 1; 282} 283 284int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 285{ 286 int ret; 287 ret = EVP_DecryptFinal_ex(ctx, out, outl); 288 return ret; 289} 290 291int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 292{ 293 int i, n; 294 unsigned int b; 295 296 *outl = 0; 297 b = ctx->cipher->block_size; 298 if (ctx->flags & EVP_CIPH_NO_PADDING) { 299 if (ctx->buf_len) { 300 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, 301 EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 302 return 0; 303 } 304 *outl = 0; 305 return 1; 306 } 307 if (b > 1) { 308 if (ctx->buf_len || !ctx->final_used) { 309 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH); 310 return (0); 311 } 312 OPENSSL_assert(b <= sizeof ctx->final); 313 n = ctx->final[b - 1]; 314 if (n == 0 || n > (int)b) { 315 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); 316 return (0); 317 } 318 for (i = 0; i < n; i++) { 319 if (ctx->final[--b] != n) { 320 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); 321 return (0); 322 } 323 } 324 n = ctx->cipher->block_size - n; 325 for (i = 0; i < n; i++) 326 out[i] = ctx->final[i]; 327 *outl = n; 328 } else 329 *outl = 0; 330 return (1); 331} 332 333void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) 334{ 335 if (ctx) { 336 EVP_CIPHER_CTX_cleanup(ctx); 337 OPENSSL_free(ctx); 338 } 339} 340 341int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) 342{ 343 if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 344 return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); 345 if (c->key_len == keylen) 346 return 1; 347 if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { 348 c->key_len = keylen; 349 return 1; 350 } 351 EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH); 352 return 0; 353} 354 355int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) 356{ 357 if (pad) 358 ctx->flags &= ~EVP_CIPH_NO_PADDING; 359 else 360 ctx->flags |= EVP_CIPH_NO_PADDING; 361 return 1; 362} 363 364int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) 365{ 366 if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) 367 return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); 368 if (RAND_bytes(key, ctx->key_len) <= 0) 369 return 0; 370 return 1; 371} 372 373#ifndef OPENSSL_NO_ENGINE 374 375# ifdef OPENSSL_FIPS 376 377static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, 378 const EVP_CIPHER **pcipher, ENGINE *impl) 379{ 380 if (impl) { 381 if (!ENGINE_init(impl)) { 382 EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); 383 return 0; 384 } 385 } else 386 /* Ask if an ENGINE is reserved for this job */ 387 impl = ENGINE_get_cipher_engine((*pcipher)->nid); 388 if (impl) { 389 /* There's an ENGINE for this job ... (apparently) */ 390 const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid); 391 if (!c) { 392 /* 393 * One positive side-effect of US's export control history, is 394 * that we should at least be able to avoid using US mispellings 395 * of "initialisation"? 396 */ 397 EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); 398 return 0; 399 } 400 /* We'll use the ENGINE's private cipher definition */ 401 *pcipher = c; 402 /* 403 * Store the ENGINE functional reference so we know 'cipher' came 404 * from an ENGINE and we need to release it when done. 405 */ 406 ctx->engine = impl; 407 } else 408 ctx->engine = NULL; 409 return 1; 410} 411 412void int_EVP_CIPHER_init_engine_callbacks(void) 413{ 414 int_EVP_CIPHER_set_engine_callbacks(ENGINE_finish, 415 do_evp_enc_engine_full); 416} 417 418# endif 419 420#endif 421