From: Andy Polyakov Date: Thu, 30 Dec 2004 22:57:19 +0000 (+0000) Subject: AES CBC and CFB performance tune-up from HEAD. X-Git-Tag: OpenSSL_0_9_7f~58 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=702be727c0d7001221e989bebdafa102dcf08c04;p=oweals%2Fopenssl.git AES CBC and CFB performance tune-up from HEAD. --- diff --git a/crypto/aes/aes_cbc.c b/crypto/aes/aes_cbc.c index 1222a21002..f909aaf47a 100644 --- a/crypto/aes/aes_cbc.c +++ b/crypto/aes/aes_cbc.c @@ -66,6 +66,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]; + const unsigned char *iv = ivec; assert(in && out && key && ivec); assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); @@ -73,22 +74,39 @@ 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]; + out[n] = in[n] ^ iv[n]; for(n=len; n < AES_BLOCK_SIZE; ++n) - tmp[n] = ivec[n]; - AES_encrypt(tmp, tmp, key); - memcpy(out, tmp, AES_BLOCK_SIZE); - memcpy(ivec, tmp, AES_BLOCK_SIZE); - } + out[n] = iv[n]; + AES_encrypt(out, out, key); + 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); @@ -106,6 +124,6 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, for(n=0; n < len; ++n) out[n] = tmp[n] ^ ivec[n]; memcpy(ivec, tmp, AES_BLOCK_SIZE); - } + } } } diff --git a/crypto/aes/aes_cfb.c b/crypto/aes/aes_cfb.c index ab42cd5ecd..49f0411010 100644 --- a/crypto/aes/aes_cfb.c +++ b/crypto/aes/aes_cfb.c @@ -158,61 +158,35 @@ void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, /* This expects a single block of size nbits for both in and out. Note that it corrupts any extra bits in the last byte of out */ -/* Untested, once it is working, it will be optimised */ void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, const int nbits,const AES_KEY *key, unsigned char *ivec,const int enc) { - int n; + int n,rem,num; unsigned char ovec[AES_BLOCK_SIZE*2]; - assert(in && out && key && ivec); - if(enc) - { - /* construct the new IV */ - AES_encrypt(ivec,ovec,key); - /* encrypt the input */ - for(n=0 ; n < (nbits+7)/8 ; ++n) - out[n]=in[n]^ovec[n]; - /* fill in the first half of the new IV with the current IV */ - memcpy(ovec,ivec,AES_BLOCK_SIZE); - /* and put the ciphertext in the second half */ - memcpy(ovec+AES_BLOCK_SIZE,out,(nbits+7)/8); - /* shift ovec left most of the bits... */ - memmove(ovec,ovec+nbits/8,AES_BLOCK_SIZE+(nbits%8 ? 1 : 0)); - /* now the remaining bits */ - if(nbits%8 != 0) - for(n=0 ; n < AES_BLOCK_SIZE ; ++n) - { - ovec[n]<<=nbits%8; - ovec[n]|=ovec[n+1]>>(8-nbits%8); - } - /* finally, move it back into place */ - memcpy(ivec,ovec,AES_BLOCK_SIZE); - } - else - { - /* construct the new IV in the first half of ovec */ - AES_encrypt(ivec,ovec,key); - /* decrypt the input */ - for(n=0 ; n < (nbits+7)/8 ; ++n) - out[n]=in[n]^ovec[n]; + if (nbits<=0 || nbits>128) return; + /* fill in the first half of the new IV with the current IV */ memcpy(ovec,ivec,AES_BLOCK_SIZE); - /* append the ciphertext */ - memcpy(ovec+AES_BLOCK_SIZE,in,(nbits+7)/8); - /* shift ovec left most of the bits... */ - memmove(ovec,ovec+nbits/8,AES_BLOCK_SIZE+(nbits%8 ? 1 : 0)); - /* now the remaining bits */ - if(nbits%8 != 0) + /* construct the new IV */ + AES_encrypt(ivec,ivec,key); + num = (nbits+7)/8; + if (enc) /* encrypt the input */ + for(n=0 ; n < num ; ++n) + out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n] ^ ivec[n]); + else /* decrypt the input */ + for(n=0 ; n < num ; ++n) + out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n]) ^ ivec[n]; + /* shift ovec left... */ + rem = nbits%8; + num = nbits/8; + if(rem==0) + memcpy(ivec,ovec+num,AES_BLOCK_SIZE); + else for(n=0 ; n < AES_BLOCK_SIZE ; ++n) - { - ovec[n]<<=nbits%8; - ovec[n]|=ovec[n+1]>>(8-nbits%8); - } - /* finally, move it back into place */ - memcpy(ivec,ovec,AES_BLOCK_SIZE); - } + ivec[n] = ovec[n+num]<>(8-rem); + /* it is not necessary to cleanse ovec, since the IV is not secret */ }