evp_enc.c revision 55714
155714Skris/* crypto/evp/evp_enc.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include "cryptlib.h" 6155714Skris#include <openssl/evp.h> 6255714Skris 6355714Skrisconst char *EVP_version="EVP" OPENSSL_VERSION_PTEXT; 6455714Skris 6555714Skrisvoid EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) 6655714Skris { 6755714Skris memset(ctx,0,sizeof(EVP_CIPHER_CTX)); 6855714Skris /* ctx->cipher=NULL; */ 6955714Skris } 7055714Skris 7155714Skrisvoid EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *data, 7255714Skris unsigned char *key, unsigned char *iv, int enc) 7355714Skris { 7455714Skris if (enc) 7555714Skris EVP_EncryptInit(ctx,data,key,iv); 7655714Skris else 7755714Skris EVP_DecryptInit(ctx,data,key,iv); 7855714Skris } 7955714Skris 8055714Skrisvoid EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 8155714Skris unsigned char *in, int inl) 8255714Skris { 8355714Skris if (ctx->encrypt) 8455714Skris EVP_EncryptUpdate(ctx,out,outl,in,inl); 8555714Skris else EVP_DecryptUpdate(ctx,out,outl,in,inl); 8655714Skris } 8755714Skris 8855714Skrisint EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 8955714Skris { 9055714Skris if (ctx->encrypt) 9155714Skris { 9255714Skris EVP_EncryptFinal(ctx,out,outl); 9355714Skris return(1); 9455714Skris } 9555714Skris else return(EVP_DecryptFinal(ctx,out,outl)); 9655714Skris } 9755714Skris 9855714Skrisvoid EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 9955714Skris unsigned char *key, unsigned char *iv) 10055714Skris { 10155714Skris if (cipher != NULL) 10255714Skris ctx->cipher=cipher; 10355714Skris ctx->cipher->init(ctx,key,iv,1); 10455714Skris ctx->encrypt=1; 10555714Skris ctx->buf_len=0; 10655714Skris } 10755714Skris 10855714Skrisvoid EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 10955714Skris unsigned char *key, unsigned char *iv) 11055714Skris { 11155714Skris if (cipher != NULL) 11255714Skris ctx->cipher=cipher; 11355714Skris ctx->cipher->init(ctx,key,iv,0); 11455714Skris ctx->encrypt=0; 11555714Skris ctx->buf_len=0; 11655714Skris } 11755714Skris 11855714Skris 11955714Skrisvoid EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 12055714Skris unsigned char *in, int inl) 12155714Skris { 12255714Skris int i,j,bl; 12355714Skris 12455714Skris i=ctx->buf_len; 12555714Skris bl=ctx->cipher->block_size; 12655714Skris *outl=0; 12755714Skris if ((inl == 0) && (i != bl)) return; 12855714Skris if (i != 0) 12955714Skris { 13055714Skris if (i+inl < bl) 13155714Skris { 13255714Skris memcpy(&(ctx->buf[i]),in,inl); 13355714Skris ctx->buf_len+=inl; 13455714Skris return; 13555714Skris } 13655714Skris else 13755714Skris { 13855714Skris j=bl-i; 13955714Skris if (j != 0) memcpy(&(ctx->buf[i]),in,j); 14055714Skris ctx->cipher->do_cipher(ctx,out,ctx->buf,bl); 14155714Skris inl-=j; 14255714Skris in+=j; 14355714Skris out+=bl; 14455714Skris *outl+=bl; 14555714Skris } 14655714Skris } 14755714Skris i=inl%bl; /* how much is left */ 14855714Skris inl-=i; 14955714Skris if (inl > 0) 15055714Skris { 15155714Skris ctx->cipher->do_cipher(ctx,out,in,inl); 15255714Skris *outl+=inl; 15355714Skris } 15455714Skris 15555714Skris if (i != 0) 15655714Skris memcpy(ctx->buf,&(in[inl]),i); 15755714Skris ctx->buf_len=i; 15855714Skris } 15955714Skris 16055714Skrisvoid EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 16155714Skris { 16255714Skris int i,n,b,bl; 16355714Skris 16455714Skris b=ctx->cipher->block_size; 16555714Skris if (b == 1) 16655714Skris { 16755714Skris *outl=0; 16855714Skris return; 16955714Skris } 17055714Skris bl=ctx->buf_len; 17155714Skris n=b-bl; 17255714Skris for (i=bl; i<b; i++) 17355714Skris ctx->buf[i]=n; 17455714Skris ctx->cipher->do_cipher(ctx,out,ctx->buf,b); 17555714Skris *outl=b; 17655714Skris } 17755714Skris 17855714Skrisvoid EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 17955714Skris unsigned char *in, int inl) 18055714Skris { 18155714Skris int b,bl,n; 18255714Skris int keep_last=0; 18355714Skris 18455714Skris *outl=0; 18555714Skris if (inl == 0) return; 18655714Skris 18755714Skris b=ctx->cipher->block_size; 18855714Skris if (b > 1) 18955714Skris { 19055714Skris /* Is the input a multiple of the block size? */ 19155714Skris bl=ctx->buf_len; 19255714Skris n=inl+bl; 19355714Skris if (n%b == 0) 19455714Skris { 19555714Skris if (inl < b) /* must be 'just one' buff */ 19655714Skris { 19755714Skris memcpy(&(ctx->buf[bl]),in,inl); 19855714Skris ctx->buf_len=b; 19955714Skris *outl=0; 20055714Skris return; 20155714Skris } 20255714Skris keep_last=1; 20355714Skris inl-=b; /* don't do the last block */ 20455714Skris } 20555714Skris } 20655714Skris EVP_EncryptUpdate(ctx,out,outl,in,inl); 20755714Skris 20855714Skris /* if we have 'decrypted' a multiple of block size, make sure 20955714Skris * we have a copy of this last block */ 21055714Skris if (keep_last) 21155714Skris { 21255714Skris memcpy(&(ctx->buf[0]),&(in[inl]),b); 21355714Skris#ifdef DEBUG 21455714Skris if (ctx->buf_len != 0) 21555714Skris { 21655714Skris abort(); 21755714Skris } 21855714Skris#endif 21955714Skris ctx->buf_len=b; 22055714Skris } 22155714Skris } 22255714Skris 22355714Skrisint EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 22455714Skris { 22555714Skris int i,b; 22655714Skris int n; 22755714Skris 22855714Skris *outl=0; 22955714Skris b=ctx->cipher->block_size; 23055714Skris if (b > 1) 23155714Skris { 23255714Skris if (ctx->buf_len != b) 23355714Skris { 23455714Skris EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH); 23555714Skris return(0); 23655714Skris } 23755714Skris EVP_EncryptUpdate(ctx,ctx->buf,&n,ctx->buf,0); 23855714Skris if (n != b) 23955714Skris return(0); 24055714Skris n=ctx->buf[b-1]; 24155714Skris if (n > b) 24255714Skris { 24355714Skris EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); 24455714Skris return(0); 24555714Skris } 24655714Skris for (i=0; i<n; i++) 24755714Skris { 24855714Skris if (ctx->buf[--b] != n) 24955714Skris { 25055714Skris EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); 25155714Skris return(0); 25255714Skris } 25355714Skris } 25455714Skris n=ctx->cipher->block_size-n; 25555714Skris for (i=0; i<n; i++) 25655714Skris out[i]=ctx->buf[i]; 25755714Skris *outl=n; 25855714Skris } 25955714Skris else 26055714Skris *outl=0; 26155714Skris return(1); 26255714Skris } 26355714Skris 26455714Skrisvoid EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) 26555714Skris { 26655714Skris if ((c->cipher != NULL) && (c->cipher->cleanup != NULL)) 26755714Skris c->cipher->cleanup(c); 26855714Skris memset(c,0,sizeof(EVP_CIPHER_CTX)); 26955714Skris } 27055714Skris 271