00001 #if defined(HAVE_UNISTD_H)
00002 #include <unistd.h>
00003 #endif
00004
00005 #include <sys/types.h>
00006
00007 #ifdef HAVE_STRING_H
00008 #include <string.h>
00009 #endif
00010
00011 #ifdef HAVE_STRINGS_H
00012 #include <strings.h>
00013 #endif
00014
00015 #if !defined(HAVE_CRYPT)
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #ifndef long32
00062 #if (SIZEOF_INT == 4)
00063 #define long32 int
00064 #elif (SIZEOF_LONG == 4)
00065 #define long32 long
00066 #elif (SIZEOF_SHORT == 4)
00067 #define long32 short
00068 #else
00069
00070 #define long32 int
00071 #endif
00072 #endif
00073
00074 #ifndef long64
00075 #ifdef HAVE_LONGLONG
00076 #define long64 long long long
00077 #endif
00078 #endif
00079
00080 #ifndef ufc_long
00081 #define ufc_long unsigned
00082 #endif
00083
00084 #ifndef _UFC_64_
00085 #define _UFC_32_
00086 #endif
00087
00088
00089
00090
00091
00092 static int pc1[56] = {
00093 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
00094 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
00095 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
00096 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
00097 };
00098
00099
00100
00101
00102
00103 static int rots[16] = {
00104 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
00105 };
00106
00107
00108
00109
00110
00111 static int pc2[48] = {
00112 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
00113 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
00114 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
00115 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
00116 };
00117
00118
00119
00120
00121
00122 static int esel[48] = {
00123 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
00124 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
00125 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
00126 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
00127 };
00128 static int e_inverse[64];
00129
00130
00131
00132
00133
00134 static int perm32[32] = {
00135 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
00136 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
00137 };
00138
00139
00140
00141
00142 static int sbox[8][4][16]= {
00143 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
00144 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
00145 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
00146 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
00147 },
00148
00149 { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
00150 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
00151 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
00152 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
00153 },
00154
00155 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
00156 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
00157 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
00158 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
00159 },
00160
00161 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
00162 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
00163 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
00164 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
00165 },
00166
00167 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
00168 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
00169 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
00170 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
00171 },
00172
00173 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
00174 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
00175 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
00176 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
00177 },
00178
00179 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
00180 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
00181 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
00182 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
00183 },
00184
00185 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
00186 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
00187 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
00188 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
00189 }
00190 };
00191
00192
00193
00194
00195
00196 static int final_perm[64] = {
00197 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
00198 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
00199 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
00200 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
00201 };
00202
00203
00204
00205
00206 #ifdef _UFC_32_
00207 long32 _ufc_keytab[16][2];
00208 #endif
00209
00210 #ifdef _UFC_64_
00211 long64 _ufc_keytab[16];
00212 #endif
00213
00214
00215 #define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
00216 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
00217
00218
00219 #define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) )
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 #ifdef _UFC_32_
00232 long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192];
00233 static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
00234 #endif
00235
00236 #ifdef _UFC_64_
00237 long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096];
00238 static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
00239 #endif
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 static ufc_long eperm32tab[4][256][2];
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 static ufc_long do_pc1[8][2][128];
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 static ufc_long do_pc2[8][128];
00276
00277
00278
00279
00280
00281
00282
00283
00284 static ufc_long efp[16][64][2];
00285
00286 static unsigned char bytemask[8] = {
00287 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
00288 };
00289
00290 static ufc_long longmask[32] = {
00291 0x80000000, 0x40000000, 0x20000000, 0x10000000,
00292 0x08000000, 0x04000000, 0x02000000, 0x01000000,
00293 0x00800000, 0x00400000, 0x00200000, 0x00100000,
00294 0x00080000, 0x00040000, 0x00020000, 0x00010000,
00295 0x00008000, 0x00004000, 0x00002000, 0x00001000,
00296 0x00000800, 0x00000400, 0x00000200, 0x00000100,
00297 0x00000080, 0x00000040, 0x00000020, 0x00000010,
00298 0x00000008, 0x00000004, 0x00000002, 0x00000001
00299 };
00300
00301
00302
00303
00304
00305
00306
00307
00308 static void clearmem(char *start, int cnt)
00309 { while(cnt--)
00310 *start++ = '\0';
00311 }
00312
00313 static int initialized = 0;
00314
00315
00316
00317 #define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
00318
00319
00320
00321
00322
00323
00324 static void ufc_init_des(void)
00325 { int comes_from_bit;
00326 int bit, sg;
00327 ufc_long j;
00328 ufc_long mask1, mask2;
00329
00330
00331
00332
00333
00334
00335 for(bit = 0; bit < 56; bit++) {
00336 comes_from_bit = pc1[bit] - 1;
00337 mask1 = bytemask[comes_from_bit % 8 + 1];
00338 mask2 = longmask[bit % 28 + 4];
00339 for(j = 0; j < 128; j++) {
00340 if(j & mask1)
00341 do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
00342 }
00343 }
00344
00345
00346
00347
00348
00349
00350 for(bit = 0; bit < 48; bit++) {
00351 comes_from_bit = pc2[bit] - 1;
00352 mask1 = bytemask[comes_from_bit % 7 + 1];
00353 mask2 = BITMASK(bit % 24);
00354 for(j = 0; j < 128; j++) {
00355 if(j & mask1)
00356 do_pc2[comes_from_bit / 7][j] |= mask2;
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 clearmem((char*)eperm32tab, sizeof(eperm32tab));
00373
00374 for(bit = 0; bit < 48; bit++) {
00375 ufc_long inner_mask1,comes_from;
00376
00377 comes_from = perm32[esel[bit]-1]-1;
00378 inner_mask1 = bytemask[comes_from % 8];
00379
00380 for(j = 256; j--;) {
00381 if(j & inner_mask1)
00382 eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24);
00383 }
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 for(sg = 0; sg < 4; sg++) {
00399 int j1, j2;
00400 int s1, s2;
00401
00402 for(j1 = 0; j1 < 64; j1++) {
00403 s1 = s_lookup(2 * sg, j1);
00404 for(j2 = 0; j2 < 64; j2++) {
00405 ufc_long to_permute, inx;
00406
00407 s2 = s_lookup(2 * sg + 1, j2);
00408 to_permute = ((s1 << 4) | s2) << (24 - 8 * sg);
00409
00410 #ifdef _UFC_32_
00411 inx = ((j1 << 6) | j2) << 1;
00412 sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0];
00413 sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1];
00414 sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];
00415 sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];
00416 sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0];
00417 sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1];
00418 sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0];
00419 sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1];
00420 #endif
00421 #ifdef _UFC_64_
00422 inx = ((j1 << 6) | j2);
00423 sb[sg][inx] =
00424 ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |
00425 (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];
00426 sb[sg][inx] |=
00427 ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |
00428 (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];
00429 sb[sg][inx] |=
00430 ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) |
00431 (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1];
00432 sb[sg][inx] |=
00433 ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) |
00434 (long64)eperm32tab[3][(to_permute) & 0xff][1];
00435 #endif
00436 }
00437 }
00438 }
00439
00440
00441
00442
00443
00444 for(bit=48; bit--;) {
00445 e_inverse[esel[bit] - 1 ] = bit;
00446 e_inverse[esel[bit] - 1 + 32] = bit + 48;
00447 }
00448
00449
00450
00451
00452
00453 clearmem((char*)efp, sizeof efp);
00454 for(bit = 0; bit < 64; bit++) {
00455 int o_bit, o_long;
00456 ufc_long word_value, inner_mask1, inner_mask2;
00457 int comes_from_f_bit, comes_from_e_bit;
00458 int comes_from_word, bit_within_word;
00459
00460
00461 o_long = bit / 32;
00462 o_bit = bit % 32;
00463
00464
00465
00466
00467
00468
00469
00470
00471 comes_from_f_bit = final_perm[bit] - 1;
00472 comes_from_e_bit = e_inverse[comes_from_f_bit];
00473 comes_from_word = comes_from_e_bit / 6;
00474 bit_within_word = comes_from_e_bit % 6;
00475
00476 inner_mask1 = longmask[bit_within_word + 26];
00477 inner_mask2 = longmask[o_bit];
00478
00479 for(word_value = 64; word_value--;) {
00480 if(word_value & inner_mask1)
00481 efp[comes_from_word][word_value][o_long] |= inner_mask2;
00482 }
00483 }
00484 initialized++;
00485 }
00486
00487
00488
00489
00490
00491
00492 #ifdef _UFC_32_
00493 static void shuffle_sb(long32 *k, ufc_long saltbits)
00494 { ufc_long j;
00495 long32 x;
00496 for(j=4096; j--;) {
00497 x = (k[0] ^ k[1]) & (long32)saltbits;
00498 *k++ ^= x;
00499 *k++ ^= x;
00500 }
00501 }
00502 #endif
00503
00504 #ifdef _UFC_64_
00505 static void shuffle_sb(long64 *k, ufc_long saltbits)
00506 { ufc_long j;
00507 long64 x;
00508 for(j=4096; j--;) {
00509 x = ((*k >> 32) ^ *k) & (long64)saltbits;
00510 *k++ ^= (x << 32) | x;
00511 }
00512 }
00513 #endif
00514
00515
00516
00517
00518
00519
00520 static unsigned char current_salt[3] = "&&";
00521 static ufc_long current_saltbits = 0;
00522 static int direction = 0;
00523
00524 static void setup_salt(const char *s1)
00525 { ufc_long i, j, saltbits;
00526 const unsigned char *s2 = (const unsigned char *)s1;
00527
00528 if(!initialized)
00529 ufc_init_des();
00530
00531 if(s2[0] == current_salt[0] && s2[1] == current_salt[1])
00532 return;
00533 current_salt[0] = s2[0]; current_salt[1] = s2[1];
00534
00535
00536
00537
00538
00539
00540 saltbits = 0;
00541 for(i = 0; i < 2; i++) {
00542 long c=ascii_to_bin(s2[i]);
00543 if(c < 0 || c > 63)
00544 c = 0;
00545 for(j = 0; j < 6; j++) {
00546 if((c >> j) & 0x1)
00547 saltbits |= BITMASK(6 * i + j);
00548 }
00549 }
00550
00551
00552
00553
00554
00555
00556 shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits);
00557 shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits);
00558 shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits);
00559 shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits);
00560
00561 current_saltbits = saltbits;
00562 }
00563
00564 static void ufc_mk_keytab(char *key)
00565 { ufc_long v1, v2, *k1;
00566 int i;
00567 #ifdef _UFC_32_
00568 long32 v, *k2 = &_ufc_keytab[0][0];
00569 #endif
00570 #ifdef _UFC_64_
00571 long64 v, *k2 = &_ufc_keytab[0];
00572 #endif
00573
00574 v1 = v2 = 0; k1 = &do_pc1[0][0][0];
00575 for(i = 8; i--;) {
00576 v1 |= k1[*key & 0x7f]; k1 += 128;
00577 v2 |= k1[*key++ & 0x7f]; k1 += 128;
00578 }
00579
00580 for(i = 0; i < 16; i++) {
00581 k1 = &do_pc2[0][0];
00582
00583 v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));
00584 v = k1[(v1 >> 21) & 0x7f]; k1 += 128;
00585 v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;
00586 v |= k1[(v1 >> 7) & 0x7f]; k1 += 128;
00587 v |= k1[(v1 ) & 0x7f]; k1 += 128;
00588
00589 #ifdef _UFC_32_
00590 *k2++ = v;
00591 v = 0;
00592 #endif
00593 #ifdef _UFC_64_
00594 v <<= 32;
00595 #endif
00596
00597 v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));
00598 v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;
00599 v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;
00600 v |= k1[(v2 >> 7) & 0x7f]; k1 += 128;
00601 v |= k1[(v2 ) & 0x7f];
00602
00603 *k2++ = v;
00604 }
00605
00606 direction = 0;
00607 }
00608
00609
00610
00611
00612
00613 ufc_long *_ufc_dofinalperm(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2)
00614 { ufc_long v1, v2, x;
00615 static ufc_long ary[2];
00616
00617 x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x;
00618 x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x;
00619
00620 v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;
00621
00622 v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];
00623 v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];
00624 v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];
00625 v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];
00626
00627 v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];
00628 v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];
00629 v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];
00630 v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];
00631
00632 v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];
00633 v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];
00634 v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];
00635 v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];
00636
00637 v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];
00638 v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];
00639 v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];
00640 v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];
00641
00642 ary[0] = v1; ary[1] = v2;
00643 return ary;
00644 }
00645
00646
00647
00648
00649
00650
00651 static char *output_conversion(ufc_long v1, ufc_long v2, const char *salt)
00652 { static char outbuf[14];
00653 int i, s;
00654
00655 outbuf[0] = salt[0];
00656 outbuf[1] = salt[1] ? salt[1] : salt[0];
00657
00658 for(i = 0; i < 5; i++)
00659 outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f);
00660
00661 s = (v2 & 0xf) << 2;
00662 v2 = (v2 >> 2) | ((v1 & 0x3) << 30);
00663
00664 for(i = 5; i < 10; i++)
00665 outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f);
00666
00667 outbuf[12] = bin_to_ascii(s);
00668 outbuf[13] = 0;
00669
00670 return outbuf;
00671 }
00672
00673
00674
00675
00676
00677 static ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long);
00678
00679 char *ufc_crypt(const char *key,const char *salt)
00680 { ufc_long *s;
00681 char ktab[9];
00682
00683
00684
00685
00686 setup_salt(salt);
00687
00688
00689
00690
00691 clearmem(ktab, sizeof ktab);
00692 strncpy(ktab, key, 8);
00693 ufc_mk_keytab(ktab);
00694
00695
00696
00697
00698 s = _ufc_doit((ufc_long)0, (ufc_long)0,
00699 (ufc_long)0, (ufc_long)0, (ufc_long)25);
00700
00701
00702
00703
00704 return output_conversion(s[0], s[1], salt);
00705 }
00706
00707
00708 #ifdef _UFC_32_
00709
00710
00711
00712
00713
00714 extern long32 _ufc_keytab[16][2];
00715 extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
00716
00717 #define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
00718
00719 static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr)
00720 { int i;
00721 long32 s, *k;
00722
00723 while(itr--) {
00724 k = &_ufc_keytab[0][0];
00725 for(i=8; i--; ) {
00726 s = *k++ ^ r1;
00727 l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
00728 l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4);
00729 s = *k++ ^ r2;
00730 l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
00731 l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4);
00732
00733 s = *k++ ^ l1;
00734 r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
00735 r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4);
00736 s = *k++ ^ l2;
00737 r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
00738 r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4);
00739 }
00740 s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
00741 }
00742 return _ufc_dofinalperm(l1, l2, r1, r2);
00743 }
00744
00745 #endif
00746
00747 #ifdef _UFC_64_
00748
00749
00750
00751
00752
00753 extern long64 _ufc_keytab[16];
00754 extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
00755
00756 #define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
00757
00758 static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr)
00759 { int i;
00760 long64 l, r, s, *k;
00761
00762 l = (((long64)l1) << 32) | ((long64)l2);
00763 r = (((long64)r1) << 32) | ((long64)r2);
00764
00765 while(itr--) {
00766 k = &_ufc_keytab[0];
00767 for(i=8; i--; ) {
00768 s = *k++ ^ r;
00769 l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
00770 l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
00771 l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
00772 l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
00773
00774 s = *k++ ^ l;
00775 r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
00776 r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
00777 r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
00778 r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
00779 }
00780 s=l; l=r; r=s;
00781 }
00782
00783 l1 = l >> 32; l2 = l & 0xffffffff;
00784 r1 = r >> 32; r2 = r & 0xffffffff;
00785 return _ufc_dofinalperm(l1, l2, r1, r2);
00786 }
00787
00788 #endif
00789
00790 #define crypt ufc_crypt
00791 #endif
00792
00793 main()
00794 {
00795 char passwd[9];
00796 char salt[9];
00797 char c_out1[256];
00798 char c_out2[256];
00799
00800 char expected_out[14];
00801
00802 strcpy(expected_out, "12yJ.Of/NQ.Pk");
00803 strcpy(passwd, "12345678");
00804 strcpy(salt, "12345678");
00805
00806 strcpy(c_out1, crypt(passwd, salt));
00807 salt[2] = '\0';
00808 strcpy(c_out2, crypt(passwd, salt));
00809
00810
00811
00812
00813
00814
00815 if((strcmp(c_out1, expected_out) != 0) &&
00816 (strcmp(c_out2, expected_out) == 0))
00817 exit(1);
00818
00819 #ifdef HAVE_BIGCRYPT
00820
00821
00822
00823
00824 {
00825 char big_passwd[17];
00826 char big_salt[17];
00827 char big_c_out1[256];
00828 char big_c_out2[256];
00829 char big_expected_out[27];
00830
00831 strcpy(big_passwd, "1234567812345678");
00832 strcpy(big_salt, "1234567812345678");
00833 strcpy(big_expected_out, "12yJ.Of/NQ.PklfyCuHi/rwM");
00834
00835 strcpy(big_c_out1, bigcrypt(big_passwd, big_salt));
00836 big_salt[2] = '\0';
00837 strcpy(big_c_out2, bigcrypt(big_passwd, big_salt));
00838
00839
00840
00841
00842
00843
00844 if((strcmp(big_c_out1, big_expected_out) != 0) &&
00845 (strcmp(big_c_out2, big_expected_out) == 0))
00846 exit(1);
00847
00848 }
00849 #endif
00850
00851 exit(0);
00852 }