1 /*
2   Copyright (C) 1997-2005  Dimitrios P. Bouras
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18    For author contact information, look in the README file.
19 */
20 
21 /* Password encryption/decryption data structures and routines */
22 
23 #include <sys/param.h>
24 #if defined(USE_OPENSSL)
25 #include <openssl/des.h>
26 #else /* ! OpenSSL */
27 #if (defined(BSD) && BSD >= 199306)
28  #include <unistd.h>
29  #include <stdlib.h>
30 #endif
31 #endif /* OpenSSL */
32 
33 static unsigned char pkey[8] = {0x87,0xB6,0xAC,0xAF,0xC6,0xC8,0x94,0x8C},
34 					 ukey[64], upwd[64];
35 
36 /* Initializes the pcode module */
pcode_init(void)37 void pcode_init(void)
38 {
39 	int i;
40 
41 	for (i=0; i<8; i++)		/* since we don't want it sticking around */
42 		pkey[i] ^= 0xFF;	/* as plain text in the executable ;) */
43 }
44 
45 /* Packs 64 bits saved in array of char into 8 bytes */
cpack(unsigned char * pb,unsigned char * ub)46 static void cpack(unsigned char *pb, unsigned char *ub)
47 {
48 	int i,j;
49 	unsigned char mask, pc;
50 
51 	for (i=0; i<8; i++) {
52 		for (mask=0x80, pc=j=0; j<8; mask>>=1, j++) {
53 			pc |= (ub[i*8+j])? mask:0x00;
54 		}
55 		pb[i] = pc;
56 	}
57 }
58 
59 /* Unpacks 8 bytes into 64 bits saved in array of char */
cupack(unsigned char * ub,unsigned char * pb)60 static void cupack(unsigned char *ub, unsigned char *pb)
61 {
62 	int i,j;
63 
64 	for (i=0; i<8; i++) {
65 		for (j=0; j<8; j++) {
66 			ub[i*8+j] = (pb[i] & (0x80>>j)) ? 1:0;
67 		}
68 	}
69 }
70 
71 /* Encrypts the plain-text password of maximum length 64 bytes */
pencode(unsigned char * ep,unsigned char * pp)72 void pencode(unsigned char *ep, unsigned char *pp)
73 {
74 	int i;
75 #if defined(USE_OPENSSL)
76 	DES_key_schedule key;
77 #else
78 #if !(defined(BSD) && BSD >= 199306)
79  	void setkey(), encrypt();
80 #endif
81 #endif
82 
83 	cupack(ukey, pkey);				/* unpack the key */
84 #if defined(USE_OPENSSL)
85 	DES_set_key((DES_cblock *)ukey, &key);
86 #else
87 	setkey(ukey);					/* insert it in crypt's machine */
88 #endif
89 	for (i=0; i<8; i++) {			/* do all 64 bytes */
90 		cupack(upwd, pp);			/* unpack the plain-text password */
91 #if defined(USE_OPENSSL)
92 		DES_ecb_encrypt((const_DES_cblock *)upwd, (DES_cblock *)upwd, &key, 1);
93 #else
94 		encrypt(upwd, 0);			/* encrypt it in place */
95 #endif
96 		cpack(ep, upwd);			/* copy it out into the result */
97 		ep += 8; pp += 8;			/* get next 8 bytes */
98 	}
99 }
100 
101 /* Decrypts the password */
pdecode(unsigned char * pp,unsigned char * ep)102 void pdecode(unsigned char *pp, unsigned char *ep)
103 {
104 	int i;
105 #if defined(USE_OPENSSL)
106 	DES_key_schedule key;
107 #else
108 #if !(defined(BSD) && BSD >= 199306)
109 	void setkey(), encrypt();
110 #endif
111 #endif
112 
113 	cupack(ukey, pkey);				/* unpack the key */
114 #if defined(USE_OPENSSL)
115 	DES_set_key((DES_cblock *)ukey, &key);
116 #else
117 	setkey(ukey);					/* insert it in crypt's machine */
118 #endif
119 	for (i=0; i<8; i++) {			/* do all 64 bytes */
120 		cupack(upwd, ep);			/* unpack the encrypted password */
121 #if defined(USE_OPENSSL)
122 		DES_ecb_encrypt((const_DES_cblock *)upwd, (DES_cblock *)upwd, &key, 0);
123 #else
124 		encrypt(upwd, 1);			/* decrypt it in place */
125 #endif
126 		cpack(pp, upwd);			/* copy it out into the result */
127 		ep += 8; pp += 8;			/* get next 8 bytes */
128 	}
129 }
130 
131