2007-09-13 H.J. Lu <hongjiu.lu@intel.com>
[glibc.git] / sunrpc / des_impl.c
blobdc94e221ab97c80ef034f37a24bb43183368a427
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"
13 static const uint32_t des_SPtrans[8][64] =
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},
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},
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},
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},
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},
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},
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},
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}};
159 static const uint32_t des_skb[8][64] =
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},
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)
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))
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
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
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.
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
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.
348 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
349 (b)^=(t),\
350 (a)^=((t)<<(n)))
352 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
353 (a)=(a)^(t)^(t>>(16-(n))))
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];
369 #define ITERATIONS 16
371 static const char shifts2[16] =
372 {0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
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 *);
379 static void
380 internal_function
381 des_set_key (unsigned char *key, unsigned long *schedule)
383 register unsigned long c, d, t, s;
384 register unsigned char *in;
385 register unsigned long *k;
386 register int i;
388 k = (unsigned long *) schedule;
389 in = key;
391 c2l (in, c);
392 c2l (in, d);
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;
407 for (i = 0; i < ITERATIONS; i++)
409 if (shifts2[i])
411 c = ((c >> 2) | (c << 26));
412 d = ((d >> 2) | (d << 26));
414 else
416 c = ((c >> 1) | (c << 27));
417 d = ((d >> 1) | (d << 27));
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)];
432 /* table contained 0213 4657 */
433 *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
434 s = ((s >> 16) | (t & 0xffff0000));
436 s = (s << 4) | (s >> 28);
437 *(k++) = s & 0xffffffff;
442 static void
443 internal_function
444 des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
446 register unsigned long l, r, t, u;
447 register int i;
448 register unsigned long *s;
450 l = buf[0];
451 r = buf[1];
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 */
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;
472 /* clear the top bits on machines with 8byte longs */
473 l &= 0xffffffff;
474 r &= 0xffffffff;
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)
481 for (i = 0; i < 32; i += 4)
483 D_ENCRYPT (l, r, i + 0); /* 1 */
484 D_ENCRYPT (r, l, i + 2); /* 2 */
487 else
489 for (i = 30; i > 0; i -= 4)
491 D_ENCRYPT (l, r, i - 0); /* 16 */
492 D_ENCRYPT (r, l, i - 2); /* 15 */
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;
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 :-) */
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);
512 buf[0] = l;
513 buf[1] = r;
515 l = r = t = u = 0;
520 _des_crypt (char *buf, unsigned len, struct desparams *desp)
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;
530 cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
532 in = (unsigned char *) buf;
533 out = (unsigned char *) buf;
534 oiv = iv = (unsigned char *) desp->des_ivec;
536 des_set_key (desp->des_key, schedule);
538 tin0 = tin1 = 0; /* For GCC */
539 if (desp->des_dir == ENCRYPT)
541 c2l (iv, tout0);
542 c2l (iv, tout1);
543 for (; len > 0; len -= 8)
545 c2l (in, tin0);
546 c2l (in, tin1);
547 if (cbc_mode)
549 tin0 ^= tout0;
550 tin1 ^= tout1;
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);
560 l2c (tout0, oiv);
561 l2c (tout1, oiv);
563 else
565 c2l (iv, xor0);
566 c2l (iv, xor1);
567 for (; len > 0; len -= 8)
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)
576 tout0 = tbuf[0] ^ xor0;
577 tout1 = tbuf[1] ^ xor1;
578 xor0 = tin0;
579 xor1 = tin1;
581 else
583 tout0 = tbuf[0];
584 tout1 = tbuf[1];
586 l2c (tout0, out);
587 l2c (tout1, out);
589 l2c (tin0, oiv);
590 l2c (tin1, oiv);
592 tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
593 tbuf[0] = tbuf[1] = 0;
594 __bzero (schedule, sizeof (schedule));
596 return (1);