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