# include "dgd.h"
/*
* A crypt function tailored to DGD, small but reasonably fast.
*/
static char Salt[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32,
16,48, 8,40,24,56, 4,36,20,52,40,24,56, 4,36,20,
52,12,44,28,60, 2,34,18,50,10,42,26,58, 6,38,22,
54,14,46,30,62, 1,33,17,49, 9,41, 1,33,17,49, 9,
41,25,57, 5,37,21,53,13,45,29,61, 3,35,19,51,11,
43,27,59, 7,39,23,55,15,47,31,63, 0, 0, 0, 0, 0,
};
static char Rot[] = {
0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,
};
static Uint PC2[14][16] = { {
0x00000000, 0x00040000, 0x00002000, 0x00042000, 0x00000001, 0x00040001,
0x00002001, 0x00042001, 0x02000000, 0x02040000, 0x02002000, 0x02042000,
0x02000001, 0x02040001, 0x02002001, 0x02042001,
}, {
0x00000000, 0x00010000, 0x00000010, 0x00010010, 0x00000400, 0x00010400,
0x00000410, 0x00010410, 0x01000000, 0x01010000, 0x01000010, 0x01010010,
0x01000400, 0x01010400, 0x01000410, 0x01010410,
}, {
0x00000000, 0x00080000, 0x08000000, 0x08080000, 0x00000100, 0x00080100,
0x08000100, 0x08080100, 0x00000000, 0x00080000, 0x08000000, 0x08080000,
0x00000100, 0x00080100, 0x08000100, 0x08080100,
}, {
0x00000000, 0x00000020, 0x00000800, 0x00000820, 0x20000000, 0x20000020,
0x20000800, 0x20000820, 0x00000002, 0x00000022, 0x00000802, 0x00000822,
0x20000002, 0x20000022, 0x20000802, 0x20000822,
}, {
0x00000000, 0x00000004, 0x00100000, 0x00100004, 0x00000000, 0x00000004,
0x00100000, 0x00100004, 0x10000000, 0x10000004, 0x10100000, 0x10100004,
0x10000000, 0x10000004, 0x10100000, 0x10100004,
}, {
0x00000000, 0x04000000, 0x00200000, 0x04200000, 0x00000000, 0x04000000,
0x00200000, 0x04200000, 0x00000200, 0x04000200, 0x00200200, 0x04200200,
0x00000200, 0x04000200, 0x00200200, 0x04200200,
}, {
0x00000000, 0x00001000, 0x00000008, 0x00001008, 0x00020000, 0x00021000,
0x00020008, 0x00021008, 0x00000000, 0x00001000, 0x00000008, 0x00001008,
0x00020000, 0x00021000, 0x00020008, 0x00021008,
}, {
0x00000000, 0x00000001, 0x08000000, 0x08000001, 0x00002000, 0x00002001,
0x08002000, 0x08002001, 0x00000002, 0x00000003, 0x08000002, 0x08000003,
0x00002002, 0x00002003, 0x08002002, 0x08002003,
}, {
0x00000000, 0x00000004, 0x00000000, 0x00000004, 0x00020000, 0x00020004,
0x00020000, 0x00020004, 0x00000200, 0x00000204, 0x00000200, 0x00000204,
0x00020200, 0x00020204, 0x00020200, 0x00020204,
}, {
0x00000000, 0x00001000, 0x00080000, 0x00081000, 0x00000000, 0x00001000,
0x00080000, 0x00081000, 0x04000000, 0x04001000, 0x04080000, 0x04081000,
0x04000000, 0x04001000, 0x04080000, 0x04081000,
}, {
0x00000000, 0x00200000, 0x00000000, 0x00200000, 0x00000010, 0x00200010,
0x00000010, 0x00200010, 0x20000000, 0x20200000, 0x20000000, 0x20200000,
0x20000010, 0x20200010, 0x20000010, 0x20200010,
}, {
0x00000000, 0x00000100, 0x02000000, 0x02000100, 0x00000020, 0x00000120,
0x02000020, 0x02000120, 0x00000400, 0x00000500, 0x02000400, 0x02000500,
0x00000420, 0x00000520, 0x02000420, 0x02000520,
}, {
0x00000000, 0x10000000, 0x00000800, 0x10000800, 0x00000008, 0x10000008,
0x00000808, 0x10000808, 0x00100000, 0x10100000, 0x00100800, 0x10100800,
0x00100008, 0x10100008, 0x00100808, 0x10100808,
}, {
0x00000000, 0x00040000, 0x01000000, 0x01040000, 0x00000000, 0x00040000,
0x01000000, 0x01040000, 0x00010000, 0x00050000, 0x01010000, 0x01050000,
0x00010000, 0x00050000, 0x01010000, 0x01050000,
} };
static char S[8][64] = { {
14, 0, 4,15,13, 7, 1, 4, 2,14,15, 2,11,13, 8, 1,
3,10,10, 6, 6,12,12,11, 5, 9, 9, 5, 0, 3, 7, 8,
4,15, 1,12,14, 8, 8, 2,13, 4, 6, 9, 2, 1,11, 7,
15, 5,12,11, 9, 3, 7,14, 3,10,10, 0, 5, 6, 0,13,
}, {
15, 3, 1,13, 8, 4,14, 7, 6,15,11, 2, 3, 8, 4,14,
9,12, 7, 0, 2, 1,13,10,12, 6, 0, 9, 5,11,10, 5,
0,13,14, 8, 7,10,11, 1,10, 3, 4,15,13, 4, 1, 2,
5,11, 8, 6,12, 7, 6,12, 9, 0, 3, 5, 2,14,15, 9,
}, {
10,13, 0, 7, 9, 0,14, 9, 6, 3, 3, 4,15, 6, 5,10,
1, 2,13, 8,12, 5, 7,14,11,12, 4,11, 2,15, 8, 1,
13, 1, 6,10, 4,13, 9, 0, 8, 6,15, 9, 3, 8, 0, 7,
11, 4, 1,15, 2,14,12, 3, 5,11,10, 5,14, 2, 7,12,
}, {
7,13,13, 8,14,11, 3, 5, 0, 6, 6,15, 9, 0,10, 3,
1, 4, 2, 7, 8, 2, 5,12,11, 1,12,10, 4,14,15, 9,
10, 3, 6,15, 9, 0, 0, 6,12,10,11, 1, 7,13,13, 8,
15, 9, 1, 4, 3, 5,14,11, 5,12, 2, 7, 8, 2, 4,14,
}, {
2,14,12,11, 4, 2, 1,12, 7, 4,10, 7,11,13, 6, 1,
8, 5, 5, 0, 3,15,15,10,13, 3, 0, 9,14, 8, 9, 6,
4,11, 2, 8, 1,12,11, 7,10, 1,13,14, 7, 2, 8,13,
15, 6, 9,15,12, 0, 5, 9, 6,10, 3, 4, 0, 5,14, 3,
}, {
12,10, 1,15,10, 4,15, 2, 9, 7, 2,12, 6, 9, 8, 5,
0, 6,13, 1, 3,13, 4,14,14, 0, 7,11, 5, 3,11, 8,
9, 4,14, 3,15, 2, 5,12, 2, 9, 8, 5,12,15, 3,10,
7,11, 0,14, 4, 1,10, 7, 1, 6,13, 0,11, 8, 6,13,
}, {
4,13,11, 0, 2,11,14, 7,15, 4, 0, 9, 8, 1,13,10,
3,14,12, 3, 9, 5, 7,12, 5, 2,10,15, 6, 8, 1, 6,
1, 6, 4,11,11,13,13, 8,12, 1, 3, 4, 7,10,14, 7,
10, 9,15, 5, 6, 0, 8,15, 0,14, 5, 2, 9, 3, 2,12,
}, {
13, 1, 2,15, 8,13, 4, 8, 6,10,15, 3,11, 7, 1, 4,
10,12, 9, 5, 3, 6,14,11, 5, 0, 0,14,12, 9, 7, 2,
7, 2,11, 1, 4,14, 1, 7, 9, 4,12,10,14, 8, 2,13,
0,15, 6,12,10, 9,13, 0,15, 3, 3, 5, 5, 6, 8,11,
} };
static Uint PM[8][16] = { {
0x00000000, 0x00000002, 0x00000200, 0x00000202,
0x00008000, 0x00008002, 0x00008200, 0x00008202,
0x00800000, 0x00800002, 0x00800200, 0x00800202,
0x00808000, 0x00808002, 0x00808200, 0x00808202,
}, {
0x00000000, 0x00004000, 0x40000000, 0x40004000,
0x00000010, 0x00004010, 0x40000010, 0x40004010,
0x00080000, 0x00084000, 0x40080000, 0x40084000,
0x00080010, 0x00084010, 0x40080010, 0x40084010,
}, {
0x00000000, 0x04000000, 0x00000004, 0x04000004,
0x00010000, 0x04010000, 0x00010004, 0x04010004,
0x00000100, 0x04000100, 0x00000104, 0x04000104,
0x00010100, 0x04010100, 0x00010104, 0x04010104,
}, {
0x00000000, 0x80000000, 0x00400000, 0x80400000,
0x00001000, 0x80001000, 0x00401000, 0x80401000,
0x00000040, 0x80000040, 0x00400040, 0x80400040,
0x00001040, 0x80001040, 0x00401040, 0x80401040,
}, {
0x00000000, 0x20000000, 0x00000080, 0x20000080,
0x00040000, 0x20040000, 0x00040080, 0x20040080,
0x01000000, 0x21000000, 0x01000080, 0x21000080,
0x01040000, 0x21040000, 0x01040080, 0x21040080,
}, {
0x00000000, 0x00002000, 0x00200000, 0x00202000,
0x00000008, 0x00002008, 0x00200008, 0x00202008,
0x10000000, 0x10002000, 0x10200000, 0x10202000,
0x10000008, 0x10002008, 0x10200008, 0x10202008,
}, {
0x00000000, 0x02000000, 0x00000400, 0x02000400,
0x00100000, 0x02100000, 0x00100400, 0x02100400,
0x00000001, 0x02000001, 0x00000401, 0x02000401,
0x00100001, 0x02100001, 0x00100401, 0x02100401,
}, {
0x00000000, 0x00000800, 0x00020000, 0x00020800,
0x00000020, 0x00000820, 0x00020020, 0x00020820,
0x08000000, 0x08000800, 0x08020000, 0x08020800,
0x08000020, 0x08000820, 0x08020020, 0x08020820,
} };
static char out[64] = {
'.', '/', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
};
# define EXG1(a, t, n, m) ((t) = (((a) >> (n)) ^ (a)) & (m), \
(a) ^= (t), (a) ^= ((t) << (n)))
# define EXG2(a, b, t, n, m) ((t) = (((a) >> (n)) ^ (b)) & (m), \
(b) ^= (t), (a) ^= (t) << (n))
/*
* NAME: P->crypt()
* DESCRIPTION: Unix password encryption.
*/
char *P_crypt(passwd, salt)
char *passwd, *salt;
{
static char result[14];
register Uint L, R, T, A, B;
register int i, j;
register char *p;
Uint keys[16][2], E[2];
/* fetch password data */
memset(result, '\0', 8);
strncpy(result, passwd, 8);
p = result;
L = UCHAR(*p++) << 1; L <<= 8;
L |= UCHAR(*p++) << 1; L <<= 8;
L |= UCHAR(*p++) << 1; L <<= 8;
L |= UCHAR(*p++) << 1;
R = UCHAR(*p++) << 1; R <<= 8;
R |= UCHAR(*p++) << 1; R <<= 8;
R |= UCHAR(*p++) << 1; R <<= 8;
R |= UCHAR(*p) << 1;
/* PC1 */
EXG2(R, L, T, 4, 0x0f0f0f0f);
EXG1(L, T, 14, 0xcccc);
EXG1(L, T, 7, 0xaa00aa);
EXG1(L, T, 4, 0x0f0f0f0f);
EXG1(L, T, 2, 0x33333333);
EXG1(L, T, 1, 0x55555555);
EXG1(R, T, 18, 0x3333);
EXG1(R, T, 9, 0x550055);
EXG1(R, T, 4, 0x0f0f0f0f);
R = (R << 4) | (L & 0xf);
L >>= 4;
/* PC2 */
for (i = 15; i >= 0; --i) {
if (Rot[i] == 0) {
L = (L << 1) | (L >> 27);
R = (R << 1) | (R >> 27);
} else {
L = (L << 2) | (L >> 26);
R = (R << 2) | (R >> 26);
}
L &= 0x0fffffff;
R &= 0x0fffffff;
A = PC2[ 0][ L >> 24 ] |
PC2[ 1][(L >> 20) & 0xf] |
PC2[ 2][(L >> 16) & 0xf] |
PC2[ 3][(L >> 12) & 0xf] |
PC2[ 4][(L >> 8) & 0xf] |
PC2[ 5][(L >> 4) & 0xf] |
PC2[ 6][ L & 0xf];
B = PC2[ 7][ R >> 24 ] |
PC2[ 8][(R >> 20) & 0xf] |
PC2[ 9][(R >> 16) & 0xf] |
PC2[10][(R >> 12) & 0xf] |
PC2[11][(R >> 8) & 0xf] |
PC2[12][(R >> 4) & 0xf] |
PC2[13][ R & 0xf];
EXG2(B, A, T, 16, 0x3f3f);
keys[i][0] = A;
keys[i][1] = B;
}
/* prepare salt */
E[0] = UCHAR(Salt[UCHAR(result[0] = *salt++)]) << 8;
E[1] = UCHAR(Salt[UCHAR(result[1] = *salt++)]) << 4;
/* encrypt */
L = 0;
R = 0;
for (i = 25; i > 0; --i) {
for (j = 15; j >= 0; --j) {
T = L;
L = R;
A = (R >> 3) | (R << 29);
R = T;
T = A ^ (A >> 16);
B = T & E[0];
B ^= (B << 16) ^ A ^ keys[j][0];
R ^= PM[6][UCHAR(S[6][B & 0x3f])]; B >>= 8;
R ^= PM[4][UCHAR(S[4][B & 0x3f])]; B >>= 8;
R ^= PM[2][UCHAR(S[2][B & 0x3f])]; B >>= 8;
R ^= PM[0][UCHAR(S[0][B & 0x3f])];
B = T & E[1];
B ^= (B << 16) ^ A;
B = ((B << 4) | (B >> 28)) ^ keys[j][1];
R ^= PM[7][UCHAR(S[7][B & 0x3f])]; B >>= 8;
R ^= PM[5][UCHAR(S[5][B & 0x3f])]; B >>= 8;
R ^= PM[3][UCHAR(S[3][B & 0x3f])]; B >>= 8;
R ^= PM[1][UCHAR(S[1][B & 0x3f])];
}
T = L;
L = R;
R = T;
}
/* FP */
EXG2(L, R, T, 1, 0x55555555);
EXG2(R, L, T, 8, 0xff00ff);
EXG2(R, L, T, 2, 0x33333333);
EXG2(L, R, T, 16, 0xffff);
EXG2(L, R, T, 4, 0x0f0f0f0f);
/* put result in static buffer */
p = result + 13;
*p = '\0';
*--p = out[(R << 2) & 0x3f]; R >>= 4;
*--p = out[R & 0x3f]; R >>= 6;
*--p = out[R & 0x3f]; R >>= 6;
*--p = out[R & 0x3f]; R >>= 6;
*--p = out[R & 0x3f]; R >>= 6;
*--p = out[((L << 4) | R) & 0x3f]; L >>= 2;
*--p = out[L & 0x3f]; L >>= 6;
*--p = out[L & 0x3f]; L >>= 6;
*--p = out[L & 0x3f]; L >>= 6;
*--p = out[L & 0x3f]; L >>= 6;
*--p = out[L & 0x3f];
return result;
}