aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Laurie <ben@openssl.org>2001-07-09 21:00:36 +0000
committerBen Laurie <ben@openssl.org>2001-07-09 21:00:36 +0000
commitc148d7097811c18f277a8559753c770f4ff85771 (patch)
treebc8cd4a5ea62675a5ccb5c51c4d04e146147043a
parent7b6055d1afaf6eed5e422c342be33f34304430b3 (diff)
downloadopenssl-c148d7097811c18f277a8559753c770f4ff85771.tar.gz
A better compromise between encrypt and decrypt (but why isn't it as fast
for encrypt?).
-rw-r--r--CHANGES4
-rw-r--r--crypto/evp/evp.h3
-rw-r--r--crypto/evp/evp_enc.c80
3 files changed, 39 insertions, 48 deletions
diff --git a/CHANGES b/CHANGES
index 78a894d443..e7d773f862 100644
--- a/CHANGES
+++ b/CHANGES
@@ -24,9 +24,9 @@ des-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k
des-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k
After:
encrypt
-des-cbc 4581.64k 5666.39k 5811.23k 5871.60k 5833.23k
+des-cbc 4660.16k 5650.19k 5807.19k 5827.13k 5783.32k
decrypt
-des-cbc 3615.18k 5102.53k 5501.58k 5631.13k 5635.52k
+des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k
[Ben Laurie]
*) Fix crypto/bn/asm/mips3.s.
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index ecd221fb06..04cb709c8f 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -455,6 +455,9 @@ struct evp_cipher_ctx_st
RIJNDAEL_KEY rijndael;
#endif
} c;
+ int final_used;
+ int block_mask;
+ unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
};
typedef struct evp_Encode_Ctx_st
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index d723d095c1..9a7a553bef 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -125,6 +125,8 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
}
if(enc != -1) ctx->encrypt=enc;
ctx->buf_len=0;
+ ctx->final_used=0;
+ ctx->block_mask=ctx->cipher->block_size-1;
return 1;
}
@@ -160,14 +162,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
{
int i,j,bl;
- i=ctx->buf_len;
- bl=ctx->cipher->block_size;
- if ((inl == 0) && (i != bl))
- {
- *outl=0;
- return 1;
- }
- if(i == 0 && (inl&(bl-1)) == 0)
+ if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
{
if(ctx->cipher->do_cipher(ctx,out,in,inl))
{
@@ -180,24 +175,26 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
return 0;
}
}
- *outl=0;
+ i=ctx->buf_len;
+ bl=ctx->cipher->block_size;
if (i != 0)
{
if (i+inl < bl)
{
memcpy(&(ctx->buf[i]),in,inl);
ctx->buf_len+=inl;
+ *outl=0;
return 1;
}
else
{
j=bl-i;
- if (j != 0) memcpy(&(ctx->buf[i]),in,j);
+ memcpy(&(ctx->buf[i]),in,j);
if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
inl-=j;
in+=j;
out+=bl;
- *outl+=bl;
+ *outl=bl;
}
}
i=inl&(bl-1);
@@ -246,48 +243,42 @@ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
unsigned char *in, int inl)
{
- int b,bl,n;
- int keep_last=0;
+ int b;
- *outl=0;
- if (inl == 0) return 1;
+ if (inl == 0)
+ {
+ *outl=0;
+ return 1;
+ }
if (ctx->flags & EVP_CIPH_NO_PADDING)
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
b=ctx->cipher->block_size;
- if (b > 1)
+ if(ctx->final_used)
{
- /* Is the input a multiple of the block size? */
- bl=ctx->buf_len;
- n=inl+bl;
- if (n%b == 0)
- {
- if (inl < b) /* must be 'just one' buff */
- {
- memcpy(&(ctx->buf[bl]),in,inl);
- ctx->buf_len=b;
- *outl=0;
- return 1;
- }
- keep_last=1;
- inl-=b; /* don't do the last block */
- }
+ memcpy(out,ctx->final,b);
+ out+=b;
}
- if(!EVP_EncryptUpdate(ctx,out,outl,in,inl)) return 0;
+
+ if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
+ return 0;
/* if we have 'decrypted' a multiple of block size, make sure
* we have a copy of this last block */
- if (keep_last)
+ if (b > 1 && !ctx->buf_len)
{
- memcpy(&(ctx->buf[0]),&(in[inl]),b);
-#ifdef DEBUG
- if (ctx->buf_len != 0)
+ if(!ctx->final_used)
{
- abort();
+ *outl-=b;
+ ctx->final_used=1;
}
-#endif
- ctx->buf_len=b;
+ memcpy(ctx->final,&out[*outl],b);
+ }
+ else if(ctx->final_used)
+ {
+ ctx->final_used=0;
+ *outl+=b;
}
return 1;
}
@@ -311,15 +302,12 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
}
if (b > 1)
{
- if (ctx->buf_len != b)
+ if (ctx->buf_len || !ctx->final_used)
{
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
return(0);
}
- if(!EVP_EncryptUpdate(ctx,ctx->buf,&n,ctx->buf,0)) return 0;
- if (n != b)
- return(0);
- n=ctx->buf[b-1];
+ n=ctx->final[b-1];
if (n > b)
{
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
@@ -327,7 +315,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
}
for (i=0; i<n; i++)
{
- if (ctx->buf[--b] != n)
+ if (ctx->final[--b] != n)
{
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
return(0);
@@ -335,7 +323,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
}
n=ctx->cipher->block_size-n;
for (i=0; i<n; i++)
- out[i]=ctx->buf[i];
+ out[i]=ctx->final[i];
*outl=n;
}
else