00001
00002
00003
00004
00005
00006 #include "vmsDES.h"
00007 #include "libdes\des_locl.h"
00008 #include "libdes\podd.h"
00009 #include "libdes\sk.h"
00010 #include "libdes\spr.h"
00011
00012 static int check_parity(des_cblock *key);
00013
00014 int des_check_key=0;
00015
00016 void des_set_odd_parity(des_cblock *key)
00017 {
00018 int i;
00019
00020 for (i=0; i<DES_KEY_SZ; i++)
00021 (*key)[i]=odd_parity[(*key)[i]];
00022 }
00023
00024 static int check_parity(des_cblock *key)
00025 {
00026 int i;
00027
00028 for (i=0; i<DES_KEY_SZ; i++)
00029 {
00030 if ((*key)[i] != odd_parity[(*key)[i]])
00031 return(0);
00032 }
00033 return(1);
00034 }
00035
00036 #define NUM_WEAK_KEY 16
00037 static des_cblock weak_keys[NUM_WEAK_KEY]={
00038
00039 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00040 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
00041 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
00042 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
00043
00044 0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,
00045 0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,
00046 0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1,
00047 0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E,
00048 0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,
00049 0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01,
00050 0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE,
00051 0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,
00052 0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,
00053 0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01,
00054 0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE,
00055 0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1};
00056
00057 int des_is_weak_key(des_cblock *key)
00058 {
00059 int i;
00060
00061 for (i=0; i<NUM_WEAK_KEY; i++)
00062
00063 if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);
00064 return(0);
00065 }
00066
00067 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
00068 (a)=(a)^(t)^(t>>(16-(n))))
00069
00070 static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
00071
00072 int des_set_key(des_cblock *key, des_key_schedule schedule)
00073 {
00074 register unsigned long c,d,t,s;
00075 register unsigned char *in;
00076 register unsigned long *k;
00077 register int i;
00078
00079 if (des_check_key)
00080 {
00081 if (!check_parity(key))
00082 return(-1);
00083
00084 if (des_is_weak_key(key))
00085 return(-2);
00086 }
00087
00088 k=(unsigned long *)schedule;
00089 in=(unsigned char *)key;
00090
00091 c2l(in,c);
00092 c2l(in,d);
00093
00094
00095
00096
00097 PERM_OP (d,c,t,4,0x0f0f0f0fL);
00098 HPERM_OP(c,t,-2,0xcccc0000L);
00099 HPERM_OP(d,t,-2,0xcccc0000L);
00100 PERM_OP (d,c,t,1,0x55555555L);
00101 PERM_OP (c,d,t,8,0x00ff00ffL);
00102 PERM_OP (d,c,t,1,0x55555555L);
00103 d= (((d&0x000000ffL)<<16)| (d&0x0000ff00L) |
00104 ((d&0x00ff0000L)>>16)|((c&0xf0000000L)>>4));
00105 c&=0x0fffffffL;
00106
00107 for (i=0; i<ITERATIONS; i++)
00108 {
00109 if (shifts2[i])
00110 { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
00111 else
00112 { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
00113 c&=0x0fffffffL;
00114 d&=0x0fffffffL;
00115
00116 s= des_skb[0][ (c )&0x3f ]|
00117 des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
00118 des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
00119 des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
00120 ((c>>22)&0x38)];
00121 t= des_skb[4][ (d )&0x3f ]|
00122 des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
00123 des_skb[6][ (d>>15)&0x3f ]|
00124 des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
00125
00126
00127 *(k++)=((t<<16)|(s&0x0000ffffL))&0xffffffffL;
00128 s= ((s>>16)|(t&0xffff0000L));
00129
00130 s=(s<<4)|(s>>28);
00131 *(k++)=s&0xffffffffL;
00132 }
00133 return(0);
00134 }
00135
00136 int des_key_sched(des_cblock *key,des_key_schedule schedule)
00137 {
00138 return(des_set_key(key,schedule));
00139 }
00140
00141 int des_ecb_encrypt(des_cblock *input,des_cblock *output,des_key_schedule ks,int encrypt)
00142 {
00143 register unsigned long l0,l1;
00144 register unsigned char *in,*out;
00145 unsigned long ll[2];
00146
00147 in=(unsigned char *)input;
00148 out=(unsigned char *)output;
00149 c2l(in,l0);
00150 c2l(in,l1);
00151 ll[0]=l0;
00152 ll[1]=l1;
00153 des_encrypt(ll,ll,ks,encrypt);
00154 l0=ll[0];
00155 l1=ll[1];
00156 l2c(l0,out);
00157 l2c(l1,out);
00158 l0=l1=ll[0]=ll[1]=0;
00159 return(0);
00160 }
00161
00162 int des_encrypt(unsigned long *input,unsigned long *output,des_key_schedule ks,int encrypt)
00163 {
00164 register unsigned long l,r,t,u;
00165 #ifdef ALT_ECB
00166 register unsigned char *des_SP=(unsigned char *)des_SPtrans;
00167 #endif
00168 #ifdef MSDOS
00169 union fudge {
00170 unsigned long l;
00171 unsigned short s[2];
00172 unsigned char c[4];
00173 } U,T;
00174 #endif
00175 register int i;
00176 register unsigned long *s;
00177
00178 l=input[0];
00179 r=input[1];
00180
00181 IP(l,r,t);
00182
00183 t=(r<<1)|(r>>31);
00184 r=(l<<1)|(l>>31);
00185 l=t;
00186
00187
00188 l&=0xffffffffL;
00189 r&=0xffffffffL;
00190
00191 s=(unsigned long *)ks;
00192
00193 if (encrypt)
00194 {
00195 for (i=0; i<32; i+=4)
00196 {
00197 D_ENCRYPT(l,r,i+0);
00198 D_ENCRYPT(r,l,i+2);
00199 }
00200 }
00201 else
00202 {
00203 for (i=30; i>0; i-=4)
00204 {
00205 D_ENCRYPT(l,r,i-0);
00206 D_ENCRYPT(r,l,i-2);
00207 }
00208 }
00209 l=(l>>1)|(l<<31);
00210 r=(r>>1)|(r<<31);
00211
00212 l&=0xffffffffL;
00213 r&=0xffffffffL;
00214
00215 FP(r,l,t);
00216 output[0]=l;
00217 output[1]=r;
00218 l=r=t=u=0;
00219 return(0);
00220 }
00221
00222 vmsDES::vmsDES()
00223 {
00224
00225 }
00226
00227 vmsDES::~vmsDES()
00228 {
00229
00230 }
00231
00232 void vmsDES::set_Key(DES_KEY szKey)
00233 {
00234 des_set_key ((des_cblock*)szKey, m_hardkey);
00235 }
00236
00237 void vmsDES::Encrypt(LPBYTE pbIn, LPBYTE pbOut, DWORD dwSize)
00238 {
00239 DoDES (pbIn, pbOut, dwSize, TRUE);
00240 }
00241
00242 void vmsDES::Decrypt(LPBYTE pbIn, LPBYTE pbOut, DWORD dwSize)
00243 {
00244 DoDES (pbIn, pbOut, dwSize, FALSE);
00245 }
00246
00247 void vmsDES::DoDES(LPBYTE pbIn, LPBYTE pbOut, DWORD dwSize, BOOL bEncrypt)
00248 {
00249 int op = bEncrypt ? DES_ENCRYPT : DES_DECRYPT;
00250
00251 while (dwSize)
00252 {
00253 if (dwSize < 8)
00254 throw "DES error: buffer is not 8-aligned";
00255 else
00256 {
00257 des_ecb_encrypt ((des_cblock*)pbIn, (des_cblock*)pbOut, m_hardkey, op);
00258 pbIn += 8; pbOut += 8;
00259 dwSize -= 8;
00260 }
00261 }
00262 }