os/ossrv/ssl/libcrypto/src/crypto/evp/evp_enc.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* crypto/evp/evp_enc.c */
sl@0
     2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
sl@0
    59
#include <stdio.h>
sl@0
    60
#include "cryptlib.h"
sl@0
    61
#include <openssl/evp.h>
sl@0
    62
#include <openssl/err.h>
sl@0
    63
#include <openssl/rand.h>
sl@0
    64
#ifndef OPENSSL_NO_ENGINE
sl@0
    65
#include <openssl/engine.h>
sl@0
    66
#endif
sl@0
    67
#include "evp_locl.h"
sl@0
    68
sl@0
    69
const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
sl@0
    70
sl@0
    71
EXPORT_C void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
sl@0
    72
	{
sl@0
    73
	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
sl@0
    74
	/* ctx->cipher=NULL; */
sl@0
    75
	}
sl@0
    76
sl@0
    77
EXPORT_C EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
sl@0
    78
	{
sl@0
    79
	EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
sl@0
    80
	if (ctx)
sl@0
    81
		EVP_CIPHER_CTX_init(ctx);
sl@0
    82
	return ctx;
sl@0
    83
	}
sl@0
    84
sl@0
    85
EXPORT_C int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
sl@0
    86
	     const unsigned char *key, const unsigned char *iv, int enc)
sl@0
    87
	{
sl@0
    88
	if (cipher)
sl@0
    89
		EVP_CIPHER_CTX_init(ctx);
sl@0
    90
	return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
sl@0
    91
	}
sl@0
    92
sl@0
    93
EXPORT_C int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
sl@0
    94
	     const unsigned char *key, const unsigned char *iv, int enc)
