diff options
author | Andy Polyakov <appro@openssl.org> | 2004-03-28 23:27:47 +0200 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2004-03-28 23:27:47 +0200 |
commit | 1a979201d5b099edbc1e3ad2fb157ee058091a40 (patch) | |
tree | aeb8ac81bc854026ce89d455deca957b10139a2c /crypto/des/cfb_enc.c | |
parent | Enhance EVP code to generate random symmetric keys of the (diff) | |
download | openssl-1a979201d5b099edbc1e3ad2fb157ee058091a40.tar.xz openssl-1a979201d5b099edbc1e3ad2fb157ee058091a40.zip |
This is essentially Intel 32-bit compiler tune-up. To start with all
available compiler versions generated bogus machine code trying to
compile new crypto/des/cfb_enc.c. Secondly, 8th version defines
__GNUC__ macro, but fails to compile *some* inline assembler correctly.
Note that all versions of icc implement MSC-like _lrot[rl] intrinsic,
which is used now instead of offensive asm. Finally, unnecessary linker
dependencies are eliminated. Most notably dependency from libirc.a
caused trouble at application start-up, if libcrypto.so is linked with
-Bsymbolic (which it is).
Diffstat (limited to 'crypto/des/cfb_enc.c')
-rw-r--r-- | crypto/des/cfb_enc.c | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/crypto/des/cfb_enc.c b/crypto/des/cfb_enc.c index 0013556c78..6738e7c0e5 100644 --- a/crypto/des/cfb_enc.c +++ b/crypto/des/cfb_enc.c @@ -58,6 +58,7 @@ #include "e_os.h" #include "des_locl.h" +#include <assert.h> /* The input and output are loaded in multiples of 8 bits. * What this means is that if you hame numbits=12 and length=2 @@ -73,12 +74,22 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, { register DES_LONG d0,d1,v0,v1; register unsigned long l=length; - register int num=numbits,n=(numbits+7)/8,i; + register int num=numbits/8,n=(numbits+7)/8,i,rem=numbits%8; DES_LONG ti[2]; unsigned char *iv; +#ifndef L_ENDIAN unsigned char ovec[16]; +#else + unsigned int sh[4]; + unsigned char *ovec=(unsigned char *)sh; - if (num > 64) return; + /* I kind of count that compiler optimizes away this assertioni,*/ + assert (sizeof(sh[0])==4); /* as this holds true for all, */ + /* but 16-bit platforms... */ + +#endif + + if (numbits<=0 || numbits > 64) return; iv = &(*ivec)[0]; c2l(iv,v0); c2l(iv,v1); @@ -98,29 +109,34 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, out+=n; /* 30-08-94 - eay - changed because l>>32 and * l<<32 are bad under gcc :-( */ - if (num == 32) + if (numbits == 32) { v0=v1; v1=d0; } - else if (num == 64) + else if (numbits == 64) { v0=d0; v1=d1; } else { +#ifndef L_ENDIAN iv=&ovec[0]; l2c(v0,iv); l2c(v1,iv); l2c(d0,iv); l2c(d1,iv); - /* shift ovec left most of the bits... */ - memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0)); - /* now the remaining bits */ - if(num%8 != 0) +#else + sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1; +#endif + if (rem==0) + memcpy(ovec,ovec+num,8); + else for(i=0 ; i < 8 ; ++i) - { - ovec[i]<<=num%8; - ovec[i]|=ovec[i+1]>>(8-num%8); - } + ovec[i]=ovec[i+num]<<rem | + ovec[i+num+1]>>(8-rem); +#ifdef L_ENDIAN + v0=sh[0], v1=sh[1]; +#else iv=&ovec[0]; c2l(iv,v0); c2l(iv,v1); +#endif } } } @@ -136,29 +152,34 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, in+=n; /* 30-08-94 - eay - changed because l>>32 and * l<<32 are bad under gcc :-( */ - if (num == 32) + if (numbits == 32) { v0=v1; v1=d0; } - else if (num == 64) + else if (numbits == 64) { v0=d0; v1=d1; } else { +#ifndef L_ENDIAN iv=&ovec[0]; l2c(v0,iv); l2c(v1,iv); l2c(d0,iv); l2c(d1,iv); - /* shift ovec left most of the bits... */ - memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0)); - /* now the remaining bits */ - if(num%8 != 0) +#else + sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1; +#endif + if (rem==0) + memcpy (ovec,ovec+num,8); + else for(i=0 ; i < 8 ; ++i) - { - ovec[i]<<=num%8; - ovec[i]|=ovec[i+1]>>(8-num%8); - } + ovec[i]=ovec[i+num]<<rem | + ovec[i+num+1]>>(8-rem); +#ifdef L_ENDIAN + v0=sh[0], v1=sh[1]; +#else iv=&ovec[0]; c2l(iv,v0); c2l(iv,v1); +#endif } d0^=ti[0]; d1^=ti[1]; |