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