sl@0
    95
	{
sl@0
    96
	if (enc == -1)
sl@0
    97
		enc = ctx->encrypt;
sl@0
    98
	else
sl@0
    99
		{
sl@0
   100
		if (enc)
sl@0
   101
			enc = 1;
sl@0
   102
		ctx->encrypt = enc;
sl@0
   103
		}
sl@0
   104
#ifndef OPENSSL_NO_ENGINE
sl@0
   105
	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
sl@0
   106
	 * so this context may already have an ENGINE! Try to avoid releasing
sl@0
   107
	 * the previous handle, re-querying for an ENGINE, and having a
sl@0
   108
	 * reinitialisation, when it may all be unecessary. */
sl@0
   109
	if (ctx->engine && ctx->cipher && (!cipher ||
sl@0
   110
			(cipher && (cipher->nid == ctx->cipher->nid))))
sl@0
   111
		goto skip_to_init;
sl@0
   112
#endif
sl@0
   113
	if (cipher)
sl@0
   114
		{
sl@0
   115
		/* Ensure a context left lying around from last time is cleared
sl@0
   116
		 * (the previous check attempted to avoid this if the same
sl@0
   117
		 * ENGINE and EVP_CIPHER could be used). */
sl@0
   118
		EVP_CIPHER_CTX_cleanup(ctx);
sl@0
   119
sl@0
   120
		/* Restore encrypt field: it is zeroed by cleanup */
sl@0
   121
		ctx->encrypt = enc;
sl@0
   122
#ifndef OPENSSL_NO_ENGINE
sl@0
   123
		if(impl)
sl@0
   124
			{
sl@0
   125
			if (!ENGINE_init(impl))
sl@0
   126
				{
sl@0
   127
				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
sl@0
   128
				return 0;
sl@0
   129
				}
sl@0
   130
			}
sl@0
   131
		else
sl@0
   132
			/* Ask if an ENGINE is reserved for this job */
sl@0
   133
			impl = ENGINE_get_cipher_engine(cipher->nid);
sl@0
   134
		if(impl)
sl@0
   135
			{
sl@0
   136
			/* There's an ENGINE for this job ... (apparently) */
sl@0
   137
			const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
sl@0
   138
			if(!c)
sl@0
   139
				{
sl@0
   140
				/* One positive side-effect of US's export
sl@0
   141
				 * control history, is that we should at least
sl@0
   142
				 * be able to avoid using US mispellings of
sl@0
   143
				 * "initialisation"? */
sl@0
   144
				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
sl@0
   145
				return 0;
sl@0
   146
				}
sl@0
   147
			/* We'll use the ENGINE's private cipher definition */
sl@0
   148
			cipher = c;
sl@0
   149
			/* Store the ENGINE functional reference so we know
sl@0
   150
			 * 'cipher' came from an ENGINE and we need to release
sl@0
   151
			 * it when done. */
sl@0
   152
			ctx->engine = impl;
sl@0
   153
			}
sl@0
   154
		else
sl@0
   155
			ctx->engine = NULL;
sl@0
   156
#endif
sl@0
   157
sl@0
   158
		ctx->cipher=cipher;
sl@0
   159
		if (ctx->cipher->ctx_size)
sl@0
   160
			{
sl@0
   161
			ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
sl@0
   162
			if (!ctx->cipher_data)
sl@0
   163
				{
sl@0
   164
				EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
sl@0
   165
				return 0;
sl@0
   166
				}
sl@0
   167
			}
sl@0
   168
		else
sl@0
   169
			{
sl@0
   170
			ctx->cipher_data = NULL;
sl@0
   171
			}
sl@0
   172
		ctx->key_len = cipher->key_len;
sl@0
   173
		ctx->flags = 0;
sl@0
   174
		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
sl@0
   175
			{
sl@0
   176
			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
sl@0
   177
				{
sl@0
   178
				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
sl@0
   179
				return 0;
sl@0
   180
				}
sl@0
   181
			}
sl@0
   182
		}
sl@0
   183
	else if(!ctx->cipher)
sl@0
   184
		{
sl@0
   185
		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
sl@0
   186
		return 0;
sl@0
   187
		}
sl@0
   188
#ifndef OPENSSL_NO_ENGINE
sl@0
   189
skip_to_init:
sl@0
   190
#endif
sl@0
   191
	/* we assume block size is a power of 2 in *cryptUpdate */
sl@0
   192
	OPENSSL_assert(ctx->cipher->block_size == 1
sl@0
   193
	    || ctx->cipher->block_size == 8
sl@0
   194
	    || ctx->cipher->block_size == 16);
sl@0
   195
sl@0
   196
	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
sl@0
   197
		switch(EVP_CIPHER_CTX_mode(ctx)) {
sl@0
   198
sl@0
   199
			case EVP_CIPH_STREAM_CIPHER:
sl@0
   200
			case EVP_CIPH_ECB_MODE:
sl@0
   201
			break;
sl@0
   202
sl@0
   203
			case EVP_CIPH_CFB_MODE:
sl@0
   204
			case EVP_CIPH_OFB_MODE:
sl@0
   205
sl@0
   206
			ctx->num = 0;
sl@0
   207
sl@0
   208
			case EVP_CIPH_CBC_MODE:
sl@0
   209
sl@0
   210
			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
sl@0
   211
					(int)sizeof(ctx->iv));
sl@0
   212
			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
sl@0
   213
			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
sl@0
   214
			break;
sl@0
   215
sl@0
   216
			default:
sl@0
   217
			return 0;
sl@0
   218
			break;
sl@0
   219
		}
sl@0
   220
	}
sl@0
   221
sl@0
   222
	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
sl@0
   223
		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
sl@0
   224
	}
sl@0
   225
	ctx->buf_len=0;
sl@0
   226
	ctx->final_used=0;
sl@0
   227
	ctx->block_mask=ctx->cipher->block_size-1;
sl@0
   228
	return 1;
sl@0
   229
	}
sl@0
   230
sl@0
   231
EXPORT_C int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
sl@0
   232
	     const unsigned char *in, int inl)
sl@0
   233
	{
sl@0
   234
	if (ctx->encrypt)
sl@0
   235
		return EVP_EncryptUpdate(ctx,out,outl,in,inl);
sl@0
   236
	else	return EVP_DecryptUpdate(ctx,out,outl,in,inl);
sl@0
   237
	}
sl@0
   238
sl@0
   239
EXPORT_C int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
sl@0
   240
	{
sl@0
   241
	if (ctx->encrypt)
sl@0
   242
		return EVP_EncryptFinal_ex(ctx,out,outl);
sl@0
   243
	else	return EVP_DecryptFinal_ex(ctx,out,outl);
sl@0
   244
	}
sl@0
   245
sl@0
   246
