提交 c148d709 编写于 作者: B Ben Laurie

A better compromise between encrypt and decrypt (but why isn't it as fast

for encrypt?).
上级 7b6055d1
...@@ -24,9 +24,9 @@ des-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k ...@@ -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 des-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k
After: After:
encrypt 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 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] [Ben Laurie]
*) Fix crypto/bn/asm/mips3.s. *) Fix crypto/bn/asm/mips3.s.
......
...@@ -455,6 +455,9 @@ struct evp_cipher_ctx_st ...@@ -455,6 +455,9 @@ struct evp_cipher_ctx_st
RIJNDAEL_KEY rijndael; RIJNDAEL_KEY rijndael;
#endif #endif
} c; } c;
int final_used;
int block_mask;
unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
}; };
typedef struct evp_Encode_Ctx_st typedef struct evp_Encode_Ctx_st
......
...@@ -125,6 +125,8 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ...@@ -125,6 +125,8 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
} }
if(enc != -1) ctx->encrypt=enc; if(enc != -1) ctx->encrypt=enc;
ctx->buf_len=0; ctx->buf_len=0;
ctx->final_used=0;
ctx->block_mask=ctx->cipher->block_size-1;
return 1; return 1;
} }
...@@ -160,14 +162,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, ...@@ -160,14 +162,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
{ {
int i,j,bl; int i,j,bl;
i=ctx->buf_len; if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
bl=ctx->cipher->block_size;
if ((inl == 0) && (i != bl))
{
*outl=0;
return 1;
}
if(i == 0 && (inl&(bl-1)) == 0)
{ {
if(ctx->cipher->do_cipher(ctx,out,in,inl)) 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, ...@@ -180,24 +175,26 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
return 0; return 0;
} }
} }
*outl=0; i=ctx->buf_len;
bl=ctx->cipher->block_size;
if (i != 0) if (i != 0)
{ {
if (i+inl < bl) if (i+inl < bl)
{ {
memcpy(&(ctx->buf[i]),in,inl); memcpy(&(ctx->buf[i]),in,inl);
ctx->buf_len+=inl; ctx->buf_len+=inl;
*outl=0;
return 1; return 1;
} }
else else
{ {
j=bl-i; 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; if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
inl-=j; inl-=j;
in+=j; in+=j;
out+=bl; out+=bl;
*outl+=bl; *outl=bl;
} }
} }
i=inl&(bl-1); i=inl&(bl-1);
...@@ -246,48 +243,42 @@ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) ...@@ -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, int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
unsigned char *in, int inl) unsigned char *in, int inl)
{ {
int b,bl,n; int b;
int keep_last=0;
*outl=0; if (inl == 0)
if (inl == 0) return 1; {
*outl=0;
return 1;
}
if (ctx->flags & EVP_CIPH_NO_PADDING) if (ctx->flags & EVP_CIPH_NO_PADDING)
return EVP_EncryptUpdate(ctx, out, outl, in, inl); return EVP_EncryptUpdate(ctx, out, outl, in, inl);
b=ctx->cipher->block_size; b=ctx->cipher->block_size;
if (b > 1) if(ctx->final_used)
{ {
/* Is the input a multiple of the block size? */ memcpy(out,ctx->final,b);
bl=ctx->buf_len; out+=b;
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 */
}
} }
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 /* if we have 'decrypted' a multiple of block size, make sure
* we have a copy of this last block */ * we have a copy of this last block */
if (keep_last) if (b > 1 && !ctx->buf_len)
{ {
memcpy(&(ctx->buf[0]),&(in[inl]),b); if(!ctx->final_used)
#ifdef DEBUG
if (ctx->buf_len != 0)
{ {
abort(); *outl-=b;
ctx->final_used=1;
} }
#endif memcpy(ctx->final,&out[*outl],b);
ctx->buf_len=b; }
else if(ctx->final_used)
{
ctx->final_used=0;
*outl+=b;
} }
return 1; return 1;
} }
...@@ -311,15 +302,12 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) ...@@ -311,15 +302,12 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
} }
if (b > 1) 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); EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
return(0); return(0);
} }
if(!EVP_EncryptUpdate(ctx,ctx->buf,&n,ctx->buf,0)) return 0; n=ctx->final[b-1];
if (n != b)
return(0);
n=ctx->buf[b-1];
if (n > b) if (n > b)
{ {
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); 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) ...@@ -327,7 +315,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
} }
for (i=0; i<n; i++) 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); EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
return(0); return(0);
...@@ -335,7 +323,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) ...@@ -335,7 +323,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
} }
n=ctx->cipher->block_size-n; n=ctx->cipher->block_size-n;
for (i=0; i<n; i++) for (i=0; i<n; i++)
out[i]=ctx->buf[i]; out[i]=ctx->final[i];
*outl=n; *outl=n;
} }
else else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册