diff options
Diffstat (limited to 'openssl/crypto/evp/evp_enc.c')
-rw-r--r-- | openssl/crypto/evp/evp_enc.c | 95 |
1 files changed, 86 insertions, 9 deletions
diff --git a/openssl/crypto/evp/evp_enc.c b/openssl/crypto/evp/evp_enc.c index c268d25cb..691072655 100644 --- a/openssl/crypto/evp/evp_enc.c +++ b/openssl/crypto/evp/evp_enc.c @@ -64,8 +64,18 @@ #ifndef OPENSSL_NO_ENGINE #include <openssl/engine.h> #endif +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif #include "evp_locl.h" +#ifdef OPENSSL_FIPS +#define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl) +#else +#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl) +#endif + + const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) @@ -115,10 +125,14 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp /* Ensure a context left lying around from last time is cleared * (the previous check attempted to avoid this if the same * ENGINE and EVP_CIPHER could be used). */ - EVP_CIPHER_CTX_cleanup(ctx); - - /* Restore encrypt field: it is zeroed by cleanup */ - ctx->encrypt = enc; + if (ctx->cipher) + { + unsigned long flags = ctx->flags; + EVP_CIPHER_CTX_cleanup(ctx); + /* Restore encrypt and flags */ + ctx->encrypt = enc; + ctx->flags = flags; + } #ifndef OPENSSL_NO_ENGINE if(impl) { @@ -155,6 +169,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp ctx->engine = NULL; #endif +#ifdef OPENSSL_FIPS + return FIPS_cipherinit(ctx, cipher, key, iv, enc); +#else ctx->cipher=cipher; if (ctx->cipher->ctx_size) { @@ -179,6 +196,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp return 0; } } +#endif } else if(!ctx->cipher) { @@ -188,6 +206,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp #ifndef OPENSSL_NO_ENGINE skip_to_init: #endif +#ifdef OPENSSL_FIPS + return FIPS_cipherinit(ctx, cipher, key, iv, enc); +#else /* we assume block size is a power of 2 in *cryptUpdate */ OPENSSL_assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 @@ -214,6 +235,13 @@ skip_to_init: memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); break; + case EVP_CIPH_CTR_MODE: + ctx->num = 0; + /* Don't reuse IV for CTR mode */ + if(iv) + memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + default: return 0; break; @@ -227,6 +255,7 @@ skip_to_init: ctx->final_used=0; ctx->block_mask=ctx->cipher->block_size-1; return 1; +#endif } int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, @@ -280,6 +309,16 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, { int i,j,bl; + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) + { + i = M_do_cipher(ctx, out, in, inl); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + if (inl <= 0) { *outl = 0; @@ -288,7 +327,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) { - if(ctx->cipher->do_cipher(ctx,out,in,inl)) + if(M_do_cipher(ctx,out,in,inl)) { *outl=inl; return 1; @@ -315,7 +354,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, { j=bl-i; memcpy(&(ctx->buf[i]),in,j); - if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0; + if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0; inl-=j; in+=j; out+=bl; @@ -328,7 +367,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, inl-=i; if (inl > 0) { - if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0; + if(!M_do_cipher(ctx,out,in,inl)) return 0; *outl+=inl; } @@ -350,6 +389,16 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int n,ret; unsigned int i, b, bl; + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) + { + ret = M_do_cipher(ctx, out, NULL, 0); + if (ret < 0) + return 0; + else + *outl = ret; + return 1; + } + b=ctx->cipher->block_size; OPENSSL_assert(b <= sizeof ctx->buf); if (b == 1) @@ -372,7 +421,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) n=b-bl; for (i=bl; i<b; i++) ctx->buf[i]=n; - ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b); + ret=M_do_cipher(ctx,out,ctx->buf,b); if(ret) @@ -387,6 +436,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, int fix_len; unsigned int b; + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) + { + fix_len = M_do_cipher(ctx, out, in, inl); + if (fix_len < 0) + { + *outl = 0; + return 0; + } + else + *outl = fix_len; + return 1; + } + if (inl <= 0) { *outl = 0; @@ -440,8 +502,18 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int i,n; unsigned int b; - *outl=0; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) + { + i = M_do_cipher(ctx, out, NULL, 0); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + b=ctx->cipher->block_size; if (ctx->flags & EVP_CIPH_NO_PADDING) { @@ -496,6 +568,7 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { +#ifndef OPENSSL_FIPS if (c->cipher != NULL) { if(c->cipher->cleanup && !c->cipher->cleanup(c)) @@ -506,12 +579,16 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) } if (c->cipher_data) OPENSSL_free(c->cipher_data); +#endif #ifndef OPENSSL_NO_ENGINE if (c->engine) /* The EVP_CIPHER we used belongs to an ENGINE, release the * functional reference we held for this reason. */ ENGINE_finish(c->engine); #endif +#ifdef OPENSSL_FIPS + FIPS_cipher_ctx_cleanup(c); +#endif memset(c,0,sizeof(EVP_CIPHER_CTX)); return 1; } |