EXPORT_C int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
sl@0
   247
	{
sl@0
   248
	if (ctx->encrypt)
sl@0
   249
		return EVP_EncryptFinal(ctx,out,outl);
sl@0
   250
	else	return EVP_DecryptFinal(ctx,out,outl);
sl@0
   251
	}
sl@0
   252
sl@0
   253
EXPORT_C int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
sl@0
   254
	     const unsigned char *key, const unsigned char *iv)
sl@0
   255
	{
sl@0
   256
	return EVP_CipherInit(ctx, cipher, key, iv, 1);
sl@0
   257
	}
sl@0
   258
sl@0
   259
EXPORT_C int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
sl@0
   260
		const unsigned char *key, const unsigned char *iv)
sl@0
   261
	{
sl@0
   262
	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
sl@0
   263
	}
sl@0
   264
sl@0
   265
EXPORT_C int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
sl@0
   266
	     const unsigned char *key, const unsigned char *iv)
sl@0
   267
	{
sl@0
   268
	return EVP_CipherInit(ctx, cipher, key, iv, 0);
sl@0
   269
	}
sl@0
   270
sl@0
   271
EXPORT_C int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
sl@0
   272
	     const unsigned char *key, const unsigned char *iv)
sl@0
   273
	{
sl@0
   274
	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
sl@0
   275
	}
sl@0
   276
sl@0
   277
EXPORT_C int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
sl@0
   278
	     const unsigned char *in, int inl)
sl@0
   279
	{
sl@0
   280
	int i,j,bl;
sl@0
   281
sl@0
   282
	OPENSSL_assert(inl > 0);
sl@0
   283
	if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
sl@0
   284
		{
sl@0
   285
		if(ctx->cipher->do_cipher(ctx,out,in,inl))
sl@0
   286
			{
sl@0
   287
			*outl=inl;
sl@0
   288
			return 1;
sl@0
   289
			}
sl@0
   290
		else
sl@0
   291
			{
sl@0
   292
			*outl=0;
sl@0
   293
			return 0;
sl@0
   294
			}
sl@0
   295
		}
sl@0
   296
	i=ctx->buf_len;
sl@0
   297
	bl=ctx->cipher->block_size;
sl@0
   298
	OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
sl@0
   299
	if (i != 0)
sl@0
   300
		{
sl@0
   301
		if (i+inl < bl)
sl@0
   302
			{
sl@0
   303
			memcpy(&(ctx->buf[i]),in,inl);
sl@0
   304
			ctx->buf_len+=inl;
sl@0
   305
			*outl=0;
sl@0
   306
			return 1;
sl@0
   307
			}
sl@0
   308
		else
sl@0
   309
			{
sl@0
   310
			j=bl-i;
sl@0
   311
			memcpy(&(ctx->buf[i]),in,j);
sl@0
   312
			if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
sl@0
   313
			inl-=j;
sl@0
   314
			in+=j;
sl@0
   315
			out+=bl;
sl@0
   316
			*outl=bl;
sl@0
   317
			}
sl@0
   318
		}
sl@0
   319
	else
sl@0
   320
		*outl = 0;
sl@0
   321
	i=inl&(bl-1);
sl@0
   322
	inl-=i;
sl@0
   323
	if (inl > 0)
sl@0
   324
		{
sl@0
   325
		if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
sl@0
   326
		*outl+=inl;
sl@0
   327
		}
sl@0
   328
sl@0
   329
	if (i != 0)
sl@0
   330
		memcpy(ctx->buf,&(in[inl]),i);
sl@0
   331
	ctx->buf_len=i;
sl@0
   332
	return 1;
sl@0
   333
	}
sl@0
   334
sl@0
   335
EXPORT_C int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
sl@0
   336
	{
sl@0
   337
	int ret;
sl@0
   338
	ret = EVP_EncryptFinal_ex(ctx, out, outl);
sl@0
   339
	return ret;
sl@0
   340
	}
sl@0
   341
sl@0
   342
