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
12static 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
158static 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
370static const char shifts2[16] =
371{0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
372
373static void des_set_key (unsigned char *, unsigned long *);
374static void des_encrypt (unsigned long *, unsigned long *, int);
375int _des_crypt (char *, unsigned, struct desparams *);
376
377static void
378des_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
439static void
440des_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
515int
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}
594