00001
00002
00003 const char *PC1CVSID = "$Id: PC1.cc 30949 2009-11-02 16:37:58Z ganis $";
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <unistd.h>
00027 #include <string.h>
00028 #include "PC1.hh"
00029
00030 typedef unsigned short ushort;
00031
00032
00033
00034 static unsigned char cleref[kPC1LENGTH] =
00035 {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
00036 'q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5'};
00037
00038 namespace PC1 {
00039
00040
00041
00042
00043
00044 static ushort code(ushort &ind, ushort &si, ushort &x1a2, ushort *x1a0)
00045 {
00046
00047 ushort ax, bx, cx, dx;
00048 ushort tmp;
00049
00050 dx = x1a2 + ind;
00051 ax = x1a0[ind];
00052 cx = 0x015a;
00053 bx = 0x4e35;
00054
00055 tmp = ax;
00056 ax = si;
00057 si = tmp;
00058
00059 tmp = ax;
00060 ax = dx;
00061 dx = tmp;
00062
00063 if (ax != 0) {
00064 ax=ax*bx;
00065 }
00066
00067 tmp = ax;
00068 ax = cx;
00069 cx = tmp;
00070
00071 if (ax != 0) {
00072 ax = ax*si;
00073 cx = ax+cx;
00074 }
00075
00076 tmp = ax;
00077 ax = si;
00078 si = tmp;
00079 ax = ax*bx;
00080 dx = cx+dx;
00081
00082 ax += 1;
00083
00084 x1a2 = dx;
00085 x1a0[ind] = ax;
00086
00087 ushort res = ax^dx;
00088 ind += 1;
00089 return res;
00090 }
00091
00092
00093 static void assemble(unsigned char *cle, ushort &inter,
00094 ushort &si, ushort &x1a2)
00095 {
00096
00097 ushort ind = 0;
00098 ushort x1a0[kPC1LENGTH/2];
00099
00100 x1a0[0] = cle[0]*256 + cle[1];
00101 ushort res = code(ind,si,x1a2,x1a0);
00102 inter = res;
00103
00104 int j;
00105 for (j = 0; j < 15; j++) {
00106 x1a0[j+1] = x1a0[j]^(cle[2*(j+1)]*256 + cle[2*(j+1)+1]);
00107 res = code(ind,si,x1a2,x1a0);
00108 inter = inter^res;
00109 }
00110 }
00111
00112 }
00113
00114
00115
00116
00117
00118
00119 int PC1HashFun(const char *in, int lin, const char *sa, int lsa,
00120 int it, char *out)
00121 {
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 if (!in || lin <= 0 || !out)
00134 return -1;
00135
00136
00137
00138 unsigned char bin[kPC1LENGTH];
00139 unsigned char cle[kPC1LENGTH];
00140 unsigned char tab[kPC1LENGTH] = {0};
00141 unsigned int ix = 0;
00142 int j = 0;
00143 memset((void *)&bin[0],0,kPC1LENGTH);
00144 memset((void *)&tab[0],0,kPC1LENGTH);
00145
00146
00147
00148 int lbin = (lin > kPC1LENGTH) ? kPC1LENGTH : lin;
00149 memcpy(&bin[0],in,lbin);
00150
00151
00152
00153 int lcle = 0;
00154 if (sa && lsa > 0) {
00155
00156 for( j = 0; j < lsa; j++) {
00157 cle[j] = sa[j];
00158 }
00159 lcle = lsa;
00160 } else {
00161
00162 for( j = 0; j < lin; j++) {
00163 cle[j] = in[j];
00164 }
00165 lcle = lin;
00166 }
00167
00168
00169 for( j = lcle; j < kPC1LENGTH; j++) {
00170 cle[j] = cleref[j];
00171 }
00172
00173
00174
00175 ushort si = 0;
00176 ushort inter = 0;
00177 ushort x1a2= 0;
00178 for (j = 0; j < kPC1LENGTH; j++) {
00179 short c = bin[j];
00180 PC1::assemble(cle,inter,si,x1a2);
00181 ushort cfc = inter >> 8;
00182 ushort cfd = inter & 0xFF;
00183 int k = 0;
00184 for( ; k < kPC1LENGTH; k++) {
00185 cle[k] = cle[k]^c;
00186 }
00187 c = c^(cfc^cfd);
00188 tab[ix] = tab[ix]^c;
00189 ix += 1;
00190 if (ix >= kPC1LENGTH) ix = 0;
00191 }
00192
00193
00194
00195
00196
00197 for (j = 1; j <= it; j++) {
00198 short c = tab[ix];
00199 PC1::assemble(cle,inter,si,x1a2);
00200 ushort cfc = inter >> 8;
00201 ushort cfd = inter & 0xFF;
00202 int k = 0;
00203 for (; k < kPC1LENGTH; k++) {
00204 cle[k] = cle[k]^c;
00205 }
00206 c = c^(cfc^cfd);
00207 tab[ix] = tab[ix]^c;
00208 ix += 1;
00209 if (ix >= kPC1LENGTH) ix = 0;
00210 }
00211
00212
00213
00214 int k = 0;
00215 for( j = 0; j < kPC1LENGTH; j++) {
00216
00217
00218 short d = (tab[j] >> 4);
00219 short e = (tab[j] & 15);
00220
00221
00222 out[k++] = d + 0x61;
00223 out[k++] = e + 0x61;
00224 }
00225
00226 out[k] = 0;
00227
00228
00229 return k;
00230 }
00231
00232
00233 int PC1Encrypt(const char *in, int lin, const char *key, int lkey, char *out)
00234 {
00235
00236
00237
00238
00239
00240
00241
00242
00243 if (!in || lin <= 0 || !key || lkey <= 0 || !out)
00244 return -1;
00245
00246
00247
00248 unsigned char cle[kPC1LENGTH];
00249 int j = 0;
00250
00251
00252
00253 int lk = (lkey > kPC1LENGTH) ? kPC1LENGTH : lkey;
00254 for( j = 0; j < lk; j++) {
00255 cle[j] = key[j];
00256 }
00257
00258
00259 for( j = lk; j < kPC1LENGTH; j++) {
00260 cle[j] = cleref[j];
00261 }
00262
00263
00264
00265 ushort si = 0;
00266 ushort inter = 0;
00267 ushort x1a2= 0;
00268
00269
00270 int n = 0;
00271 for (j = 0; j < lin; j++) {
00272
00273 short c = in[j];
00274 PC1::assemble(cle,inter,si,x1a2);
00275 ushort cfc = inter >> 8;
00276 ushort cfd = inter & 0xFF;
00277 int k = 0;
00278 for( ; k < kPC1LENGTH; k++) {
00279 cle[k] = cle[k]^c;
00280 }
00281 c = c^(cfc^cfd);
00282
00283
00284
00285 short d = (c >> 4);
00286 short e = (c & 15);
00287
00288
00289
00290 out[n++] = d + 0x61;
00291 out[n++] = e + 0x61;
00292 }
00293
00294
00295 return n;
00296 }
00297
00298
00299 int PC1Decrypt(const char *in, int lin, const char *key, int lkey, char *out)
00300 {
00301
00302
00303
00304
00305
00306
00307
00308
00309 if (!in || lin <= 0 || !key || lkey <= 0 || !out)
00310 return -1;
00311
00312
00313
00314 unsigned char cle[kPC1LENGTH];
00315 int j = 0;
00316
00317
00318
00319 int lk = (lkey > kPC1LENGTH) ? kPC1LENGTH : lkey;
00320 for( j = 0; j < lk; j++) {
00321 cle[j] = key[j];
00322 }
00323
00324
00325 for( j = lk; j < kPC1LENGTH; j++) {
00326 cle[j] = cleref[j];
00327 }
00328
00329
00330
00331 ushort si = 0;
00332 ushort inter = 0;
00333 ushort x1a2= 0;
00334
00335
00336 int n = 0;
00337 for (j = 0; j < lin; j += 2 ) {
00338
00339 short d = in[j] - 0x61;
00340 short e = in[j+1] - 0x61;
00341 d = d << 4;
00342 short c = d + e;
00343
00344 PC1::assemble(cle,inter,si,x1a2);
00345 ushort cfc = inter >> 8;
00346 ushort cfd = inter & 0xFF;
00347
00348 c = c^(cfc^cfd);
00349 int k = 0;
00350 for( ; k < kPC1LENGTH; k++) {
00351 cle[k] = cle[k]^c;
00352 }
00353 out[n++] = c;
00354 }
00355
00356
00357 return n;
00358 }