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