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. 8296465Sdelphij * 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). 15296465Sdelphij * 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. 22296465Sdelphij * 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 :-). 37296465Sdelphij * 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)" 40296465Sdelphij * 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. 52296465Sdelphij * 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> 6268651Skris#include <openssl/err.h> 63160814Ssimon#include <openssl/rand.h> 64111147Snectar#ifndef OPENSSL_NO_ENGINE 65296465Sdelphij# include <openssl/engine.h> 66111147Snectar#endif 6768651Skris#include "evp_locl.h" 6855714Skris 69194206Ssimon#ifdef OPENSSL_FIPS 70296465Sdelphij# define M_do_cipher(ctx, out, in, inl) \ 71296465Sdelphij EVP_Cipher(ctx,out,in,inl) 72194206Ssimon#else 73296465Sdelphij# define M_do_cipher(ctx, out, in, inl) \ 74296465Sdelphij ctx->cipher->do_cipher(ctx,out,in,inl) 75194206Ssimon#endif 76194206Ssimon 77296465Sdelphijconst char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT; 7855714Skris 79160814SsimonEVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) 80296465Sdelphij{ 81296465Sdelphij EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof *ctx); 82296465Sdelphij if (ctx) 83296465Sdelphij EVP_CIPHER_CTX_init(ctx); 84296465Sdelphij return ctx; 85296465Sdelphij} 86109998Smarkm 8768651Skrisint EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 88296465Sdelphij const unsigned char *key, const unsigned char *iv, int enc) 89296465Sdelphij{ 90296465Sdelphij if (cipher) 91296465Sdelphij EVP_CIPHER_CTX_init(ctx); 92296465Sdelphij return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); 93296465Sdelphij} 94109998Smarkm 9568651Skrisint EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 96296465Sdelphij const unsigned char *in, int inl) 97296465Sdelphij{ 98296465Sdelphij if (ctx->encrypt) 99296465Sdelphij return EVP_EncryptUpdate(ctx, out, outl, in, inl); 100296465Sdelphij else 101296465Sdelphij return EVP_DecryptUpdate(ctx, out, outl, in, inl); 102296465Sdelphij} 10355714Skris 104109998Smarkmint EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 105296465Sdelphij{ 106296465Sdelphij if (ctx->encrypt) 107296465Sdelphij return EVP_EncryptFinal_ex(ctx, out, outl); 108296465Sdelphij else 109296465Sdelphij return EVP_DecryptFinal_ex(ctx, out, outl); 110296465Sdelphij} 111109998Smarkm 11255714Skrisint EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 113296465Sdelphij{ 114296465Sdelphij if (ctx->encrypt) 115296465Sdelphij return EVP_EncryptFinal(ctx, out, outl); 116296465Sdelphij else 117296465Sdelphij return EVP_DecryptFinal(ctx, out, outl); 118296465Sdelphij} 11955714Skris 12068651Skrisint EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 121296465Sdelphij const unsigned char *key, const unsigned char *iv) 122296465Sdelphij{ 123296465Sdelphij return EVP_CipherInit(ctx, cipher, key, iv, 1); 124296465Sdelphij} 12555714Skris 126296465Sdelphijint EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 127296465Sdelphij ENGINE *impl, const unsigned char *key, 128296465Sdelphij const unsigned char *iv) 129296465Sdelphij{ 130296465Sdelphij return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); 131296465Sdelphij} 132109998Smarkm 13368651Skrisint EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 134296465Sdelphij const unsigned char *key, const unsigned char *iv) 135296465Sdelphij{ 136296465Sdelphij return EVP_CipherInit(ctx, cipher, key, iv, 0); 137296465Sdelphij} 13855714Skris 139296465Sdelphijint EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 140296465Sdelphij ENGINE *impl, const unsigned char *key, 141296465Sdelphij const unsigned char *iv) 142296465Sdelphij{ 143296465Sdelphij return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); 144296465Sdelphij} 14555714Skris 14668651Skrisint EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 147296465Sdelphij const unsigned char *in, int inl) 148296465Sdelphij{ 149296465Sdelphij int i, j, bl; 15055714Skris 151296465Sdelphij if (inl <= 0) { 152296465Sdelphij *outl = 0; 153296465Sdelphij return inl == 0; 154296465Sdelphij } 155194206Ssimon 156296465Sdelphij if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) { 157296465Sdelphij if (M_do_cipher(ctx, out, in, inl)) { 158296465Sdelphij *outl = inl; 159296465Sdelphij return 1; 160296465Sdelphij } else { 161296465Sdelphij *outl = 0; 162296465Sdelphij return 0; 163296465Sdelphij } 164296465Sdelphij } 165296465Sdelphij i = ctx->buf_len; 166296465Sdelphij bl = ctx->cipher->block_size; 167296465Sdelphij OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); 168296465Sdelphij if (i != 0) { 169299068Sdelphij if (bl - i > inl) { 170296465Sdelphij memcpy(&(ctx->buf[i]), in, inl); 171296465Sdelphij ctx->buf_len += inl; 172296465Sdelphij *outl = 0; 173296465Sdelphij return 1; 174296465Sdelphij } else { 175296465Sdelphij j = bl - i; 176296465Sdelphij memcpy(&(ctx->buf[i]), in, j); 177296465Sdelphij if (!M_do_cipher(ctx, out, ctx->buf, bl)) 178296465Sdelphij return 0; 179296465Sdelphij inl -= j; 180296465Sdelphij in += j; 181296465Sdelphij out += bl; 182296465Sdelphij *outl = bl; 183296465Sdelphij } 184296465Sdelphij } else 185296465Sdelphij *outl = 0; 186296465Sdelphij i = inl & (bl - 1); 187296465Sdelphij inl -= i; 188296465Sdelphij if (inl > 0) { 189296465Sdelphij if (!M_do_cipher(ctx, out, in, inl)) 190296465Sdelphij return 0; 191296465Sdelphij *outl += inl; 192296465Sdelphij } 19355714Skris 194296465Sdelphij if (i != 0) 195296465Sdelphij memcpy(ctx->buf, &(in[inl]), i); 196296465Sdelphij ctx->buf_len = i; 197296465Sdelphij return 1; 198296465Sdelphij} 19955714Skris 20068651Skrisint EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 201296465Sdelphij{ 202296465Sdelphij int ret; 203296465Sdelphij ret = EVP_EncryptFinal_ex(ctx, out, outl); 204296465Sdelphij return ret; 205296465Sdelphij} 20655714Skris 207109998Smarkmint EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 208296465Sdelphij{ 209296465Sdelphij int n, ret; 210296465Sdelphij unsigned int i, b, bl; 211109998Smarkm 212296465Sdelphij b = ctx->cipher->block_size; 213296465Sdelphij OPENSSL_assert(b <= sizeof ctx->buf); 214296465Sdelphij if (b == 1) { 215296465Sdelphij *outl = 0; 216296465Sdelphij return 1; 217296465Sdelphij } 218296465Sdelphij bl = ctx->buf_len; 219296465Sdelphij if (ctx->flags & EVP_CIPH_NO_PADDING) { 220296465Sdelphij if (bl) { 221296465Sdelphij EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, 222296465Sdelphij EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 223296465Sdelphij return 0; 224296465Sdelphij } 225296465Sdelphij *outl = 0; 226296465Sdelphij return 1; 227296465Sdelphij } 228109998Smarkm 229296465Sdelphij n = b - bl; 230296465Sdelphij for (i = bl; i < b; i++) 231296465Sdelphij ctx->buf[i] = n; 232296465Sdelphij ret = M_do_cipher(ctx, out, ctx->buf, b); 233109998Smarkm 234296465Sdelphij if (ret) 235296465Sdelphij *outl = b; 236109998Smarkm 237296465Sdelphij return ret; 238296465Sdelphij} 239109998Smarkm 24068651Skrisint EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 241296465Sdelphij const unsigned char *in, int inl) 242296465Sdelphij{ 243296465Sdelphij int fix_len; 244296465Sdelphij unsigned int b; 24555714Skris 246296465Sdelphij if (inl <= 0) { 247296465Sdelphij *outl = 0; 248296465Sdelphij return inl == 0; 249296465Sdelphij } 25055714Skris 251296465Sdelphij if (ctx->flags & EVP_CIPH_NO_PADDING) 252296465Sdelphij return EVP_EncryptUpdate(ctx, out, outl, in, inl); 253109998Smarkm 254296465Sdelphij b = ctx->cipher->block_size; 255296465Sdelphij OPENSSL_assert(b <= sizeof ctx->final); 256109998Smarkm 257296465Sdelphij if (ctx->final_used) { 258296465Sdelphij memcpy(out, ctx->final, b); 259296465Sdelphij out += b; 260296465Sdelphij fix_len = 1; 261296465Sdelphij } else 262296465Sdelphij fix_len = 0; 26355714Skris 264296465Sdelphij if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) 265296465Sdelphij return 0; 266109998Smarkm 267296465Sdelphij /* 268296465Sdelphij * if we have 'decrypted' a multiple of block size, make sure we have a 269296465Sdelphij * copy of this last block 270296465Sdelphij */ 271296465Sdelphij if (b > 1 && !ctx->buf_len) { 272296465Sdelphij *outl -= b; 273296465Sdelphij ctx->final_used = 1; 274296465Sdelphij memcpy(ctx->final, &out[*outl], b); 275296465Sdelphij } else 276296465Sdelphij ctx->final_used = 0; 277109998Smarkm 278296465Sdelphij if (fix_len) 279296465Sdelphij *outl += b; 280109998Smarkm 281296465Sdelphij return 1; 282296465Sdelphij} 28355714Skris 28455714Skrisint EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 285296465Sdelphij{ 286296465Sdelphij int ret; 287296465Sdelphij ret = EVP_DecryptFinal_ex(ctx, out, outl); 288296465Sdelphij return ret; 289296465Sdelphij} 290109998Smarkm 291109998Smarkmint EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 292296465Sdelphij{ 293296465Sdelphij int i, n; 294296465Sdelphij unsigned int b; 29555714Skris 296296465Sdelphij *outl = 0; 297296465Sdelphij b = ctx->cipher->block_size; 298296465Sdelphij if (ctx->flags & EVP_CIPH_NO_PADDING) { 299296465Sdelphij if (ctx->buf_len) { 300296465Sdelphij EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, 301296465Sdelphij EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 302296465Sdelphij return 0; 303296465Sdelphij } 304296465Sdelphij *outl = 0; 305296465Sdelphij return 1; 306296465Sdelphij } 307296465Sdelphij if (b > 1) { 308296465Sdelphij if (ctx->buf_len || !ctx->final_used) { 309296465Sdelphij EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH); 310296465Sdelphij return (0); 311296465Sdelphij } 312296465Sdelphij OPENSSL_assert(b <= sizeof ctx->final); 313296465Sdelphij n = ctx->final[b - 1]; 314296465Sdelphij if (n == 0 || n > (int)b) { 315296465Sdelphij EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); 316296465Sdelphij return (0); 317296465Sdelphij } 318296465Sdelphij for (i = 0; i < n; i++) { 319296465Sdelphij if (ctx->final[--b] != n) { 320296465Sdelphij EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); 321296465Sdelphij return (0); 322296465Sdelphij } 323296465Sdelphij } 324296465Sdelphij n = ctx->cipher->block_size - n; 325296465Sdelphij for (i = 0; i < n; i++) 326296465Sdelphij out[i] = ctx->final[i]; 327296465Sdelphij *outl = n; 328296465Sdelphij } else 329296465Sdelphij *outl = 0; 330296465Sdelphij return (1); 331296465Sdelphij} 33255714Skris 333160814Ssimonvoid EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) 334296465Sdelphij{ 335296465Sdelphij if (ctx) { 336296465Sdelphij EVP_CIPHER_CTX_cleanup(ctx); 337296465Sdelphij OPENSSL_free(ctx); 338296465Sdelphij } 339296465Sdelphij} 340160814Ssimon 34168651Skrisint EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) 342296465Sdelphij{ 343296465Sdelphij if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 344296465Sdelphij return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); 345296465Sdelphij if (c->key_len == keylen) 346296465Sdelphij return 1; 347296465Sdelphij if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { 348296465Sdelphij c->key_len = keylen; 349296465Sdelphij return 1; 350296465Sdelphij } 351296465Sdelphij EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH); 352296465Sdelphij return 0; 353296465Sdelphij} 35468651Skris 355109998Smarkmint EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) 356296465Sdelphij{ 357296465Sdelphij if (pad) 358296465Sdelphij ctx->flags &= ~EVP_CIPH_NO_PADDING; 359296465Sdelphij else 360296465Sdelphij ctx->flags |= EVP_CIPH_NO_PADDING; 361296465Sdelphij return 1; 362296465Sdelphij} 363109998Smarkm 364160814Ssimonint EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) 365296465Sdelphij{ 366296465Sdelphij if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) 367296465Sdelphij return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); 368296465Sdelphij if (RAND_bytes(key, ctx->key_len) <= 0) 369296465Sdelphij return 0; 370296465Sdelphij return 1; 371296465Sdelphij} 372160814Ssimon 373194206Ssimon#ifndef OPENSSL_NO_ENGINE 374194206Ssimon 375296465Sdelphij# ifdef OPENSSL_FIPS 376194206Ssimon 377296465Sdelphijstatic int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, 378296465Sdelphij const EVP_CIPHER **pcipher, ENGINE *impl) 379296465Sdelphij{ 380296465Sdelphij if (impl) { 381296465Sdelphij if (!ENGINE_init(impl)) { 382296465Sdelphij EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); 383296465Sdelphij return 0; 384296465Sdelphij } 385296465Sdelphij } else 386296465Sdelphij /* Ask if an ENGINE is reserved for this job */ 387296465Sdelphij impl = ENGINE_get_cipher_engine((*pcipher)->nid); 388296465Sdelphij if (impl) { 389296465Sdelphij /* There's an ENGINE for this job ... (apparently) */ 390296465Sdelphij const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid); 391296465Sdelphij if (!c) { 392296465Sdelphij /* 393296465Sdelphij * One positive side-effect of US's export control history, is 394296465Sdelphij * that we should at least be able to avoid using US mispellings 395296465Sdelphij * of "initialisation"? 396296465Sdelphij */ 397296465Sdelphij EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); 398296465Sdelphij return 0; 399296465Sdelphij } 400296465Sdelphij /* We'll use the ENGINE's private cipher definition */ 401296465Sdelphij *pcipher = c; 402296465Sdelphij /* 403296465Sdelphij * Store the ENGINE functional reference so we know 'cipher' came 404296465Sdelphij * from an ENGINE and we need to release it when done. 405296465Sdelphij */ 406296465Sdelphij ctx->engine = impl; 407296465Sdelphij } else 408296465Sdelphij ctx->engine = NULL; 409296465Sdelphij return 1; 410296465Sdelphij} 411194206Ssimon 412194206Ssimonvoid int_EVP_CIPHER_init_engine_callbacks(void) 413296465Sdelphij{ 414296465Sdelphij int_EVP_CIPHER_set_engine_callbacks(ENGINE_finish, 415296465Sdelphij do_evp_enc_engine_full); 416296465Sdelphij} 417194206Ssimon 418296465Sdelphij# endif 419194206Ssimon 420194206Ssimon#endif 421