Zero cipher_data in EVP_CIPHER_CTX_cleanup

Add cleanup calls to evp_test.c

Allow reuse of cipher contexts by removing
automatic cleanup in EVP_*Final().
This commit is contained in:
Dr. Stephen Henson 2002-05-15 18:49:25 +00:00
parent 60e5f36d27
commit 544a2aea4b
3 changed files with 26 additions and 16 deletions

View File

@ -55,6 +55,14 @@
Changes between 0.9.6d and 0.9.7 [XX xxx 2002] Changes between 0.9.6d and 0.9.7 [XX xxx 2002]
*) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this
allows existing EVP_CIPHER_CTX structures to be reused after
calling EVP_*Final(). This behaviour is used by encryption
BIOs and some applications. This has the side effect that
applications must explicitly clean up cipher contexts with
EVP_CIPHER_CTX_cleanup() or they will leak memory.
[Steve Henson]
*) Check the values of dna and dnb in bn_mul_recursive before calling *) Check the values of dna and dnb in bn_mul_recursive before calling
bn_mul_comba (a non zero value means the a or b arrays do not contain bn_mul_comba (a non zero value means the a or b arrays do not contain
n2 elements) and fallback to bn_mul_normal if either is not zero. n2 elements) and fallback to bn_mul_normal if either is not zero.

View File

@ -102,11 +102,13 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
goto skip_to_init; goto skip_to_init;
if (cipher) if (cipher)
{ {
/* Ensure an ENGINE left lying around from last time is cleared /* Ensure a context left lying around from last time is cleared
* (the previous check attempted to avoid this if the same * (the previous check attempted to avoid this if the same
* ENGINE and EVP_CIPHER could be used). */ * ENGINE and EVP_CIPHER could be used). */
if(ctx->engine) EVP_CIPHER_CTX_cleanup(ctx);
ENGINE_finish(ctx->engine);
/* Restore encrypt field: it is zeroed by cleanup */
ctx->encrypt = enc;
if(impl) if(impl)
{ {
if (!ENGINE_init(impl)) if (!ENGINE_init(impl))
@ -140,6 +142,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
} }
else else
ctx->engine = NULL; ctx->engine = NULL;
ctx->cipher=cipher; ctx->cipher=cipher;
ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
ctx->key_len = cipher->key_len; ctx->key_len = cipher->key_len;
@ -303,7 +306,6 @@ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{ {
int ret; int ret;
ret = EVP_EncryptFinal_ex(ctx, out, outl); ret = EVP_EncryptFinal_ex(ctx, out, outl);
EVP_CIPHER_CTX_cleanup(ctx);
return ret; return ret;
} }
@ -314,14 +316,12 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
b=ctx->cipher->block_size; b=ctx->cipher->block_size;
if (b == 1) if (b == 1)
{ {
EVP_CIPHER_CTX_cleanup(ctx);
*outl=0; *outl=0;
return 1; return 1;
} }
bl=ctx->buf_len; bl=ctx->buf_len;
if (ctx->flags & EVP_CIPH_NO_PADDING) if (ctx->flags & EVP_CIPH_NO_PADDING)
{ {
EVP_CIPHER_CTX_cleanup(ctx);
if(bl) if(bl)
{ {
EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
@ -336,7 +336,6 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
ctx->buf[i]=n; ctx->buf[i]=n;
ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b); ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
EVP_CIPHER_CTX_cleanup(ctx);
if(ret) if(ret)
*outl=b; *outl=b;
@ -394,7 +393,6 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{ {
int ret; int ret;
ret = EVP_DecryptFinal_ex(ctx, out, outl); ret = EVP_DecryptFinal_ex(ctx, out, outl);
EVP_CIPHER_CTX_cleanup(ctx);
return ret; return ret;
} }
@ -407,7 +405,6 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
b=ctx->cipher->block_size; b=ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING) if (ctx->flags & EVP_CIPH_NO_PADDING)
{ {
EVP_CIPHER_CTX_cleanup(ctx);
if(ctx->buf_len) if(ctx->buf_len)
{ {
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
@ -420,14 +417,12 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{ {
if (ctx->buf_len || !ctx->final_used) if (ctx->buf_len || !ctx->final_used)
{ {
EVP_CIPHER_CTX_cleanup(ctx);
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH); EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
return(0); return(0);
} }
n=ctx->final[b-1]; n=ctx->final[b-1];
if (n > b) if (n > b)
{ {
EVP_CIPHER_CTX_cleanup(ctx);
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
return(0); return(0);
} }
@ -435,7 +430,6 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{ {
if (ctx->final[--b] != n) if (ctx->final[--b] != n)
{ {
EVP_CIPHER_CTX_cleanup(ctx);
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
return(0); return(0);
} }
@ -447,17 +441,21 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
} }
else else
*outl=0; *outl=0;
EVP_CIPHER_CTX_cleanup(ctx);
return(1); return(1);
} }
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
{ {
if ((c->cipher != NULL) && (c->cipher->cleanup != NULL)) if (c->cipher != NULL)
{ {
if(!c->cipher->cleanup(c)) return 0; if(c->cipher->cleanup && !c->cipher->cleanup(c))
return 0;
/* Zero cipher context data */
if (c->cipher_data)
memset(c->cipher_data, 0, c->cipher->ctx_size);
} }
OPENSSL_free(c->cipher_data); if (c->cipher_data)
OPENSSL_free(c->cipher_data);
if (c->engine) if (c->engine)
/* The EVP_CIPHER we used belongs to an ENGINE, release the /* The EVP_CIPHER we used belongs to an ENGINE, release the
* functional reference we held for this reason. */ * functional reference we held for this reason. */

View File

@ -209,6 +209,8 @@ static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
exit(9); exit(9);
} }
EVP_CIPHER_CTX_cleanup(&ctx);
printf("\n"); printf("\n");
} }
@ -279,6 +281,8 @@ static int test_digest(const char *digest,
printf("\n"); printf("\n");
EVP_MD_CTX_cleanup(&ctx);
return 1; return 1;
} }