EXPORT_C int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
sl@0
   343
	{
sl@0
   344
	int n,ret;
sl@0
   345
	unsigned int i, b, bl;
sl@0
   346
sl@0
   347
	b=ctx->cipher->block_size;
sl@0
   348
	OPENSSL_assert(b <= sizeof ctx->buf);
sl@0
   349
	if (b == 1)
sl@0
   350
		{
sl@0
   351
		*outl=0;
sl@0
   352
		return 1;
sl@0
   353
		}
sl@0
   354
	bl=ctx->buf_len;
sl@0
   355
	if (ctx->flags & EVP_CIPH_NO_PADDING)
sl@0
   356
		{
sl@0
   357
		if(bl)
sl@0
   358
			{
sl@0
   359
			EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
sl@0
   360
			return 0;
sl@0
   361
			}
sl@0
   362
		*outl = 0;
sl@0
   363
		return 1;
sl@0
   364
		}
sl@0
   365
sl@0
   366
	n=b-bl;
sl@0
   367
	for (i=bl; i<b; i++)
sl@0
   368
		ctx->buf[i]=n;
sl@0
   369
	ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
sl@0
   370
sl@0
   371
sl@0
   372
	if(ret)
sl@0
   373
		*outl=b;
sl@0
   374
sl@0
   375
	return ret;
sl@0
   376
	}
sl@0
   377
sl@0
   378
EXPORT_C int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
sl@0
   379
	     const unsigned char *in, int inl)
sl@0
   380
	{
sl@0
   381
	int fix_len;
sl@0
   382
	unsigned int b;
sl@0
   383
sl@0
   384
	if (inl == 0)
sl@0
   385
		{
sl@0
   386
		*outl=0;
sl@0
   387
		return 1;
sl@0
   388
		}
sl@0
   389
sl@0
   390
	if (ctx->flags & EVP_CIPH_NO_PADDING)
sl@0
   391
		return EVP_EncryptUpdate(ctx, out, outl, in, inl);
sl@0
   392
sl@0
   393
	b=ctx->cipher->block_size;
sl@0
   394
	OPENSSL_assert(b <= sizeof ctx->final);
sl@0
   395
sl@0
   396
	if(ctx->final_used)
sl@0
   397
		{
sl@0
   398
		memcpy(out,ctx->final,b);
sl@0
   399
		out+=b;
sl@0
   400
		fix_len = 1;
sl@0
   401
		}
sl@0
   402
	else
sl@0
   403
		fix_len = 0;
sl@0
   404
sl@0
   405
sl@0
   406
	if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
sl@0
   407
		return 0;
sl@0
   408
sl@0
   409
	/* if we have 'decrypted' a multiple of block size, make sure
sl@0
   410
	 * we have a copy of this last block */
sl@0
   411
	if (b > 1 && !ctx->buf_len)
sl@0
   412
		{
sl@0
   413
		*outl-=b;
sl@0
   414
		ctx->final_used=1;
sl@0
   415
		memcpy(ctx->final,&out[*outl],b);
sl@0
   416
		}
sl@0
   417
	else
sl@0
   418
		ctx->final_used = 0;
sl@0
   419
sl@0
   420
	if (fix_len)
sl@0
   421
		*outl += b;
sl@0
   422
		
sl@0
   423
	return 1;
sl@0
   424
	}
sl@0
   425
sl@0
   426
EXPORT_C int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
sl@0
   427
	{
sl@0
   428
	int ret;
sl@0
   429
	ret = EVP_DecryptFinal_ex(ctx, out, outl);
sl@0
   430
	return ret;
sl@0
   431
	}
sl@0
   432
sl@0
   433
