2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk>
[kopensolaris-gnu/glibc.git] / sunrpc / des_impl.c
1 /* Copyright (C) 1992 Eric Young */
2 /* Collected from libdes and modified for SECURE RPC by Martin Kuck 1994 */
3 /* This file is distributed under the terms of the GNU Lesser General */
4 /* Public License, version 2.1 or later - see the file COPYING.LIB for details.*/
5 /* If you did not receive a copy of the license with this program, please*/
6 /* write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,*/
7 /* Boston, MA 02111, USA to obtain a copy. */
8 #include <string.h>
9 #include "des.h"
10
11
12 static const unsigned long des_SPtrans[8][64] =
13 {
14   {                             /* nibble 0 */
15     0x00820200, 0x00020000, 0x80800000, 0x80820200,
16     0x00800000, 0x80020200, 0x80020000, 0x80800000,
17     0x80020200, 0x00820200, 0x00820000, 0x80000200,
18     0x80800200, 0x00800000, 0x00000000, 0x80020000,
19     0x00020000, 0x80000000, 0x00800200, 0x00020200,
20     0x80820200, 0x00820000, 0x80000200, 0x00800200,
21     0x80000000, 0x00000200, 0x00020200, 0x80820000,
22     0x00000200, 0x80800200, 0x80820000, 0x00000000,
23     0x00000000, 0x80820200, 0x00800200, 0x80020000,
24     0x00820200, 0x00020000, 0x80000200, 0x00800200,
25     0x80820000, 0x00000200, 0x00020200, 0x80800000,
26     0x80020200, 0x80000000, 0x80800000, 0x00820000,
27     0x80820200, 0x00020200, 0x00820000, 0x80800200,
28     0x00800000, 0x80000200, 0x80020000, 0x00000000,
29     0x00020000, 0x00800000, 0x80800200, 0x00820200,
30     0x80000000, 0x80820000, 0x00000200, 0x80020200},
31
32   {                             /* nibble 1 */
33     0x10042004, 0x00000000, 0x00042000, 0x10040000,
34     0x10000004, 0x00002004, 0x10002000, 0x00042000,
35     0x00002000, 0x10040004, 0x00000004, 0x10002000,
36     0x00040004, 0x10042000, 0x10040000, 0x00000004,
37     0x00040000, 0x10002004, 0x10040004, 0x00002000,
38     0x00042004, 0x10000000, 0x00000000, 0x00040004,
39     0x10002004, 0x00042004, 0x10042000, 0x10000004,
40     0x10000000, 0x00040000, 0x00002004, 0x10042004,
41     0x00040004, 0x10042000, 0x10002000, 0x00042004,
42     0x10042004, 0x00040004, 0x10000004, 0x00000000,
43     0x10000000, 0x00002004, 0x00040000, 0x10040004,
44     0x00002000, 0x10000000, 0x00042004, 0x10002004,
45     0x10042000, 0x00002000, 0x00000000, 0x10000004,
46     0x00000004, 0x10042004, 0x00042000, 0x10040000,
47     0x10040004, 0x00040000, 0x00002004, 0x10002000,
48     0x10002004, 0x00000004, 0x10040000, 0x00042000},
49
50   {                             /* nibble 2 */
51     0x41000000, 0x01010040, 0x00000040, 0x41000040,
52     0x40010000, 0x01000000, 0x41000040, 0x00010040,
53     0x01000040, 0x00010000, 0x01010000, 0x40000000,
54     0x41010040, 0x40000040, 0x40000000, 0x41010000,
55     0x00000000, 0x40010000, 0x01010040, 0x00000040,
56     0x40000040, 0x41010040, 0x00010000, 0x41000000,
57     0x41010000, 0x01000040, 0x40010040, 0x01010000,
58     0x00010040, 0x00000000, 0x01000000, 0x40010040,
59     0x01010040, 0x00000040, 0x40000000, 0x00010000,
60     0x40000040, 0x40010000, 0x01010000, 0x41000040,
61     0x00000000, 0x01010040, 0x00010040, 0x41010000,
62     0x40010000, 0x01000000, 0x41010040, 0x40000000,
63     0x40010040, 0x41000000, 0x01000000, 0x41010040,
64     0x00010000, 0x01000040, 0x41000040, 0x00010040,
65     0x01000040, 0x00000000, 0x41010000, 0x40000040,
66     0x41000000, 0x40010040, 0x00000040, 0x01010000},
67
68   {                             /* nibble 3 */
69     0x00100402, 0x04000400, 0x00000002, 0x04100402,
70     0x00000000, 0x04100000, 0x04000402, 0x00100002,
71     0x04100400, 0x04000002, 0x04000000, 0x00000402,
72     0x04000002, 0x00100402, 0x00100000, 0x04000000,
73     0x04100002, 0x00100400, 0x00000400, 0x00000002,
74     0x00100400, 0x04000402, 0x04100000, 0x00000400,
75     0x00000402, 0x00000000, 0x00100002, 0x04100400,
76     0x04000400, 0x04100002, 0x04100402, 0x00100000,
77     0x04100002, 0x00000402, 0x00100000, 0x04000002,
78     0x00100400, 0x04000400, 0x00000002, 0x04100000,
79     0x04000402, 0x00000000, 0x00000400, 0x00100002,
80     0x00000000, 0x04100002, 0x04100400, 0x00000400,
81     0x04000000, 0x04100402, 0x00100402, 0x00100000,
82     0x04100402, 0x00000002, 0x04000400, 0x00100402,
83     0x00100002, 0x00100400, 0x04100000, 0x04000402,
84     0x00000402, 0x04000000, 0x04000002, 0x04100400},
85
86   {                             /* nibble 4 */
87     0x02000000, 0x00004000, 0x00000100, 0x02004108,
88     0x02004008, 0x02000100, 0x00004108, 0x02004000,
89     0x00004000, 0x00000008, 0x02000008, 0x00004100,
90     0x02000108, 0x02004008, 0x02004100, 0x00000000,
91     0x00004100, 0x02000000, 0x00004008, 0x00000108,
92     0x02000100, 0x00004108, 0x00000000, 0x02000008,
93     0x00000008, 0x02000108, 0x02004108, 0x00004008,
94     0x02004000, 0x00000100, 0x00000108, 0x02004100,
95     0x02004100, 0x02000108, 0x00004008, 0x02004000,
96     0x00004000, 0x00000008, 0x02000008, 0x02000100,
97     0x02000000, 0x00004100, 0x02004108, 0x00000000,
98     0x00004108, 0x02000000, 0x00000100, 0x00004008,
99     0x02000108, 0x00000100, 0x00000000, 0x02004108,
100     0x02004008, 0x02004100, 0x00000108, 0x00004000,
101     0x00004100, 0x02004008, 0x02000100, 0x00000108,
102     0x00000008, 0x00004108, 0x02004000, 0x02000008},
103
104   {                             /* nibble 5 */
105     0x20000010, 0x00080010, 0x00000000, 0x20080800,
106     0x00080010, 0x00000800, 0x20000810, 0x00080000,
107     0x00000810, 0x20080810, 0x00080800, 0x20000000,
108     0x20000800, 0x20000010, 0x20080000, 0x00080810,
109     0x00080000, 0x20000810, 0x20080010, 0x00000000,
110     0x00000800, 0x00000010, 0x20080800, 0x20080010,
111     0x20080810, 0x20080000, 0x20000000, 0x00000810,
112     0x00000010, 0x00080800, 0x00080810, 0x20000800,
113     0x00000810, 0x20000000, 0x20000800, 0x00080810,
114     0x20080800, 0x00080010, 0x00000000, 0x20000800,
115     0x20000000, 0x00000800, 0x20080010, 0x00080000,
116     0x00080010, 0x20080810, 0x00080800, 0x00000010,
117     0x20080810, 0x00080800, 0x00080000, 0x20000810,
118     0x20000010, 0x20080000, 0x00080810, 0x00000000,
119     0x00000800, 0x20000010, 0x20000810, 0x20080800,
120     0x20080000, 0x00000810, 0x00000010, 0x20080010},
121
122   {                             /* nibble 6 */
123     0x00001000, 0x00000080, 0x00400080, 0x00400001,
124     0x00401081, 0x00001001, 0x00001080, 0x00000000,
125     0x00400000, 0x00400081, 0x00000081, 0x00401000,
126     0x00000001, 0x00401080, 0x00401000, 0x00000081,
127     0x00400081, 0x00001000, 0x00001001, 0x00401081,
128     0x00000000, 0x00400080, 0x00400001, 0x00001080,
129     0x00401001, 0x00001081, 0x00401080, 0x00000001,
130     0x00001081, 0x00401001, 0x00000080, 0x00400000,
131     0x00001081, 0x00401000, 0x00401001, 0x00000081,
132     0x00001000, 0x00000080, 0x00400000, 0x00401001,
133     0x00400081, 0x00001081, 0x00001080, 0x00000000,
134     0x00000080, 0x00400001, 0x00000001, 0x00400080,
135     0x00000000, 0x00400081, 0x00400080, 0x00001080,
136     0x00000081, 0x00001000, 0x00401081, 0x00400000,
137     0x00401080, 0x00000001, 0x00001001, 0x00401081,
138     0x00400001, 0x00401080, 0x00401000, 0x00001001},
139
140   {                             /* nibble 7 */
141     0x08200020, 0x08208000, 0x00008020, 0x00000000,
142     0x08008000, 0x00200020, 0x08200000, 0x08208020,
143     0x00000020, 0x08000000, 0x00208000, 0x00008020,
144     0x00208020, 0x08008020, 0x08000020, 0x08200000,
145     0x00008000, 0x00208020, 0x00200020, 0x08008000,
146     0x08208020, 0x08000020, 0x00000000, 0x00208000,
147     0x08000000, 0x00200000, 0x08008020, 0x08200020,
148     0x00200000, 0x00008000, 0x08208000, 0x00000020,
149     0x00200000, 0x00008000, 0x08000020, 0x08208020,
150     0x00008020, 0x08000000, 0x00000000, 0x00208000,
151     0x08200020, 0x08008020, 0x08008000, 0x00200020,
152     0x08208000, 0x00000020, 0x00200020, 0x08008000,
153     0x08208020, 0x00200000, 0x08200000, 0x08000020,
154     0x00208000, 0x00008020, 0x08008020, 0x08200000,
155     0x00000020, 0x08208000, 0x00208020, 0x00000000,
156     0x08000000, 0x08200020, 0x00008000, 0x00208020}};
157
158 static const unsigned long des_skb[8][64] =
159 {
160   {                             /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
161     0x00000000, 0x00000010, 0x20000000, 0x20000010,
162     0x00010000, 0x00010010, 0x20010000, 0x20010010,
163     0x00000800, 0x00000810, 0x20000800, 0x20000810,
164     0x00010800, 0x00010810, 0x20010800, 0x20010810,
165     0x00000020, 0x00000030, 0x20000020, 0x20000030,
166     0x00010020, 0x00010030, 0x20010020, 0x20010030,
167     0x00000820, 0x00000830, 0x20000820, 0x20000830,
168     0x00010820, 0x00010830, 0x20010820, 0x20010830,
169     0x00080000, 0x00080010, 0x20080000, 0x20080010,
170     0x00090000, 0x00090010, 0x20090000, 0x20090010,
171     0x00080800, 0x00080810, 0x20080800, 0x20080810,
172     0x00090800, 0x00090810, 0x20090800, 0x20090810,
173     0x00080020, 0x00080030, 0x20080020, 0x20080030,
174     0x00090020, 0x00090030, 0x20090020, 0x20090030,
175     0x00080820, 0x00080830, 0x20080820, 0x20080830,
176     0x00090820, 0x00090830, 0x20090820, 0x20090830},
177   {                             /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
178     0x00000000, 0x02000000, 0x00002000, 0x02002000,
179     0x00200000, 0x02200000, 0x00202000, 0x02202000,
180     0x00000004, 0x02000004, 0x00002004, 0x02002004,
181     0x00200004, 0x02200004, 0x00202004, 0x02202004,
182     0x00000400, 0x02000400, 0x00002400, 0x02002400,
183     0x00200400, 0x02200400, 0x00202400, 0x02202400,
184     0x00000404, 0x02000404, 0x00002404, 0x02002404,
185     0x00200404, 0x02200404, 0x00202404, 0x02202404,
186     0x10000000, 0x12000000, 0x10002000, 0x12002000,
187     0x10200000, 0x12200000, 0x10202000, 0x12202000,
188     0x10000004, 0x12000004, 0x10002004, 0x12002004,
189     0x10200004, 0x12200004, 0x10202004, 0x12202004,
190     0x10000400, 0x12000400, 0x10002400, 0x12002400,
191     0x10200400, 0x12200400, 0x10202400, 0x12202400,
192     0x10000404, 0x12000404, 0x10002404, 0x12002404,
193     0x10200404, 0x12200404, 0x10202404, 0x12202404},
194   {                             /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
195     0x00000000, 0x00000001, 0x00040000, 0x00040001,
196     0x01000000, 0x01000001, 0x01040000, 0x01040001,
197     0x00000002, 0x00000003, 0x00040002, 0x00040003,
198     0x01000002, 0x01000003, 0x01040002, 0x01040003,
199     0x00000200, 0x00000201, 0x00040200, 0x00040201,
200     0x01000200, 0x01000201, 0x01040200, 0x01040201,
201     0x00000202, 0x00000203, 0x00040202, 0x00040203,
202     0x01000202, 0x01000203, 0x01040202, 0x01040203,
203     0x08000000, 0x08000001, 0x08040000, 0x08040001,
204     0x09000000, 0x09000001, 0x09040000, 0x09040001,
205     0x08000002, 0x08000003, 0x08040002, 0x08040003,
206     0x09000002, 0x09000003, 0x09040002, 0x09040003,
207     0x08000200, 0x08000201, 0x08040200, 0x08040201,
208     0x09000200, 0x09000201, 0x09040200, 0x09040201,
209     0x08000202, 0x08000203, 0x08040202, 0x08040203,
210     0x09000202, 0x09000203, 0x09040202, 0x09040203},
211   {                             /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
212     0x00000000, 0x00100000, 0x00000100, 0x00100100,
213     0x00000008, 0x00100008, 0x00000108, 0x00100108,
214     0x00001000, 0x00101000, 0x00001100, 0x00101100,
215     0x00001008, 0x00101008, 0x00001108, 0x00101108,
216     0x04000000, 0x04100000, 0x04000100, 0x04100100,
217     0x04000008, 0x04100008, 0x04000108, 0x04100108,
218     0x04001000, 0x04101000, 0x04001100, 0x04101100,
219     0x04001008, 0x04101008, 0x04001108, 0x04101108,
220     0x00020000, 0x00120000, 0x00020100, 0x00120100,
221     0x00020008, 0x00120008, 0x00020108, 0x00120108,
222     0x00021000, 0x00121000, 0x00021100, 0x00121100,
223     0x00021008, 0x00121008, 0x00021108, 0x00121108,
224     0x04020000, 0x04120000, 0x04020100, 0x04120100,
225     0x04020008, 0x04120008, 0x04020108, 0x04120108,
226     0x04021000, 0x04121000, 0x04021100, 0x04121100,
227     0x04021008, 0x04121008, 0x04021108, 0x04121108},
228   {                             /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
229     0x00000000, 0x10000000, 0x00010000, 0x10010000,
230     0x00000004, 0x10000004, 0x00010004, 0x10010004,
231     0x20000000, 0x30000000, 0x20010000, 0x30010000,
232     0x20000004, 0x30000004, 0x20010004, 0x30010004,
233     0x00100000, 0x10100000, 0x00110000, 0x10110000,
234     0x00100004, 0x10100004, 0x00110004, 0x10110004,
235     0x20100000, 0x30100000, 0x20110000, 0x30110000,
236     0x20100004, 0x30100004, 0x20110004, 0x30110004,
237     0x00001000, 0x10001000, 0x00011000, 0x10011000,
238     0x00001004, 0x10001004, 0x00011004, 0x10011004,
239     0x20001000, 0x30001000, 0x20011000, 0x30011000,
240     0x20001004, 0x30001004, 0x20011004, 0x30011004,
241     0x00101000, 0x10101000, 0x00111000, 0x10111000,
242     0x00101004, 0x10101004, 0x00111004, 0x10111004,
243     0x20101000, 0x30101000, 0x20111000, 0x30111000,
244     0x20101004, 0x30101004, 0x20111004, 0x30111004},
245   {                             /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
246     0x00000000, 0x08000000, 0x00000008, 0x08000008,
247     0x00000400, 0x08000400, 0x00000408, 0x08000408,
248     0x00020000, 0x08020000, 0x00020008, 0x08020008,
249     0x00020400, 0x08020400, 0x00020408, 0x08020408,
250     0x00000001, 0x08000001, 0x00000009, 0x08000009,
251     0x00000401, 0x08000401, 0x00000409, 0x08000409,
252     0x00020001, 0x08020001, 0x00020009, 0x08020009,
253     0x00020401, 0x08020401, 0x00020409, 0x08020409,
254     0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
255     0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
256     0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
257     0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
258     0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
259     0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
260     0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
261     0x02020401, 0x0A020401, 0x02020409, 0x0A020409},
262   {                             /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
263     0x00000000, 0x00000100, 0x00080000, 0x00080100,
264     0x01000000, 0x01000100, 0x01080000, 0x01080100,
265     0x00000010, 0x00000110, 0x00080010, 0x00080110,
266     0x01000010, 0x01000110, 0x01080010, 0x01080110,
267     0x00200000, 0x00200100, 0x00280000, 0x00280100,
268     0x01200000, 0x01200100, 0x01280000, 0x01280100,
269     0x00200010, 0x00200110, 0x00280010, 0x00280110,
270     0x01200010, 0x01200110, 0x01280010, 0x01280110,
271     0x00000200, 0x00000300, 0x00080200, 0x00080300,
272     0x01000200, 0x01000300, 0x01080200, 0x01080300,
273     0x00000210, 0x00000310, 0x00080210, 0x00080310,
274     0x01000210, 0x01000310, 0x01080210, 0x01080310,
275     0x00200200, 0x00200300, 0x00280200, 0x00280300,
276     0x01200200, 0x01200300, 0x01280200, 0x01280300,
277     0x00200210, 0x00200310, 0x00280210, 0x00280310,
278     0x01200210, 0x01200310, 0x01280210, 0x01280310},
279   {                             /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
280     0x00000000, 0x04000000, 0x00040000, 0x04040000,
281     0x00000002, 0x04000002, 0x00040002, 0x04040002,
282     0x00002000, 0x04002000, 0x00042000, 0x04042000,
283     0x00002002, 0x04002002, 0x00042002, 0x04042002,
284     0x00000020, 0x04000020, 0x00040020, 0x04040020,
285     0x00000022, 0x04000022, 0x00040022, 0x04040022,
286     0x00002020, 0x04002020, 0x00042020, 0x04042020,
287     0x00002022, 0x04002022, 0x00042022, 0x04042022,
288     0x00000800, 0x04000800, 0x00040800, 0x04040800,
289     0x00000802, 0x04000802, 0x00040802, 0x04040802,
290     0x00002800, 0x04002800, 0x00042800, 0x04042800,
291     0x00002802, 0x04002802, 0x00042802, 0x04042802,
292     0x00000820, 0x04000820, 0x00040820, 0x04040820,
293     0x00000822, 0x04000822, 0x00040822, 0x04040822,
294     0x00002820, 0x04002820, 0x00042820, 0x04042820,
295     0x00002822, 0x04002822, 0x00042822, 0x04042822},
296 };
297
298 #define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
299                          l|=((unsigned long)(*((c)++)))<< 8, \
300                          l|=((unsigned long)(*((c)++)))<<16, \
301                          l|=((unsigned long)(*((c)++)))<<24)
302
303 #define l2c(l,c)        (*((c)++)=(unsigned char)(((l)    )&0xff), \
304                          *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
305                          *((c)++)=(unsigned char)(((l)>>16)&0xff), \
306                          *((c)++)=(unsigned char)(((l)>>24)&0xff))
307
308 /*
309  * IP and FP
310  * The problem is more of a geometric problem that random bit fiddling.
311  *  0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
312  *  8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
313  * 16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
314  * 24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
315  *
316  * 32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
317  * 40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
318  * 48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
319  * 56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
320  *
321  * The output has been subject to swaps of the form
322  * 0 1 -> 3 1 but the odd and even bits have been put into
323  * 2 3    2 0
324  * different words.  The main trick is to remember that
325  * t=((l>>size)^r)&(mask);
326  * r^=t;
327  * l^=(t<<size);
328  * can be used to swap and move bits between words.
329  *
330  * So l =  0  1  2  3  r = 16 17 18 19
331  *         4  5  6  7      20 21 22 23
332  *         8  9 10 11      24 25 26 27
333  *        12 13 14 15      28 29 30 31
334  * becomes (for size == 2 and mask == 0x3333)
335  * t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
336  *       6^20  7^21 -- --        4  5 20 21       6  7 22 23
337  *      10^24 11^25 -- --        8  9 24 25      10 11 24 25
338  *      14^28 15^29 -- --       12 13 28 29      14 15 28 29
339  *
340  * Thanks for hints from Richard Outerbridge - he told me IP&FP
341  * could be done in 15 xor, 10 shifts and 5 ands.
342  * When I finally started to think of the problem in 2D
343  * I first got ~42 operations without xors.  When I remembered
344  * how to use xors :-) I got it to its final state.
345  */
346
347 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
348         (b)^=(t),\
349         (a)^=((t)<<(n)))
350
351 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
352         (a)=(a)^(t)^(t>>(16-(n))))
353
354
355 /* The changes to this macro may help or hinder, depending on the
356  * compiler and the achitecture.  gcc2 always seems to do well :-).
357  * Inspired by Dana How <how@isl.stanford.edu>
358  * DO NOT use the alternative version on machines with 8 byte longs.
359  */
360 #ifdef ALT_ECB
361 #define D_ENCRYPT(L,R,S) \
362         u=((R^s[S  ])<<2);      \
363         t= R^s[S+1]; \
364         t=((t>>2)+(t<<30)); \
365         L^= \
366         *(const unsigned long *)(des_SP+0x0100+((t    )&0xfc))+ \
367         *(const unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
368         *(const unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
369         *(const unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
370         *(const unsigned long *)(des_SP+       ((u    )&0xfc))+ \
371         *(const unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
372         *(const unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
373         *(const unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
374 #else /* original version */
375 #define D_ENCRYPT(L,R,S)        \
376         u=(R^s[S  ]); \
377         t=R^s[S+1]; \
378         t=((t>>4)+(t<<28)); \
379         L^=     des_SPtrans[1][(t    )&0x3f]| \
380                 des_SPtrans[3][(t>> 8)&0x3f]| \
381                 des_SPtrans[5][(t>>16)&0x3f]| \
382                 des_SPtrans[7][(t>>24)&0x3f]| \
383                 des_SPtrans[0][(u    )&0x3f]| \
384                 des_SPtrans[2][(u>> 8)&0x3f]| \
385                 des_SPtrans[4][(u>>16)&0x3f]| \
386                 des_SPtrans[6][(u>>24)&0x3f];
387 #endif
388
389 #define ITERATIONS 16
390
391 static const char shifts2[16] =
392 {0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
393
394 static void des_set_key (char *, unsigned long *) internal_function;
395 static void des_encrypt (unsigned long *, unsigned long *, int)
396      internal_function;
397 int _des_crypt (char *, unsigned, struct desparams *);
398
399 static void
400 internal_function
401 des_set_key (char *key, unsigned long *schedule)
402 {
403   register unsigned long c, d, t, s;
404   register unsigned char *in;
405   register unsigned long *k;
406   register int i;
407
408   k = (unsigned long *) schedule;
409   in = (unsigned char *) key;
410
411   c2l (in, c);
412   c2l (in, d);
413
414   /* I now do it in 47 simple operations :-)
415    * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
416    * for the inspiration. :-) */
417   PERM_OP (d, c, t, 4, 0x0f0f0f0f);
418   HPERM_OP (c, t, -2, 0xcccc0000);
419   HPERM_OP (d, t, -2, 0xcccc0000);
420   PERM_OP (d, c, t, 1, 0x55555555);
421   PERM_OP (c, d, t, 8, 0x00ff00ff);
422   PERM_OP (d, c, t, 1, 0x55555555);
423   d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
424        ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
425   c &= 0x0fffffff;
426
427   for (i = 0; i < ITERATIONS; i++)
428     {
429       if (shifts2[i])
430         {
431           c = ((c >> 2) | (c << 26));
432           d = ((d >> 2) | (d << 26));
433         }
434       else
435         {
436           c = ((c >> 1) | (c << 27));
437           d = ((d >> 1) | (d << 27));
438         }
439       c &= 0x0fffffff;
440       d &= 0x0fffffff;
441       /* could be a few less shifts but I am to lazy at this
442        * point in time to investigate */
443       s = des_skb[0][(c) & 0x3f] |
444         des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
445         des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
446         des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
447       t = des_skb[4][(d) & 0x3f] |
448         des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
449         des_skb[6][(d >> 15) & 0x3f] |
450         des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
451
452       /* table contained 0213 4657 */
453       *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
454       s = ((s >> 16) | (t & 0xffff0000));
455
456       s = (s << 4) | (s >> 28);
457       *(k++) = s & 0xffffffff;
458     }
459 }
460
461
462 static void
463 internal_function
464 des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
465 {
466   register unsigned long l, r, t, u;
467 #ifdef ALT_ECB
468   register const unsigned char *des_SP = (const unsigned char *) des_SPtrans;
469 #endif
470   register int i;
471   register unsigned long *s;
472
473   l = buf[0];
474   r = buf[1];
475
476   /* do IP */
477   PERM_OP (r, l, t, 4, 0x0f0f0f0f);
478   PERM_OP (l, r, t, 16, 0x0000ffff);
479   PERM_OP (r, l, t, 2, 0x33333333);
480   PERM_OP (l, r, t, 8, 0x00ff00ff);
481   PERM_OP (r, l, t, 1, 0x55555555);
482   /* r and l are reversed - remember that :-) - fix
483    * it in the next step */
484
485   /* Things have been modified so that the initial rotate is
486    * done outside the loop.  This required the
487    * des_SPtrans values in sp.h to be rotated 1 bit to the right.
488    * One perl script later and things have a 5% speed up on a sparc2.
489    * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
490    * for pointing this out. */
491   t = (r << 1) | (r >> 31);
492   r = (l << 1) | (l >> 31);
493   l = t;
494
495   /* clear the top bits on machines with 8byte longs */
496   l &= 0xffffffff;
497   r &= 0xffffffff;
498
499   s = (unsigned long *) schedule;
500   /* I don't know if it is worth the effort of loop unrolling the
501    * inner loop */
502   if (encrypt)
503     {
504       for (i = 0; i < 32; i += 4)
505         {
506           D_ENCRYPT (l, r, i + 0);      /*  1 */
507           D_ENCRYPT (r, l, i + 2);      /*  2 */
508         }
509     }
510   else
511     {
512       for (i = 30; i > 0; i -= 4)
513         {
514           D_ENCRYPT (l, r, i - 0);      /* 16 */
515           D_ENCRYPT (r, l, i - 2);      /* 15 */
516         }
517     }
518   l = (l >> 1) | (l << 31);
519   r = (r >> 1) | (r << 31);
520   /* clear the top bits on machines with 8byte longs */
521   l &= 0xffffffff;
522   r &= 0xffffffff;
523
524   /* swap l and r
525    * we will not do the swap so just remember they are
526    * reversed for the rest of the subroutine
527    * luckily FP fixes this problem :-) */
528
529   PERM_OP (r, l, t, 1, 0x55555555);
530   PERM_OP (l, r, t, 8, 0x00ff00ff);
531   PERM_OP (r, l, t, 2, 0x33333333);
532   PERM_OP (l, r, t, 16, 0x0000ffff);
533   PERM_OP (r, l, t, 4, 0x0f0f0f0f);
534
535   buf[0] = l;
536   buf[1] = r;
537
538   l = r = t = u = 0;
539 }
540
541
542 int
543 _des_crypt (char *buf, unsigned len, struct desparams *desp)
544 {
545   unsigned long schedule[32];
546   register unsigned long tin0, tin1;
547   register unsigned long tout0, tout1, xor0, xor1;
548   register unsigned char *in, *out;
549   unsigned long tbuf[2];
550   unsigned char *iv, *oiv;
551   int cbc_mode;
552
553   cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
554
555   in = (unsigned char *) buf;
556   out = (unsigned char *) buf;
557   oiv = iv = (unsigned char *) desp->des_ivec;
558
559   des_set_key (desp->des_key, schedule);
560
561   tin0 = tin1 = 0;              /* For GCC */
562   if (desp->des_dir == ENCRYPT)
563     {
564       c2l (iv, tout0);
565       c2l (iv, tout1);
566       for (; len > 0; len -= 8)
567         {
568           c2l (in, tin0);
569           c2l (in, tin1);
570           if (cbc_mode)
571             {
572               tin0 ^= tout0;
573               tin1 ^= tout1;
574             }
575           tbuf[0] = tin0;
576           tbuf[1] = tin1;
577           des_encrypt (tbuf, schedule, 1);
578           tout0 = tbuf[0];
579           tout1 = tbuf[1];
580           l2c (tout0, out);
581           l2c (tout1, out);
582         }
583       l2c (tout0, oiv);
584       l2c (tout1, oiv);
585     }
586   else
587     {
588       c2l (iv, xor0);
589       c2l (iv, xor1);
590       for (; len > 0; len -= 8)
591         {
592           c2l (in, tin0);
593           c2l (in, tin1);
594           tbuf[0] = tin0;
595           tbuf[1] = tin1;
596           des_encrypt (tbuf, schedule, 0);
597           if (cbc_mode)
598             {
599               tout0 = tbuf[0] ^ xor0;
600               tout1 = tbuf[1] ^ xor1;
601               xor0 = tin0;
602               xor1 = tin1;
603             }
604           else
605             {
606               tout0 = tbuf[0];
607               tout1 = tbuf[1];
608             }
609           l2c (tout0, out);
610           l2c (tout1, out);
611         }
612       l2c (tin0, oiv);
613       l2c (tin1, oiv);
614     }
615   tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
616   tbuf[0] = tbuf[1] = 0;
617   __bzero (schedule, sizeof (schedule));
618
619   return (1);
620 }