67
67
#include "evp_locl.h"
70
#define M_do_cipher(ctx, out, in, inl) \
71
EVP_Cipher(ctx,out,in,inl)
73
#define M_do_cipher(ctx, out, in, inl) \
74
ctx->cipher->do_cipher(ctx,out,in,inl)
77
69
const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
71
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
73
memset(ctx,0,sizeof(EVP_CIPHER_CTX));
74
/* ctx->cipher=NULL; */
79
77
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
81
79
EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
92
90
return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
93
int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
94
const unsigned char *key, const unsigned char *iv, int enc)
104
#ifndef OPENSSL_NO_ENGINE
105
/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
106
* so this context may already have an ENGINE! Try to avoid releasing
107
* the previous handle, re-querying for an ENGINE, and having a
108
* reinitialisation, when it may all be unecessary. */
109
if (ctx->engine && ctx->cipher && (!cipher ||
110
(cipher && (cipher->nid == ctx->cipher->nid))))
115
/* Ensure a context left lying around from last time is cleared
116
* (the previous check attempted to avoid this if the same
117
* ENGINE and EVP_CIPHER could be used). */
118
EVP_CIPHER_CTX_cleanup(ctx);
120
/* Restore encrypt field: it is zeroed by cleanup */
122
#ifndef OPENSSL_NO_ENGINE
125
if (!ENGINE_init(impl))
127
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
132
/* Ask if an ENGINE is reserved for this job */
133
impl = ENGINE_get_cipher_engine(cipher->nid);
136
/* There's an ENGINE for this job ... (apparently) */
137
const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
140
/* One positive side-effect of US's export
141
* control history, is that we should at least
142
* be able to avoid using US mispellings of
143
* "initialisation"? */
144
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
147
/* We'll use the ENGINE's private cipher definition */
149
/* Store the ENGINE functional reference so we know
150
* 'cipher' came from an ENGINE and we need to release
159
if (ctx->cipher->ctx_size)
161
ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
162
if (!ctx->cipher_data)
164
EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
170
ctx->cipher_data = NULL;
172
ctx->key_len = cipher->key_len;
174
if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
176
if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
178
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
183
else if(!ctx->cipher)
185
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
188
#ifndef OPENSSL_NO_ENGINE
191
/* we assume block size is a power of 2 in *cryptUpdate */
192
OPENSSL_assert(ctx->cipher->block_size == 1
193
|| ctx->cipher->block_size == 8
194
|| ctx->cipher->block_size == 16);
196
if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
197
switch(EVP_CIPHER_CTX_mode(ctx)) {
199
case EVP_CIPH_STREAM_CIPHER:
200
case EVP_CIPH_ECB_MODE:
203
case EVP_CIPH_CFB_MODE:
204
case EVP_CIPH_OFB_MODE:
209
case EVP_CIPH_CBC_MODE:
211
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
212
(int)sizeof(ctx->iv));
213
if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
214
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
223
if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
224
if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
228
ctx->block_mask=ctx->cipher->block_size-1;
95
232
int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
96
233
const unsigned char *in, int inl)
497
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
499
if (c->cipher != NULL)
501
if(c->cipher->cleanup && !c->cipher->cleanup(c))
503
/* Cleanse cipher context data */
505
OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
508
OPENSSL_free(c->cipher_data);
509
#ifndef OPENSSL_NO_ENGINE
511
/* The EVP_CIPHER we used belongs to an ENGINE, release the
512
* functional reference we held for this reason. */
513
ENGINE_finish(c->engine);
515
memset(c,0,sizeof(EVP_CIPHER_CTX));
360
519
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
362
521
if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
540
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
544
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
548
if(!ctx->cipher->ctrl) {
549
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
553
ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
555
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
381
561
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
383
563
if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
570
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
572
if ((in == NULL) || (in->cipher == NULL))
574
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
390
577
#ifndef OPENSSL_NO_ENGINE
394
static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
398
if (!ENGINE_init(impl))
400
EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
405
/* Ask if an ENGINE is reserved for this job */
406
impl = ENGINE_get_cipher_engine((*pcipher)->nid);
409
/* There's an ENGINE for this job ... (apparently) */
410
const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid);
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);
420
/* We'll use the ENGINE's private cipher definition */
422
/* Store the ENGINE functional reference so we know
423
* 'cipher' came from an ENGINE and we need to release
578
/* Make sure it's safe to copy a cipher context using an ENGINE */
579
if (in->engine && !ENGINE_init(in->engine))
581
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB);
586
EVP_CIPHER_CTX_cleanup(out);
587
memcpy(out,in,sizeof *out);
589
if (in->cipher_data && in->cipher->ctx_size)
591
out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
592
if (!out->cipher_data)
594
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
597
memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
600
if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
601
return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
432
void int_EVP_CIPHER_init_engine_callbacks(void)
434
int_EVP_CIPHER_set_engine_callbacks(
435
ENGINE_finish, do_evp_enc_engine_full);