diff options
author | Andy Polyakov <appro@openssl.org> | 2004-01-27 21:47:35 +0000 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2004-01-27 21:47:35 +0000 |
commit | 8c6336b0aac8c34584116d2c05b6d828dc9d8ae6 (patch) | |
tree | 00d5cd5a4f49583f6defa8c4c93de1afa7ac8dbd /crypto/des | |
parent | 87203dc99aeaf3ef50b3df4ac99f2471d06434eb (diff) | |
download | openssl-8c6336b0aac8c34584116d2c05b6d828dc9d8ae6.zip openssl-8c6336b0aac8c34584116d2c05b6d828dc9d8ae6.tar.gz openssl-8c6336b0aac8c34584116d2c05b6d828dc9d8ae6.tar.bz2 |
CFB DES sync-up with FIPS branch.
Diffstat (limited to 'crypto/des')
-rw-r--r-- | crypto/des/cfb64ede.c | 111 | ||||
-rw-r--r-- | crypto/des/cfb_enc.c | 86 |
2 files changed, 158 insertions, 39 deletions
diff --git a/crypto/des/cfb64ede.c b/crypto/des/cfb64ede.c index 60c1aa0..5a54c11 100644 --- a/crypto/des/cfb64ede.c +++ b/crypto/des/cfb64ede.c @@ -140,3 +140,114 @@ void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out, long length, DES_ede3_cfb64_encrypt(in,out,length,ks1,ks2,ks1,ivec,num,enc); } #endif + +/* This is compatible with the single key CFB-r for DES, even thought that's + * not what EVP needs. + */ + +void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out, + int numbits,long length,DES_key_schedule *ks1, + DES_key_schedule *ks2,DES_key_schedule *ks3, + DES_cblock *ivec,int enc) + { + register DES_LONG d0,d1,v0,v1; + register unsigned long l=length; + register int num=numbits,n=(numbits+7)/8,i; + DES_LONG ti[2]; + unsigned char *iv; + unsigned char ovec[16]; + + if (num > 64) return; + iv = &(*ivec)[0]; + c2l(iv,v0); + c2l(iv,v1); + if (enc) + { + while (l >= n) + { + l-=n; + ti[0]=v0; + ti[1]=v1; + DES_encrypt3(ti,ks1,ks2,ks3); + c2ln(in,d0,d1,n); + in+=n; + d0^=ti[0]; + d1^=ti[1]; + l2cn(d0,d1,out,n); + out+=n; + /* 30-08-94 - eay - changed because l>>32 and + * l<<32 are bad under gcc :-( */ + if (num == 32) + { v0=v1; v1=d0; } + else if (num == 64) + { v0=d0; v1=d1; } + else + { + 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) + for(i=0 ; i < 8 ; ++i) + { + ovec[i]<<=num%8; + ovec[i]|=ovec[i+1]>>(8-num%8); + } + iv=&ovec[0]; + c2l(iv,v0); + c2l(iv,v1); + } + } + } + else + { + while (l >= n) + { + l-=n; + ti[0]=v0; + ti[1]=v1; + DES_encrypt3(ti,ks1,ks2,ks3); + c2ln(in,d0,d1,n); + in+=n; + /* 30-08-94 - eay - changed because l>>32 and + * l<<32 are bad under gcc :-( */ + if (num == 32) + { v0=v1; v1=d0; } + else if (num == 64) + { v0=d0; v1=d1; } + else + { + 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) + for(i=0 ; i < 8 ; ++i) + { + ovec[i]<<=num%8; + ovec[i]|=ovec[i+1]>>(8-num%8); + } + iv=&ovec[0]; + c2l(iv,v0); + c2l(iv,v1); + } + d0^=ti[0]; + d1^=ti[1]; + l2cn(d0,d1,out,n); + out+=n; + } + } + iv = &(*ivec)[0]; + l2c(v0,iv); + l2c(v1,iv); + v0=v1=d0=d1=ti[0]=ti[1]=0; + } + diff --git a/crypto/des/cfb_enc.c b/crypto/des/cfb_enc.c index 136efba..225410e 100644 --- a/crypto/des/cfb_enc.c +++ b/crypto/des/cfb_enc.c @@ -65,32 +65,20 @@ * the second. The second 12 bits will come from the 3rd and half the 4th * byte. */ +/* Until Aug 1 2003 this function did not correctly implement CFB-r, so it + * will not be compatible with any encryption prior to that date. Ben. */ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, - long length, DES_key_schedule *schedule, DES_cblock *ivec, int enc) + long length, DES_key_schedule *schedule, DES_cblock *ivec, + int enc) { - register DES_LONG d0,d1,v0,v1,n=(numbits+7)/8; - register DES_LONG mask0,mask1; + register DES_LONG d0,d1,v0,v1; register unsigned long l=length; - register int num=numbits; + register int num=numbits,n=(numbits+7)/8,i; DES_LONG ti[2]; unsigned char *iv; + unsigned char ovec[16]; if (num > 64) return; - if (num > 32) - { - mask0=0xffffffffL; - if (num == 64) - mask1=mask0; - else mask1=(1L<<(num-32))-1; - } - else - { - if (num == 32) - mask0=0xffffffffL; - else mask0=(1L<<num)-1; - mask1=0x00000000L; - } - iv = &(*ivec)[0]; c2l(iv,v0); c2l(iv,v1); @@ -104,8 +92,8 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT); c2ln(in,d0,d1,n); in+=n; - d0=(d0^ti[0])&mask0; - d1=(d1^ti[1])&mask1; + d0^=ti[0]; + d1^=ti[1]; l2cn(d0,d1,out,n); out+=n; /* 30-08-94 - eay - changed because l>>32 and @@ -114,15 +102,25 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, { v0=v1; v1=d0; } else if (num == 64) { v0=d0; v1=d1; } - else if (num > 32) /* && num != 64 */ - { - v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffffL; - v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffffL; - } - else /* num < 32 */ + else { - v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL; - v1=((v1>>num)|(d0<<(32-num)))&0xffffffffL; + 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) + for(i=0 ; i < 8 ; ++i) + { + ovec[i]<<=num%8; + ovec[i]|=ovec[i+1]>>(8-num%8); + } + iv=&ovec[0]; + c2l(iv,v0); + c2l(iv,v1); } } } @@ -142,18 +140,28 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, { v0=v1; v1=d0; } else if (num == 64) { v0=d0; v1=d1; } - else if (num > 32) /* && num != 64 */ - { - v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffffL; - v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffffL; - } - else /* num < 32 */ + else { - v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL; - v1=((v1>>num)|(d0<<(32-num)))&0xffffffffL; + 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) + for(i=0 ; i < 8 ; ++i) + { + ovec[i]<<=num%8; + ovec[i]|=ovec[i+1]>>(8-num%8); + } + iv=&ovec[0]; + c2l(iv,v0); + c2l(iv,v1); } - d0=(d0^ti[0])&mask0; - d1=(d1^ti[1])&mask1; + d0^=ti[0]; + d1^=ti[1]; l2cn(d0,d1,out,n); out+=n; } |