EXPORT_C int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
sl@0
   434
	{
sl@0
   435
	int i,n;
sl@0
   436
	unsigned int b;
sl@0
   437
sl@0
   438
	*outl=0;
sl@0
   439
	b=ctx->cipher->block_size;
sl@0
   440
	if (ctx->flags & EVP_CIPH_NO_PADDING)
sl@0
   441
		{
sl@0
   442
		if(ctx->buf_len)
sl@0
   443
			{
sl@0
   444
			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
sl@0
   445
			return 0;
sl@0
   446
			}
sl@0
   447
		*outl = 0;
sl@0
   448
		return 1;
sl@0
   449
		}
sl@0
   450
	if (b > 1)
sl@0
   451
		{
sl@0
   452
		if (ctx->buf_len || !ctx->final_used)
sl@0
   453
			{
sl@0
   454
			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
sl@0
   455
			return(0);
sl@0
   456
			}
sl@0
   457
		OPENSSL_assert(b <= sizeof ctx->final);
sl@0
   458
		n=ctx->final[b-1];
sl@0
   459
		if (n == 0 || n > (int)b)
sl@0
   460
			{
sl@0
   461
			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
sl@0
   462
			return(0);
sl@0
   463
			}
sl@0
   464
		for (i=0; i<n; i++)
sl@0
   465
			{
sl@0
   466
			if (ctx->final[--b] != n)
sl@0
   467
				{
sl@0
   468
				EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
sl@0
   469
				return(0);
sl@0
   470
				}
sl@0
   471
			}
sl@0
   472
		n=ctx->cipher->block_size-n;
sl@0
   473
		for (i=0; i<n; i++)
sl@0
   474
			out[i]=ctx->final[i];
sl@0
   475
		*outl=n;
sl@0
   476
		}
sl@0
   477
	else
sl@0
   478
		*outl=0;
sl@0
   479
	return(1);
sl@0
   480
	}
sl@0
   481
sl@0
   482
EXPORT_C void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
sl@0
   483
	{
sl@0
   484
	if (ctx)
sl@0
   485
		{
sl@0
   486
		EVP_CIPHER_CTX_cleanup(ctx);
sl@0
   487
		OPENSSL_free(ctx);
sl@0
   488
		}
sl@0
   489
	}
sl@0
   490
EXPORT_C int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
sl@0
   491
	{
sl@0
   492
	if (c->cipher != NULL)
sl@0
   493
		{
sl@0
   494
		if(c->cipher->cleanup && !c->cipher->cleanup(c))
sl@0
   495
			return 0;
sl@0
   496
		/* Cleanse cipher context data */
sl@0
   497
		if (c->cipher_data)
sl@0
   498
			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
sl@0
   499
		}
sl@0
   500
	if (c->cipher_data)
sl@0
   501
		OPENSSL_free(c->cipher_data);
sl@0
   502
#ifndef OPENSSL_NO_ENGINE
sl@0
   503
	if (c->engine)
sl@0
   504
		/* The EVP_CIPHER we used belongs to an ENGINE, release the
sl@0
   505
		 * functional reference we held for this reason. */
sl@0
   506
		ENGINE_finish(c->engine);
sl@0
   507
#endif
sl@0
   508
	memset(c,0,sizeof(EVP_CIPHER_CTX));
sl@0
   509
	return 1;
sl@0
   510
	}
sl@0
   511
sl@0
   512
EXPORT_C int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
sl@0
   513
	{
sl@0
   514
	if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
sl@0
   515
		return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
sl@0
   516
	if(c->key_len == keylen) return 1;
sl@0
   517
	if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
sl@0
   518
		{
sl@0
   519
		c->key_len = keylen;
sl@0
   520
		return 1;
sl@0
   521
		}
sl@0
   522
	EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
sl@0
   523
	return 0;
sl@0
   524
	}
sl@0
   525
sl@0
   526
EXPORT_C int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
sl@0
   527
	{
sl@0
   528
	if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
sl@0
   529
	else ctx->flags |= EVP_CIPH_NO_PADDING;
sl@0
   530
	return 1;
sl@0
   531
	}
sl@0
   532
sl@0
   533
EXPORT_C int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
sl@0
   534
{
sl@0
   535
	int ret;
sl@0
   536
	if(!ctx->cipher) {
sl@0
   537
		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
sl@0
   538
		return 0;
sl@0
   539
	}
sl@0
   540
sl@0
   541
	if(!ctx->cipher->ctrl) {
sl@0
   542
		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
sl@0
   543
		return 0;
sl@0
   544
	}
sl@0
   545
sl@0
   546
	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
sl@0
   547
	if(ret == -1) {
sl@0
   548
		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
sl@0
   549
		return 0;
sl@0
   550
	}
sl@0
   551
	return ret;
sl@0
   552
}
sl@0
   553
sl@0
   554
EXPORT_C int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
sl@0
   555
	{
sl@0
   556
	if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
sl@0
   557
		return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
sl@0
   558
	if (RAND_bytes(key, ctx->key_len) <= 0)
sl@0
   559
		return 0;
sl@0
   560
	return 1;
sl@0
   561
	}
sl@0
   562