# 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; }