diff options
Diffstat (limited to 'src/lib/libcrypto/des/cfb_enc.c')
| -rw-r--r-- | src/lib/libcrypto/des/cfb_enc.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/src/lib/libcrypto/des/cfb_enc.c b/src/lib/libcrypto/des/cfb_enc.c index 03cabb223c..720f29a28e 100644 --- a/src/lib/libcrypto/des/cfb_enc.c +++ b/src/lib/libcrypto/des/cfb_enc.c | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | 58 | ||
| 59 | #include "e_os.h" | 59 | #include "e_os.h" |
| 60 | #include "des_locl.h" | 60 | #include "des_locl.h" |
| 61 | #include <assert.h> | ||
| 61 | 62 | ||
| 62 | /* The input and output are loaded in multiples of 8 bits. | 63 | /* The input and output are loaded in multiples of 8 bits. |
| 63 | * What this means is that if you hame numbits=12 and length=2 | 64 | * What this means is that if you hame numbits=12 and length=2 |
| @@ -72,19 +73,29 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, | |||
| 72 | int enc) | 73 | int enc) |
| 73 | { | 74 | { |
| 74 | register DES_LONG d0,d1,v0,v1; | 75 | register DES_LONG d0,d1,v0,v1; |
| 75 | register unsigned long l=length,n=(numbits+7)/8; | 76 | register unsigned long l=length; |
| 76 | register int num=numbits,i; | 77 | register int num=numbits/8,n=(numbits+7)/8,i,rem=numbits%8; |
| 77 | DES_LONG ti[2]; | 78 | DES_LONG ti[2]; |
| 78 | unsigned char *iv; | 79 | unsigned char *iv; |
| 80 | #ifndef L_ENDIAN | ||
| 79 | unsigned char ovec[16]; | 81 | unsigned char ovec[16]; |
| 82 | #else | ||
| 83 | unsigned int sh[4]; | ||
| 84 | unsigned char *ovec=(unsigned char *)sh; | ||
| 80 | 85 | ||
| 81 | if (num > 64) return; | 86 | /* I kind of count that compiler optimizes away this assertioni,*/ |
| 87 | assert (sizeof(sh[0])==4); /* as this holds true for all, */ | ||
| 88 | /* but 16-bit platforms... */ | ||
| 89 | |||
| 90 | #endif | ||
| 91 | |||
| 92 | if (numbits<=0 || numbits > 64) return; | ||
| 82 | iv = &(*ivec)[0]; | 93 | iv = &(*ivec)[0]; |
| 83 | c2l(iv,v0); | 94 | c2l(iv,v0); |
| 84 | c2l(iv,v1); | 95 | c2l(iv,v1); |
| 85 | if (enc) | 96 | if (enc) |
| 86 | { | 97 | { |
| 87 | while (l >= n) | 98 | while (l >= (unsigned long)n) |
| 88 | { | 99 | { |
| 89 | l-=n; | 100 | l-=n; |
| 90 | ti[0]=v0; | 101 | ti[0]=v0; |
| @@ -98,35 +109,40 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, | |||
| 98 | out+=n; | 109 | out+=n; |
| 99 | /* 30-08-94 - eay - changed because l>>32 and | 110 | /* 30-08-94 - eay - changed because l>>32 and |
| 100 | * l<<32 are bad under gcc :-( */ | 111 | * l<<32 are bad under gcc :-( */ |
| 101 | if (num == 32) | 112 | if (numbits == 32) |
| 102 | { v0=v1; v1=d0; } | 113 | { v0=v1; v1=d0; } |
| 103 | else if (num == 64) | 114 | else if (numbits == 64) |
| 104 | { v0=d0; v1=d1; } | 115 | { v0=d0; v1=d1; } |
| 105 | else | 116 | else |
| 106 | { | 117 | { |
| 118 | #ifndef L_ENDIAN | ||
| 107 | iv=&ovec[0]; | 119 | iv=&ovec[0]; |
| 108 | l2c(v0,iv); | 120 | l2c(v0,iv); |
| 109 | l2c(v1,iv); | 121 | l2c(v1,iv); |
| 110 | l2c(d0,iv); | 122 | l2c(d0,iv); |
| 111 | l2c(d1,iv); | 123 | l2c(d1,iv); |
| 112 | /* shift ovec left most of the bits... */ | 124 | #else |
| 113 | memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0)); | 125 | sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1; |
| 114 | /* now the remaining bits */ | 126 | #endif |
| 115 | if(num%8 != 0) | 127 | if (rem==0) |
| 128 | memmove(ovec,ovec+num,8); | ||
| 129 | else | ||
| 116 | for(i=0 ; i < 8 ; ++i) | 130 | for(i=0 ; i < 8 ; ++i) |
| 117 | { | 131 | ovec[i]=ovec[i+num]<<rem | |
| 118 | ovec[i]<<=num%8; | 132 | ovec[i+num+1]>>(8-rem); |
| 119 | ovec[i]|=ovec[i+1]>>(8-num%8); | 133 | #ifdef L_ENDIAN |
| 120 | } | 134 | v0=sh[0], v1=sh[1]; |
| 135 | #else | ||
| 121 | iv=&ovec[0]; | 136 | iv=&ovec[0]; |
| 122 | c2l(iv,v0); | 137 | c2l(iv,v0); |
| 123 | c2l(iv,v1); | 138 | c2l(iv,v1); |
| 139 | #endif | ||
| 124 | } | 140 | } |
| 125 | } | 141 | } |
| 126 | } | 142 | } |
| 127 | else | 143 | else |
| 128 | { | 144 | { |
| 129 | while (l >= n) | 145 | while (l >= (unsigned long)n) |
| 130 | { | 146 | { |
| 131 | l-=n; | 147 | l-=n; |
| 132 | ti[0]=v0; | 148 | ti[0]=v0; |
| @@ -136,29 +152,34 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, | |||
| 136 | in+=n; | 152 | in+=n; |
| 137 | /* 30-08-94 - eay - changed because l>>32 and | 153 | /* 30-08-94 - eay - changed because l>>32 and |
| 138 | * l<<32 are bad under gcc :-( */ | 154 | * l<<32 are bad under gcc :-( */ |
| 139 | if (num == 32) | 155 | if (numbits == 32) |
| 140 | { v0=v1; v1=d0; } | 156 | { v0=v1; v1=d0; } |
| 141 | else if (num == 64) | 157 | else if (numbits == 64) |
| 142 | { v0=d0; v1=d1; } | 158 | { v0=d0; v1=d1; } |
| 143 | else | 159 | else |
| 144 | { | 160 | { |
| 161 | #ifndef L_ENDIAN | ||
| 145 | iv=&ovec[0]; | 162 | iv=&ovec[0]; |
| 146 | l2c(v0,iv); | 163 | l2c(v0,iv); |
| 147 | l2c(v1,iv); | 164 | l2c(v1,iv); |
| 148 | l2c(d0,iv); | 165 | l2c(d0,iv); |
| 149 | l2c(d1,iv); | 166 | l2c(d1,iv); |
| 150 | /* shift ovec left most of the bits... */ | 167 | #else |
| 151 | memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0)); | 168 | sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1; |
| 152 | /* now the remaining bits */ | 169 | #endif |
| 153 | if(num%8 != 0) | 170 | if (rem==0) |
| 171 | memmove(ovec,ovec+num,8); | ||
| 172 | else | ||
| 154 | for(i=0 ; i < 8 ; ++i) | 173 | for(i=0 ; i < 8 ; ++i) |
| 155 | { | 174 | ovec[i]=ovec[i+num]<<rem | |
| 156 | ovec[i]<<=num%8; | 175 | ovec[i+num+1]>>(8-rem); |
| 157 | ovec[i]|=ovec[i+1]>>(8-num%8); | 176 | #ifdef L_ENDIAN |
| 158 | } | 177 | v0=sh[0], v1=sh[1]; |
| 178 | #else | ||
| 159 | iv=&ovec[0]; | 179 | iv=&ovec[0]; |
| 160 | c2l(iv,v0); | 180 | c2l(iv,v0); |
| 161 | c2l(iv,v1); | 181 | c2l(iv,v1); |
| 182 | #endif | ||
| 162 | } | 183 | } |
| 163 | d0^=ti[0]; | 184 | d0^=ti[0]; |
| 164 | d1^=ti[1]; | 185 | d1^=ti[1]; |
