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