summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2004-12-26 12:31:37 +0000
committerAndy Polyakov <appro@openssl.org>2004-12-26 12:31:37 +0000
commit131e064e4ae44288a5a84866deac2b19c88b7826 (patch)
treeb2b654cffb852755a02fef81e211d13f30a6ce1f
parent556b8f3f77d94b4d720e4ea488cf557a952fdc9b (diff)
downloadopenssl-131e064e4ae44288a5a84866deac2b19c88b7826.tar.gz
Eliminate redundant memcpy of IV material. Performance improvement varies
from platform to platform and can be as large as 20%.
-rw-r--r--crypto/aes/aes_cbc.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/crypto/aes/aes_cbc.c b/crypto/aes/aes_cbc.c
index 1222a21002..e43135e8a0 100644
--- a/crypto/aes/aes_cbc.c
+++ b/crypto/aes/aes_cbc.c
@@ -65,7 +65,7 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
unsigned long n;
unsigned long len = length;
- unsigned char tmp[AES_BLOCK_SIZE];
+ unsigned char tmp[AES_BLOCK_SIZE], *iv = ivec;
assert(in && out && key && ivec);
assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
@@ -73,22 +73,40 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
if (AES_ENCRYPT == enc) {
while (len >= AES_BLOCK_SIZE) {
for(n=0; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = in[n] ^ ivec[n];
- AES_encrypt(tmp, out, key);
- memcpy(ivec, out, AES_BLOCK_SIZE);
+ out[n] = in[n] ^ iv[n];
+ AES_encrypt(out, out, key);
+ iv = out;
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
if (len) {
for(n=0; n < len; ++n)
- tmp[n] = in[n] ^ ivec[n];
+ tmp[n] = in[n] ^ iv[n];
for(n=len; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = ivec[n];
+ tmp[n] = iv[n];
AES_encrypt(tmp, tmp, key);
memcpy(out, tmp, AES_BLOCK_SIZE);
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ iv = out;
}
+ memcpy(ivec,iv,AES_BLOCK_SIZE);
+ } else if (in != out) {
+ while (len >= AES_BLOCK_SIZE) {
+ AES_decrypt(in, out, key);
+ for(n=0; n < AES_BLOCK_SIZE; ++n)
+ out[n] ^= iv[n];
+ iv = in;
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ if (len) {
+ AES_decrypt(in,tmp,key);
+ for(n=0; n < len; ++n)
+ out[n] = tmp[n] ^ iv[n];
+ iv = in;
+ }
+ memcpy(ivec,iv,AES_BLOCK_SIZE);
} else {
while (len >= AES_BLOCK_SIZE) {
memcpy(tmp, in, AES_BLOCK_SIZE);