This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Include fcrypt.c for crypt() on Windows
[perl5.git] / win32 / fcrypt.c
1 /* fcrypt.c */
2 /* Copyright (C) 1993 Eric Young - see README for more details */
3 #include <stdio.h>
4
5 /* Eric Young.
6  * This version of crypt has been developed from my MIT compatable
7  * DES library.
8  * The library is available at pub/DES at ftp.psy.uq.oz.au
9  * eay@psych.psy.uq.oz.au
10  */
11
12 typedef unsigned char des_cblock[8];
13
14 typedef struct des_ks_struct
15         {
16         union   {
17                 des_cblock _;
18                 /* make sure things are correct size on machines with
19                  * 8 byte longs */
20                 unsigned long pad[2];
21                 } ks;
22 #define _       ks._
23         } des_key_schedule[16];
24
25 #define DES_KEY_SZ      (sizeof(des_cblock))
26 #define DES_ENCRYPT     1
27 #define DES_DECRYPT     0
28
29 #define ITERATIONS 16
30 #define HALF_ITERATIONS 8
31
32 #define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
33                          l|=((unsigned long)(*((c)++)))<< 8, \
34                          l|=((unsigned long)(*((c)++)))<<16, \
35                          l|=((unsigned long)(*((c)++)))<<24)
36
37 #define l2c(l,c)        (*((c)++)=(unsigned char)(((l)    )&0xff), \
38                          *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
39                          *((c)++)=(unsigned char)(((l)>>16)&0xff), \
40                          *((c)++)=(unsigned char)(((l)>>24)&0xff))
41
42 static unsigned long SPtrans[8][64]={
43 /* nibble 0 */
44 0x00820200, 0x00020000, 0x80800000, 0x80820200,
45 0x00800000, 0x80020200, 0x80020000, 0x80800000,
46 0x80020200, 0x00820200, 0x00820000, 0x80000200,
47 0x80800200, 0x00800000, 0x00000000, 0x80020000,
48 0x00020000, 0x80000000, 0x00800200, 0x00020200,
49 0x80820200, 0x00820000, 0x80000200, 0x00800200,
50 0x80000000, 0x00000200, 0x00020200, 0x80820000,
51 0x00000200, 0x80800200, 0x80820000, 0x00000000,
52 0x00000000, 0x80820200, 0x00800200, 0x80020000,
53 0x00820200, 0x00020000, 0x80000200, 0x00800200,
54 0x80820000, 0x00000200, 0x00020200, 0x80800000,
55 0x80020200, 0x80000000, 0x80800000, 0x00820000,
56 0x80820200, 0x00020200, 0x00820000, 0x80800200,
57 0x00800000, 0x80000200, 0x80020000, 0x00000000,
58 0x00020000, 0x00800000, 0x80800200, 0x00820200,
59 0x80000000, 0x80820000, 0x00000200, 0x80020200,
60 /* nibble 1 */
61 0x10042004, 0x00000000, 0x00042000, 0x10040000,
62 0x10000004, 0x00002004, 0x10002000, 0x00042000,
63 0x00002000, 0x10040004, 0x00000004, 0x10002000,
64 0x00040004, 0x10042000, 0x10040000, 0x00000004,
65 0x00040000, 0x10002004, 0x10040004, 0x00002000,
66 0x00042004, 0x10000000, 0x00000000, 0x00040004,
67 0x10002004, 0x00042004, 0x10042000, 0x10000004,
68 0x10000000, 0x00040000, 0x00002004, 0x10042004,
69 0x00040004, 0x10042000, 0x10002000, 0x00042004,
70 0x10042004, 0x00040004, 0x10000004, 0x00000000,
71 0x10000000, 0x00002004, 0x00040000, 0x10040004,
72 0x00002000, 0x10000000, 0x00042004, 0x10002004,
73 0x10042000, 0x00002000, 0x00000000, 0x10000004,
74 0x00000004, 0x10042004, 0x00042000, 0x10040000,
75 0x10040004, 0x00040000, 0x00002004, 0x10002000,
76 0x10002004, 0x00000004, 0x10040000, 0x00042000,
77 /* nibble 2 */
78 0x41000000, 0x01010040, 0x00000040, 0x41000040,
79 0x40010000, 0x01000000, 0x41000040, 0x00010040,
80 0x01000040, 0x00010000, 0x01010000, 0x40000000,
81 0x41010040, 0x40000040, 0x40000000, 0x41010000,
82 0x00000000, 0x40010000, 0x01010040, 0x00000040,
83 0x40000040, 0x41010040, 0x00010000, 0x41000000,
84 0x41010000, 0x01000040, 0x40010040, 0x01010000,
85 0x00010040, 0x00000000, 0x01000000, 0x40010040,
86 0x01010040, 0x00000040, 0x40000000, 0x00010000,
87 0x40000040, 0x40010000, 0x01010000, 0x41000040,
88 0x00000000, 0x01010040, 0x00010040, 0x41010000,
89 0x40010000, 0x01000000, 0x41010040, 0x40000000,
90 0x40010040, 0x41000000, 0x01000000, 0x41010040,
91 0x00010000, 0x01000040, 0x41000040, 0x00010040,
92 0x01000040, 0x00000000, 0x41010000, 0x40000040,
93 0x41000000, 0x40010040, 0x00000040, 0x01010000,
94 /* nibble 3 */
95 0x00100402, 0x04000400, 0x00000002, 0x04100402,
96 0x00000000, 0x04100000, 0x04000402, 0x00100002,
97 0x04100400, 0x04000002, 0x04000000, 0x00000402,
98 0x04000002, 0x00100402, 0x00100000, 0x04000000,
99 0x04100002, 0x00100400, 0x00000400, 0x00000002,
100 0x00100400, 0x04000402, 0x04100000, 0x00000400,
101 0x00000402, 0x00000000, 0x00100002, 0x04100400,
102 0x04000400, 0x04100002, 0x04100402, 0x00100000,
103 0x04100002, 0x00000402, 0x00100000, 0x04000002,
104 0x00100400, 0x04000400, 0x00000002, 0x04100000,
105 0x04000402, 0x00000000, 0x00000400, 0x00100002,
106 0x00000000, 0x04100002, 0x04100400, 0x00000400,
107 0x04000000, 0x04100402, 0x00100402, 0x00100000,
108 0x04100402, 0x00000002, 0x04000400, 0x00100402,
109 0x00100002, 0x00100400, 0x04100000, 0x04000402,
110 0x00000402, 0x04000000, 0x04000002, 0x04100400,
111 /* nibble 4 */
112 0x02000000, 0x00004000, 0x00000100, 0x02004108,
113 0x02004008, 0x02000100, 0x00004108, 0x02004000,
114 0x00004000, 0x00000008, 0x02000008, 0x00004100,
115 0x02000108, 0x02004008, 0x02004100, 0x00000000,
116 0x00004100, 0x02000000, 0x00004008, 0x00000108,
117 0x02000100, 0x00004108, 0x00000000, 0x02000008,
118 0x00000008, 0x02000108, 0x02004108, 0x00004008,
119 0x02004000, 0x00000100, 0x00000108, 0x02004100,
120 0x02004100, 0x02000108, 0x00004008, 0x02004000,
121 0x00004000, 0x00000008, 0x02000008, 0x02000100,
122 0x02000000, 0x00004100, 0x02004108, 0x00000000,
123 0x00004108, 0x02000000, 0x00000100, 0x00004008,
124 0x02000108, 0x00000100, 0x00000000, 0x02004108,
125 0x02004008, 0x02004100, 0x00000108, 0x00004000,
126 0x00004100, 0x02004008, 0x02000100, 0x00000108,
127 0x00000008, 0x00004108, 0x02004000, 0x02000008,
128 /* nibble 5 */
129 0x20000010, 0x00080010, 0x00000000, 0x20080800,
130 0x00080010, 0x00000800, 0x20000810, 0x00080000,
131 0x00000810, 0x20080810, 0x00080800, 0x20000000,
132 0x20000800, 0x20000010, 0x20080000, 0x00080810,
133 0x00080000, 0x20000810, 0x20080010, 0x00000000,
134 0x00000800, 0x00000010, 0x20080800, 0x20080010,
135 0x20080810, 0x20080000, 0x20000000, 0x00000810,
136 0x00000010, 0x00080800, 0x00080810, 0x20000800,
137 0x00000810, 0x20000000, 0x20000800, 0x00080810,
138 0x20080800, 0x00080010, 0x00000000, 0x20000800,
139 0x20000000, 0x00000800, 0x20080010, 0x00080000,
140 0x00080010, 0x20080810, 0x00080800, 0x00000010,
141 0x20080810, 0x00080800, 0x00080000, 0x20000810,
142 0x20000010, 0x20080000, 0x00080810, 0x00000000,
143 0x00000800, 0x20000010, 0x20000810, 0x20080800,
144 0x20080000, 0x00000810, 0x00000010, 0x20080010,
145 /* nibble 6 */
146 0x00001000, 0x00000080, 0x00400080, 0x00400001,
147 0x00401081, 0x00001001, 0x00001080, 0x00000000,
148 0x00400000, 0x00400081, 0x00000081, 0x00401000,
149 0x00000001, 0x00401080, 0x00401000, 0x00000081,
150 0x00400081, 0x00001000, 0x00001001, 0x00401081,
151 0x00000000, 0x00400080, 0x00400001, 0x00001080,
152 0x00401001, 0x00001081, 0x00401080, 0x00000001,
153 0x00001081, 0x00401001, 0x00000080, 0x00400000,
154 0x00001081, 0x00401000, 0x00401001, 0x00000081,
155 0x00001000, 0x00000080, 0x00400000, 0x00401001,
156 0x00400081, 0x00001081, 0x00001080, 0x00000000,
157 0x00000080, 0x00400001, 0x00000001, 0x00400080,
158 0x00000000, 0x00400081, 0x00400080, 0x00001080,
159 0x00000081, 0x00001000, 0x00401081, 0x00400000,
160 0x00401080, 0x00000001, 0x00001001, 0x00401081,
161 0x00400001, 0x00401080, 0x00401000, 0x00001001,
162 /* nibble 7 */
163 0x08200020, 0x08208000, 0x00008020, 0x00000000,
164 0x08008000, 0x00200020, 0x08200000, 0x08208020,
165 0x00000020, 0x08000000, 0x00208000, 0x00008020,
166 0x00208020, 0x08008020, 0x08000020, 0x08200000,
167 0x00008000, 0x00208020, 0x00200020, 0x08008000,
168 0x08208020, 0x08000020, 0x00000000, 0x00208000,
169 0x08000000, 0x00200000, 0x08008020, 0x08200020,
170 0x00200000, 0x00008000, 0x08208000, 0x00000020,
171 0x00200000, 0x00008000, 0x08000020, 0x08208020,
172 0x00008020, 0x08000000, 0x00000000, 0x00208000,
173 0x08200020, 0x08008020, 0x08008000, 0x00200020,
174 0x08208000, 0x00000020, 0x00200020, 0x08008000,
175 0x08208020, 0x00200000, 0x08200000, 0x08000020,
176 0x00208000, 0x00008020, 0x08008020, 0x08200000,
177 0x00000020, 0x08208000, 0x00208020, 0x00000000,
178 0x08000000, 0x08200020, 0x00008000, 0x00208020};
179 static unsigned long skb[8][64]={
180 /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
181 0x00000000,0x00000010,0x20000000,0x20000010,
182 0x00010000,0x00010010,0x20010000,0x20010010,
183 0x00000800,0x00000810,0x20000800,0x20000810,
184 0x00010800,0x00010810,0x20010800,0x20010810,
185 0x00000020,0x00000030,0x20000020,0x20000030,
186 0x00010020,0x00010030,0x20010020,0x20010030,
187 0x00000820,0x00000830,0x20000820,0x20000830,
188 0x00010820,0x00010830,0x20010820,0x20010830,
189 0x00080000,0x00080010,0x20080000,0x20080010,
190 0x00090000,0x00090010,0x20090000,0x20090010,
191 0x00080800,0x00080810,0x20080800,0x20080810,
192 0x00090800,0x00090810,0x20090800,0x20090810,
193 0x00080020,0x00080030,0x20080020,0x20080030,
194 0x00090020,0x00090030,0x20090020,0x20090030,
195 0x00080820,0x00080830,0x20080820,0x20080830,
196 0x00090820,0x00090830,0x20090820,0x20090830,
197 /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
198 0x00000000,0x02000000,0x00002000,0x02002000,
199 0x00200000,0x02200000,0x00202000,0x02202000,
200 0x00000004,0x02000004,0x00002004,0x02002004,
201 0x00200004,0x02200004,0x00202004,0x02202004,
202 0x00000400,0x02000400,0x00002400,0x02002400,
203 0x00200400,0x02200400,0x00202400,0x02202400,
204 0x00000404,0x02000404,0x00002404,0x02002404,
205 0x00200404,0x02200404,0x00202404,0x02202404,
206 0x10000000,0x12000000,0x10002000,0x12002000,
207 0x10200000,0x12200000,0x10202000,0x12202000,
208 0x10000004,0x12000004,0x10002004,0x12002004,
209 0x10200004,0x12200004,0x10202004,0x12202004,
210 0x10000400,0x12000400,0x10002400,0x12002400,
211 0x10200400,0x12200400,0x10202400,0x12202400,
212 0x10000404,0x12000404,0x10002404,0x12002404,
213 0x10200404,0x12200404,0x10202404,0x12202404,
214 /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
215 0x00000000,0x00000001,0x00040000,0x00040001,
216 0x01000000,0x01000001,0x01040000,0x01040001,
217 0x00000002,0x00000003,0x00040002,0x00040003,
218 0x01000002,0x01000003,0x01040002,0x01040003,
219 0x00000200,0x00000201,0x00040200,0x00040201,
220 0x01000200,0x01000201,0x01040200,0x01040201,
221 0x00000202,0x00000203,0x00040202,0x00040203,
222 0x01000202,0x01000203,0x01040202,0x01040203,
223 0x08000000,0x08000001,0x08040000,0x08040001,
224 0x09000000,0x09000001,0x09040000,0x09040001,
225 0x08000002,0x08000003,0x08040002,0x08040003,
226 0x09000002,0x09000003,0x09040002,0x09040003,
227 0x08000200,0x08000201,0x08040200,0x08040201,
228 0x09000200,0x09000201,0x09040200,0x09040201,
229 0x08000202,0x08000203,0x08040202,0x08040203,
230 0x09000202,0x09000203,0x09040202,0x09040203,
231 /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
232 0x00000000,0x00100000,0x00000100,0x00100100,
233 0x00000008,0x00100008,0x00000108,0x00100108,
234 0x00001000,0x00101000,0x00001100,0x00101100,
235 0x00001008,0x00101008,0x00001108,0x00101108,
236 0x04000000,0x04100000,0x04000100,0x04100100,
237 0x04000008,0x04100008,0x04000108,0x04100108,
238 0x04001000,0x04101000,0x04001100,0x04101100,
239 0x04001008,0x04101008,0x04001108,0x04101108,
240 0x00020000,0x00120000,0x00020100,0x00120100,
241 0x00020008,0x00120008,0x00020108,0x00120108,
242 0x00021000,0x00121000,0x00021100,0x00121100,
243 0x00021008,0x00121008,0x00021108,0x00121108,
244 0x04020000,0x04120000,0x04020100,0x04120100,
245 0x04020008,0x04120008,0x04020108,0x04120108,
246 0x04021000,0x04121000,0x04021100,0x04121100,
247 0x04021008,0x04121008,0x04021108,0x04121108,
248 /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
249 0x00000000,0x10000000,0x00010000,0x10010000,
250 0x00000004,0x10000004,0x00010004,0x10010004,
251 0x20000000,0x30000000,0x20010000,0x30010000,
252 0x20000004,0x30000004,0x20010004,0x30010004,
253 0x00100000,0x10100000,0x00110000,0x10110000,
254 0x00100004,0x10100004,0x00110004,0x10110004,
255 0x20100000,0x30100000,0x20110000,0x30110000,
256 0x20100004,0x30100004,0x20110004,0x30110004,
257 0x00001000,0x10001000,0x00011000,0x10011000,
258 0x00001004,0x10001004,0x00011004,0x10011004,
259 0x20001000,0x30001000,0x20011000,0x30011000,
260 0x20001004,0x30001004,0x20011004,0x30011004,
261 0x00101000,0x10101000,0x00111000,0x10111000,
262 0x00101004,0x10101004,0x00111004,0x10111004,
263 0x20101000,0x30101000,0x20111000,0x30111000,
264 0x20101004,0x30101004,0x20111004,0x30111004,
265 /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
266 0x00000000,0x08000000,0x00000008,0x08000008,
267 0x00000400,0x08000400,0x00000408,0x08000408,
268 0x00020000,0x08020000,0x00020008,0x08020008,
269 0x00020400,0x08020400,0x00020408,0x08020408,
270 0x00000001,0x08000001,0x00000009,0x08000009,
271 0x00000401,0x08000401,0x00000409,0x08000409,
272 0x00020001,0x08020001,0x00020009,0x08020009,
273 0x00020401,0x08020401,0x00020409,0x08020409,
274 0x02000000,0x0A000000,0x02000008,0x0A000008,
275 0x02000400,0x0A000400,0x02000408,0x0A000408,
276 0x02020000,0x0A020000,0x02020008,0x0A020008,
277 0x02020400,0x0A020400,0x02020408,0x0A020408,
278 0x02000001,0x0A000001,0x02000009,0x0A000009,
279 0x02000401,0x0A000401,0x02000409,0x0A000409,
280 0x02020001,0x0A020001,0x02020009,0x0A020009,
281 0x02020401,0x0A020401,0x02020409,0x0A020409,
282 /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
283 0x00000000,0x00000100,0x00080000,0x00080100,
284 0x01000000,0x01000100,0x01080000,0x01080100,
285 0x00000010,0x00000110,0x00080010,0x00080110,
286 0x01000010,0x01000110,0x01080010,0x01080110,
287 0x00200000,0x00200100,0x00280000,0x00280100,
288 0x01200000,0x01200100,0x01280000,0x01280100,
289 0x00200010,0x00200110,0x00280010,0x00280110,
290 0x01200010,0x01200110,0x01280010,0x01280110,
291 0x00000200,0x00000300,0x00080200,0x00080300,
292 0x01000200,0x01000300,0x01080200,0x01080300,
293 0x00000210,0x00000310,0x00080210,0x00080310,
294 0x01000210,0x01000310,0x01080210,0x01080310,
295 0x00200200,0x00200300,0x00280200,0x00280300,
296 0x01200200,0x01200300,0x01280200,0x01280300,
297 0x00200210,0x00200310,0x00280210,0x00280310,
298 0x01200210,0x01200310,0x01280210,0x01280310,
299 /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
300 0x00000000,0x04000000,0x00040000,0x04040000,
301 0x00000002,0x04000002,0x00040002,0x04040002,
302 0x00002000,0x04002000,0x00042000,0x04042000,
303 0x00002002,0x04002002,0x00042002,0x04042002,
304 0x00000020,0x04000020,0x00040020,0x04040020,
305 0x00000022,0x04000022,0x00040022,0x04040022,
306 0x00002020,0x04002020,0x00042020,0x04042020,
307 0x00002022,0x04002022,0x00042022,0x04042022,
308 0x00000800,0x04000800,0x00040800,0x04040800,
309 0x00000802,0x04000802,0x00040802,0x04040802,
310 0x00002800,0x04002800,0x00042800,0x04042800,
311 0x00002802,0x04002802,0x00042802,0x04042802,
312 0x00000820,0x04000820,0x00040820,0x04040820,
313 0x00000822,0x04000822,0x00040822,0x04040822,
314 0x00002820,0x04002820,0x00042820,0x04042820,
315 0x00002822,0x04002822,0x00042822,0x04042822,
316 };
317
318 /* See ecb_encrypt.c for a pseudo description of these macros. */
319 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
320         (b)^=(t),\
321         (a)^=((t)<<(n)))
322
323 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
324         (a)=(a)^(t)^(t>>(16-(n))))\
325
326 static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
327
328 static int body(
329         unsigned long *out0,
330         unsigned long *out1,
331         des_key_schedule ks,
332         unsigned long Eswap0,
333         unsigned long Eswap1);
334
335 static int
336 des_set_key(des_cblock *key, des_key_schedule schedule)
337         {
338         register unsigned long c,d,t,s;
339         register unsigned char *in;
340         register unsigned long *k;
341         register int i;
342
343         k=(unsigned long *)schedule;
344         in=(unsigned char *)key;
345
346         c2l(in,c);
347         c2l(in,d);
348
349         /* I now do it in 47 simple operations :-)
350          * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
351          * for the inspiration. :-) */
352         PERM_OP (d,c,t,4,0x0f0f0f0f);
353         HPERM_OP(c,t,-2,0xcccc0000);
354         HPERM_OP(d,t,-2,0xcccc0000);
355         PERM_OP (d,c,t,1,0x55555555);
356         PERM_OP (c,d,t,8,0x00ff00ff);
357         PERM_OP (d,c,t,1,0x55555555);
358         d=      (((d&0x000000ff)<<16)| (d&0x0000ff00)     |
359                  ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
360         c&=0x0fffffff;
361
362         for (i=0; i<ITERATIONS; i++)
363                 {
364                 if (shifts2[i])
365                         { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
366                 else
367                         { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
368                 c&=0x0fffffff;
369                 d&=0x0fffffff;
370                 /* could be a few less shifts but I am to lazy at this
371                  * point in time to investigate */
372                 s=      skb[0][ (c    )&0x3f                ]|
373                         skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
374                         skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
375                         skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
376                                               ((c>>22)&0x38)];
377                 t=      skb[4][ (d    )&0x3f                ]|
378                         skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
379                         skb[6][ (d>>15)&0x3f                ]|
380                         skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
381
382                 /* table contained 0213 4657 */
383                 *(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
384                 s=     ((s>>16)|(t&0xffff0000));
385                 
386                 s=(s<<4)|(s>>28);
387                 *(k++)=s&0xffffffff;
388                 }
389         return(0);
390         }
391
392 /******************************************************************
393  * modified stuff for crypt.
394  ******************************************************************/
395
396 /* The changes to this macro may help or hinder, depending on the
397  * compiler and the achitecture.  gcc2 always seems to do well :-). 
398  * Inspired by Dana How <how@isl.stanford.edu>
399  * DO NOT use the alternative version on machines with 8 byte longs.
400  */
401 #ifdef ALT_ECB
402 #define D_ENCRYPT(L,R,S) \
403         v=(R^(R>>16)); \
404         u=(v&E0); \
405         v=(v&E1); \
406         u=((u^(u<<16))^R^s[S  ])<<2; \
407         t=(v^(v<<16))^R^s[S+1]; \
408         t=(t>>2)|(t<<30); \
409         L^= \
410         *(unsigned long *)(des_SP+0x0100+((t    )&0xfc))+ \
411         *(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
412         *(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
413         *(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
414         *(unsigned long *)(des_SP+       ((u    )&0xfc))+ \
415         *(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
416         *(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
417         *(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
418 #else /* original version */
419 #define D_ENCRYPT(L,R,S)        \
420         v=(R^(R>>16)); \
421         u=(v&E0); \
422         v=(v&E1); \
423         u=(u^(u<<16))^R^s[S  ]; \
424         t=(v^(v<<16))^R^s[S+1]; \
425         t=(t>>4)|(t<<28); \
426         L^=     SPtrans[1][(t    )&0x3f]| \
427                 SPtrans[3][(t>> 8)&0x3f]| \
428                 SPtrans[5][(t>>16)&0x3f]| \
429                 SPtrans[7][(t>>24)&0x3f]| \
430                 SPtrans[0][(u    )&0x3f]| \
431                 SPtrans[2][(u>> 8)&0x3f]| \
432                 SPtrans[4][(u>>16)&0x3f]| \
433                 SPtrans[6][(u>>24)&0x3f];
434 #endif
435
436 unsigned char con_salt[128]={
437 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
438 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
439 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
440 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
441 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
442 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
443 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
444 0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
445 0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
446 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
447 0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
448 0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
449 0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
450 0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
451 0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
452 0x3D,0x3E,0x3F,0x00,0x00,0x00,0x00,0x00,
453 };
454
455 unsigned char cov_2char[64]={
456 0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
457 0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
458 0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
459 0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
460 0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
461 0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
462 0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
463 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
464 };
465
466 char *
467 des_fcrypt(const char *buf, const char *salt, char *buff)
468         {
469         unsigned int i,j,x,y;
470         unsigned long Eswap0=0,Eswap1=0;
471         unsigned long out[2],ll;
472         des_cblock key;
473         des_key_schedule ks;
474         unsigned char bb[9];
475         unsigned char *b=bb;
476         unsigned char c,u;
477
478         /* eay 25/08/92
479          * If you call crypt("pwd","*") as often happens when you
480          * have * as the pwd field in /etc/passwd, the function
481          * returns *\0XXXXXXXXX
482          * The \0 makes the string look like * so the pwd "*" would
483          * crypt to "*".  This was found when replacing the crypt in
484          * our shared libraries.  People found that the disbled
485          * accounts effectivly had no passwd :-(. */
486         x=buff[0]=((salt[0] == '\0')?'A':salt[0]);
487         Eswap0=con_salt[x];
488         x=buff[1]=((salt[1] == '\0')?'A':salt[1]);
489         Eswap1=con_salt[x]<<4;
490
491         for (i=0; i<8; i++)
492                 {
493                 c= *(buf++);
494                 if (!c) break;
495                 key[i]=(c<<1);
496                 }
497         for (; i<8; i++)
498                 key[i]=0;
499
500         des_set_key((des_cblock *)(key),ks);
501         body(&out[0],&out[1],ks,Eswap0,Eswap1);
502
503         ll=out[0]; l2c(ll,b);
504         ll=out[1]; l2c(ll,b);
505         y=0;
506         u=0x80;
507         bb[8]=0;
508         for (i=2; i<13; i++)
509                 {
510                 c=0;
511                 for (j=0; j<6; j++)
512                         {
513                         c<<=1;
514                         if (bb[y] & u) c|=1;
515                         u>>=1;
516                         if (!u)
517                                 {
518                                 y++;
519                                 u=0x80;
520                                 }
521                         }
522                 buff[i]=cov_2char[c];
523                 }
524         buff[13]='\0';
525         return buff;
526         }
527
528 static int 
529 body(   unsigned long *out0,
530         unsigned long *out1,
531         des_key_schedule ks,
532         unsigned long Eswap0,
533         unsigned long Eswap1)
534         {
535         register unsigned long l,r,t,u,v;
536 #ifdef ALT_ECB
537         register unsigned char *des_SP=(unsigned char *)SPtrans;
538 #endif
539         register unsigned long *s;
540         register int i,j;
541         register unsigned long E0,E1;
542
543         l=0;
544         r=0;
545
546         s=(unsigned long *)ks;
547         E0=Eswap0;
548         E1=Eswap1;
549
550         for (j=0; j<25; j++)
551                 {
552                 for (i=0; i<(ITERATIONS*2); i+=4)
553                         {
554                         D_ENCRYPT(l,r,  i);     /*  1 */
555                         D_ENCRYPT(r,l,  i+2);   /*  2 */
556                         }
557                 t=l;
558                 l=r;
559                 r=t;
560                 }
561         t=r;
562         r=(l>>1)|(l<<31);
563         l=(t>>1)|(t<<31);
564         /* clear the top bits on machines with 8byte longs */
565         l&=0xffffffff;
566         r&=0xffffffff;
567
568         PERM_OP(r,l,t, 1,0x55555555);
569         PERM_OP(l,r,t, 8,0x00ff00ff);
570         PERM_OP(r,l,t, 2,0x33333333);
571         PERM_OP(l,r,t,16,0x0000ffff);
572         PERM_OP(r,l,t, 4,0x0f0f0f0f);
573
574         *out0=l;
575         *out1=r;
576         return(0);
577         }
578