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