summaryrefslogtreecommitdiffstats
path: root/crypto/des/cfb_enc.c
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2004-03-28 23:27:47 +0200
committerAndy Polyakov <appro@openssl.org>2004-03-28 23:27:47 +0200
commit1a979201d5b099edbc1e3ad2fb157ee058091a40 (patch)
treeaeb8ac81bc854026ce89d455deca957b10139a2c /crypto/des/cfb_enc.c
parentEnhance EVP code to generate random symmetric keys of the (diff)
downloadopenssl-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.c65
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];