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