nsswitch: use new internal API (callers)
[platform/upstream/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 /* see <https://www.gnu.org/licenses/> to obtain a copy.  */
7 #include <string.h>
8 #include <stdint.h>
9 #include "des.h"
10
11
12 static const uint32_t 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 uint32_t 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 #define D_ENCRYPT(L,R,S)        \
356         u=(R^s[S  ]); \
357         t=R^s[S+1]; \
358         t=((t>>4)+(t<<28)); \
359         L^=     des_SPtrans[1][(t    )&0x3f]| \
360                 des_SPtrans[3][(t>> 8)&0x3f]| \
361                 des_SPtrans[5][(t>>16)&0x3f]| \
362                 des_SPtrans[7][(t>>24)&0x3f]| \
363                 des_SPtrans[0][(u    )&0x3f]| \
364                 des_SPtrans[2][(u>> 8)&0x3f]| \
365                 des_SPtrans[4][(u>>16)&0x3f]| \
366                 des_SPtrans[6][(u>>24)&0x3f];
367
368 #define ITERATIONS 16
369
370 static const char shifts2[16] =
371 {0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
372
373 static void des_set_key (unsigned char *, unsigned long *);
374 static void des_encrypt (unsigned long *, unsigned long *, int);
375 int _des_crypt (char *, unsigned, struct desparams *);
376
377 static void
378 des_set_key (unsigned char *key, unsigned long *schedule)
379 {
380   register unsigned long c, d, t, s;
381   register unsigned char *in;
382   register unsigned long *k;
383   register int i;
384
385   k = (unsigned long *) schedule;
386   in = key;
387
388   c2l (in, c);
389   c2l (in, d);
390
391   /* I now do it in 47 simple operations :-)
392    * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
393    * for the inspiration. :-) */
394   PERM_OP (d, c, t, 4, 0x0f0f0f0f);
395   HPERM_OP (c, t, -2, 0xcccc0000);
396   HPERM_OP (d, t, -2, 0xcccc0000);
397   PERM_OP (d, c, t, 1, 0x55555555);
398   PERM_OP (c, d, t, 8, 0x00ff00ff);
399   PERM_OP (d, c, t, 1, 0x55555555);
400   d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
401        ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
402   c &= 0x0fffffff;
403
404   for (i = 0; i < ITERATIONS; i++)
405     {
406       if (shifts2[i])
407         {
408           c = ((c >> 2) | (c << 26));
409           d = ((d >> 2) | (d << 26));
410         }
411       else
412         {
413           c = ((c >> 1) | (c << 27));
414           d = ((d >> 1) | (d << 27));
415         }
416       c &= 0x0fffffff;
417       d &= 0x0fffffff;
418       /* could be a few less shifts but I am to lazy at this
419        * point in time to investigate */
420       s = des_skb[0][(c) & 0x3f] |
421         des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
422         des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
423         des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
424       t = des_skb[4][(d) & 0x3f] |
425         des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
426         des_skb[6][(d >> 15) & 0x3f] |
427         des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
428
429       /* table contained 0213 4657 */
430       *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
431       s = ((s >> 16) | (t & 0xffff0000));
432
433       s = (s << 4) | (s >> 28);
434       *(k++) = s & 0xffffffff;
435     }
436 }
437
438
439 static void
440 des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
441 {
442   register unsigned long l, r, t, u;
443   register int i;
444   register unsigned long *s;
445
446   l = buf[0];
447   r = buf[1];
448
449   /* do IP */
450   PERM_OP (r, l, t, 4, 0x0f0f0f0f);
451   PERM_OP (l, r, t, 16, 0x0000ffff);
452   PERM_OP (r, l, t, 2, 0x33333333);
453   PERM_OP (l, r, t, 8, 0x00ff00ff);
454   PERM_OP (r, l, t, 1, 0x55555555);
455   /* r and l are reversed - remember that :-) - fix
456    * it in the next step */
457
458   /* Things have been modified so that the initial rotate is
459    * done outside the loop.  This required the
460    * des_SPtrans values in sp.h to be rotated 1 bit to the right.
461    * One perl script later and things have a 5% speed up on a sparc2.
462    * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
463    * for pointing this out. */
464   t = (r << 1) | (r >> 31);
465   r = (l << 1) | (l >> 31);
466   l = t;
467
468   /* clear the top bits on machines with 8byte longs */
469   l &= 0xffffffff;
470   r &= 0xffffffff;
471
472   s = (unsigned long *) schedule;
473   /* I don't know if it is worth the effort of loop unrolling the
474    * inner loop */
475   if (encrypt)
476     {
477       for (i = 0; i < 32; i += 4)
478         {
479           D_ENCRYPT (l, r, i + 0);      /*  1 */
480           D_ENCRYPT (r, l, i + 2);      /*  2 */
481         }
482     }
483   else
484     {
485       for (i = 30; i > 0; i -= 4)
486         {
487           D_ENCRYPT (l, r, i - 0);      /* 16 */
488           D_ENCRYPT (r, l, i - 2);      /* 15 */
489         }
490     }
491   l = (l >> 1) | (l << 31);
492   r = (r >> 1) | (r << 31);
493   /* clear the top bits on machines with 8byte longs */
494   l &= 0xffffffff;
495   r &= 0xffffffff;
496
497   /* swap l and r
498    * we will not do the swap so just remember they are
499    * reversed for the rest of the subroutine
500    * luckily FP fixes this problem :-) */
501
502   PERM_OP (r, l, t, 1, 0x55555555);
503   PERM_OP (l, r, t, 8, 0x00ff00ff);
504   PERM_OP (r, l, t, 2, 0x33333333);
505   PERM_OP (l, r, t, 16, 0x0000ffff);
506   PERM_OP (r, l, t, 4, 0x0f0f0f0f);
507
508   buf[0] = l;
509   buf[1] = r;
510
511   l = r = t = u = 0;
512 }
513
514
515 int
516 _des_crypt (char *buf, unsigned len, struct desparams *desp)
517 {
518   unsigned long schedule[32];
519   register unsigned long tin0, tin1;
520   register unsigned long tout0, tout1, xor0, xor1;
521   register unsigned char *in, *out;
522   unsigned long tbuf[2];
523   unsigned char *iv, *oiv;
524   int cbc_mode;
525
526   cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
527
528   in = (unsigned char *) buf;
529   out = (unsigned char *) buf;
530   oiv = iv = (unsigned char *) desp->des_ivec;
531
532   des_set_key (desp->des_key, schedule);
533
534   tin0 = tin1 = 0;              /* For GCC */
535   if (desp->des_dir == ENCRYPT)
536     {
537       c2l (iv, tout0);
538       c2l (iv, tout1);
539       for (; len > 0; len -= 8)
540         {
541           c2l (in, tin0);
542           c2l (in, tin1);
543           if (cbc_mode)
544             {
545               tin0 ^= tout0;
546               tin1 ^= tout1;
547             }
548           tbuf[0] = tin0;
549           tbuf[1] = tin1;
550           des_encrypt (tbuf, schedule, 1);
551           tout0 = tbuf[0];
552           tout1 = tbuf[1];
553           l2c (tout0, out);
554           l2c (tout1, out);
555         }
556       l2c (tout0, oiv);
557       l2c (tout1, oiv);
558     }
559   else
560     {
561       c2l (iv, xor0);
562       c2l (iv, xor1);
563       for (; len > 0; len -= 8)
564         {
565           c2l (in, tin0);
566           c2l (in, tin1);
567           tbuf[0] = tin0;
568           tbuf[1] = tin1;
569           des_encrypt (tbuf, schedule, 0);
570           if (cbc_mode)
571             {
572               tout0 = tbuf[0] ^ xor0;
573               tout1 = tbuf[1] ^ xor1;
574               xor0 = tin0;
575               xor1 = tin1;
576             }
577           else
578             {
579               tout0 = tbuf[0];
580               tout1 = tbuf[1];
581             }
582           l2c (tout0, out);
583           l2c (tout1, out);
584         }
585       l2c (tin0, oiv);
586       l2c (tin1, oiv);
587     }
588   tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
589   tbuf[0] = tbuf[1] = 0;
590   memset (schedule, 0, sizeof (schedule));
591
592   return (1);
593 }