Home | History | Annotate | Download | only in evp
      1 /* crypto/evp/evp_enc.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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