Automatic merge of /spare/repo/netdev-2.6 branch tlan
[linux-2.6] / crypto / des.c
1 /* 
2  * Cryptographic API.
3  *
4  * DES & Triple DES EDE Cipher Algorithms.
5  *
6  * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
7  * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
8  * Derived from Cryptoapi and Nettle implementations, adapted for in-place
9  * scatterlist interface.  Changed LGPL to GPL per section 3 of the LGPL.
10  *
11  * Copyright (c) 1992 Dana L. How.
12  * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de> 
13  * Copyright (c) Gisle Sælensminde <gisle@ii.uib.no>
14  * Copyright (C) 2001 Niels Möller.
15  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  */
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/mm.h>
26 #include <linux/errno.h>
27 #include <asm/scatterlist.h>
28 #include <linux/crypto.h>
29
30 #define DES_KEY_SIZE            8
31 #define DES_EXPKEY_WORDS        32
32 #define DES_BLOCK_SIZE          8
33
34 #define DES3_EDE_KEY_SIZE       (3 * DES_KEY_SIZE)
35 #define DES3_EDE_EXPKEY_WORDS   (3 * DES_EXPKEY_WORDS)
36 #define DES3_EDE_BLOCK_SIZE     DES_BLOCK_SIZE
37
38 #define ROR(d,c,o)      ((d) = (d) >> (c) | (d) << (o))
39
40 struct des_ctx {
41         u8 iv[DES_BLOCK_SIZE];
42         u32 expkey[DES_EXPKEY_WORDS];
43 };
44
45 struct des3_ede_ctx {
46         u8 iv[DES_BLOCK_SIZE];
47         u32 expkey[DES3_EDE_EXPKEY_WORDS];
48 };
49
50 static const u32 des_keymap[] = {
51         0x02080008, 0x02082000, 0x00002008, 0x00000000,
52         0x02002000, 0x00080008, 0x02080000, 0x02082008,
53         0x00000008, 0x02000000, 0x00082000, 0x00002008,
54         0x00082008, 0x02002008, 0x02000008, 0x02080000,
55         0x00002000, 0x00082008, 0x00080008, 0x02002000,
56         0x02082008, 0x02000008, 0x00000000, 0x00082000,
57         0x02000000, 0x00080000, 0x02002008, 0x02080008,
58         0x00080000, 0x00002000, 0x02082000, 0x00000008,
59         0x00080000, 0x00002000, 0x02000008, 0x02082008,
60         0x00002008, 0x02000000, 0x00000000, 0x00082000,
61         0x02080008, 0x02002008, 0x02002000, 0x00080008,
62         0x02082000, 0x00000008, 0x00080008, 0x02002000,
63         0x02082008, 0x00080000, 0x02080000, 0x02000008,
64         0x00082000, 0x00002008, 0x02002008, 0x02080000,
65         0x00000008, 0x02082000, 0x00082008, 0x00000000,
66         0x02000000, 0x02080008, 0x00002000, 0x00082008,
67
68         0x08000004, 0x00020004, 0x00000000, 0x08020200,
69         0x00020004, 0x00000200, 0x08000204, 0x00020000,
70         0x00000204, 0x08020204, 0x00020200, 0x08000000,
71         0x08000200, 0x08000004, 0x08020000, 0x00020204,
72         0x00020000, 0x08000204, 0x08020004, 0x00000000,
73         0x00000200, 0x00000004, 0x08020200, 0x08020004,
74         0x08020204, 0x08020000, 0x08000000, 0x00000204,
75         0x00000004, 0x00020200, 0x00020204, 0x08000200,
76         0x00000204, 0x08000000, 0x08000200, 0x00020204,
77         0x08020200, 0x00020004, 0x00000000, 0x08000200,
78         0x08000000, 0x00000200, 0x08020004, 0x00020000,
79         0x00020004, 0x08020204, 0x00020200, 0x00000004,
80         0x08020204, 0x00020200, 0x00020000, 0x08000204,
81         0x08000004, 0x08020000, 0x00020204, 0x00000000,
82         0x00000200, 0x08000004, 0x08000204, 0x08020200,
83         0x08020000, 0x00000204, 0x00000004, 0x08020004,
84
85         0x80040100, 0x01000100, 0x80000000, 0x81040100,
86         0x00000000, 0x01040000, 0x81000100, 0x80040000,
87         0x01040100, 0x81000000, 0x01000000, 0x80000100,
88         0x81000000, 0x80040100, 0x00040000, 0x01000000,
89         0x81040000, 0x00040100, 0x00000100, 0x80000000,
90         0x00040100, 0x81000100, 0x01040000, 0x00000100,
91         0x80000100, 0x00000000, 0x80040000, 0x01040100,
92         0x01000100, 0x81040000, 0x81040100, 0x00040000,
93         0x81040000, 0x80000100, 0x00040000, 0x81000000,
94         0x00040100, 0x01000100, 0x80000000, 0x01040000,
95         0x81000100, 0x00000000, 0x00000100, 0x80040000,
96         0x00000000, 0x81040000, 0x01040100, 0x00000100,
97         0x01000000, 0x81040100, 0x80040100, 0x00040000,
98         0x81040100, 0x80000000, 0x01000100, 0x80040100,
99         0x80040000, 0x00040100, 0x01040000, 0x81000100,
100         0x80000100, 0x01000000, 0x81000000, 0x01040100,
101
102         0x04010801, 0x00000000, 0x00010800, 0x04010000,
103         0x04000001, 0x00000801, 0x04000800, 0x00010800,
104         0x00000800, 0x04010001, 0x00000001, 0x04000800,
105         0x00010001, 0x04010800, 0x04010000, 0x00000001,
106         0x00010000, 0x04000801, 0x04010001, 0x00000800,
107         0x00010801, 0x04000000, 0x00000000, 0x00010001,
108         0x04000801, 0x00010801, 0x04010800, 0x04000001,
109         0x04000000, 0x00010000, 0x00000801, 0x04010801,
110         0x00010001, 0x04010800, 0x04000800, 0x00010801,
111         0x04010801, 0x00010001, 0x04000001, 0x00000000,
112         0x04000000, 0x00000801, 0x00010000, 0x04010001,
113         0x00000800, 0x04000000, 0x00010801, 0x04000801,
114         0x04010800, 0x00000800, 0x00000000, 0x04000001,
115         0x00000001, 0x04010801, 0x00010800, 0x04010000,
116         0x04010001, 0x00010000, 0x00000801, 0x04000800,
117         0x04000801, 0x00000001, 0x04010000, 0x00010800,
118
119         0x00000400, 0x00000020, 0x00100020, 0x40100000,
120         0x40100420, 0x40000400, 0x00000420, 0x00000000,
121         0x00100000, 0x40100020, 0x40000020, 0x00100400,
122         0x40000000, 0x00100420, 0x00100400, 0x40000020,
123         0x40100020, 0x00000400, 0x40000400, 0x40100420,
124         0x00000000, 0x00100020, 0x40100000, 0x00000420,
125         0x40100400, 0x40000420, 0x00100420, 0x40000000,
126         0x40000420, 0x40100400, 0x00000020, 0x00100000,
127         0x40000420, 0x00100400, 0x40100400, 0x40000020,
128         0x00000400, 0x00000020, 0x00100000, 0x40100400,
129         0x40100020, 0x40000420, 0x00000420, 0x00000000,
130         0x00000020, 0x40100000, 0x40000000, 0x00100020,
131         0x00000000, 0x40100020, 0x00100020, 0x00000420,
132         0x40000020, 0x00000400, 0x40100420, 0x00100000,
133         0x00100420, 0x40000000, 0x40000400, 0x40100420,
134         0x40100000, 0x00100420, 0x00100400, 0x40000400,
135
136         0x00800000, 0x00001000, 0x00000040, 0x00801042,
137         0x00801002, 0x00800040, 0x00001042, 0x00801000,
138         0x00001000, 0x00000002, 0x00800002, 0x00001040,
139         0x00800042, 0x00801002, 0x00801040, 0x00000000,
140         0x00001040, 0x00800000, 0x00001002, 0x00000042,
141         0x00800040, 0x00001042, 0x00000000, 0x00800002,
142         0x00000002, 0x00800042, 0x00801042, 0x00001002,
143         0x00801000, 0x00000040, 0x00000042, 0x00801040,
144         0x00801040, 0x00800042, 0x00001002, 0x00801000,
145         0x00001000, 0x00000002, 0x00800002, 0x00800040,
146         0x00800000, 0x00001040, 0x00801042, 0x00000000,
147         0x00001042, 0x00800000, 0x00000040, 0x00001002,
148         0x00800042, 0x00000040, 0x00000000, 0x00801042,
149         0x00801002, 0x00801040, 0x00000042, 0x00001000,
150         0x00001040, 0x00801002, 0x00800040, 0x00000042,
151         0x00000002, 0x00001042, 0x00801000, 0x00800002,
152
153         0x10400000, 0x00404010, 0x00000010, 0x10400010,
154         0x10004000, 0x00400000, 0x10400010, 0x00004010,
155         0x00400010, 0x00004000, 0x00404000, 0x10000000,
156         0x10404010, 0x10000010, 0x10000000, 0x10404000,
157         0x00000000, 0x10004000, 0x00404010, 0x00000010,
158         0x10000010, 0x10404010, 0x00004000, 0x10400000,
159         0x10404000, 0x00400010, 0x10004010, 0x00404000,
160         0x00004010, 0x00000000, 0x00400000, 0x10004010,
161         0x00404010, 0x00000010, 0x10000000, 0x00004000,
162         0x10000010, 0x10004000, 0x00404000, 0x10400010,
163         0x00000000, 0x00404010, 0x00004010, 0x10404000,
164         0x10004000, 0x00400000, 0x10404010, 0x10000000,
165         0x10004010, 0x10400000, 0x00400000, 0x10404010,
166         0x00004000, 0x00400010, 0x10400010, 0x00004010,
167         0x00400010, 0x00000000, 0x10404000, 0x10000010,
168         0x10400000, 0x10004010, 0x00000010, 0x00404000,
169
170         0x00208080, 0x00008000, 0x20200000, 0x20208080,
171         0x00200000, 0x20008080, 0x20008000, 0x20200000,
172         0x20008080, 0x00208080, 0x00208000, 0x20000080,
173         0x20200080, 0x00200000, 0x00000000, 0x20008000,
174         0x00008000, 0x20000000, 0x00200080, 0x00008080,
175         0x20208080, 0x00208000, 0x20000080, 0x00200080,
176         0x20000000, 0x00000080, 0x00008080, 0x20208000,
177         0x00000080, 0x20200080, 0x20208000, 0x00000000,
178         0x00000000, 0x20208080, 0x00200080, 0x20008000,
179         0x00208080, 0x00008000, 0x20000080, 0x00200080,
180         0x20208000, 0x00000080, 0x00008080, 0x20200000,
181         0x20008080, 0x20000000, 0x20200000, 0x00208000,
182         0x20208080, 0x00008080, 0x00208000, 0x20200080,
183         0x00200000, 0x20000080, 0x20008000, 0x00000000,
184         0x00008000, 0x00200000, 0x20200080, 0x00208080,
185         0x20000000, 0x20208000, 0x00000080, 0x20008080,
186 };
187
188 static const u8 rotors[] = {
189         34, 13,  5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
190         14, 36, 30, 24, 49,  2, 15, 37, 42, 50,  0, 21,
191         38, 48,  6, 26, 39,  4, 52, 25, 12, 27, 31, 40,
192         1, 17, 28, 29, 23, 51, 35,  7,  3, 22,  9, 43,
193
194         41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
195         21, 43, 37,  0,  1,  9, 22, 44, 49,  2,  7, 28,
196         45, 55, 13, 33, 46, 11,  6, 32, 19, 34, 38, 47,
197         8, 24, 35, 36, 30,  3, 42, 14, 10, 29, 16, 50,
198
199         55, 34, 26, 38, 11, 39, 53,  5, 32, 45, 54, 41,
200         35,  2, 51, 14, 15, 23, 36,  3,  8, 16, 21, 42,
201         6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52,  4,
202         22,  7, 49, 50, 44, 17,  1, 28, 24, 43, 30,  9,
203
204         12, 48, 40, 52, 25, 53, 38, 19, 46,  6, 11, 55,
205         49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35,  1,
206         20, 26, 41,  4, 45, 39, 34, 31, 47,  5, 13, 18,
207         36, 21,  8,  9,  3,  0, 15, 42,  7,  2, 44, 23,
208
209         26,  5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
210         8, 30, 24, 42, 43, 51,  9,  0, 36, 44, 49, 15,
211         34, 40, 55, 18,  6, 53, 48, 45,  4, 19, 27, 32,
212         50, 35, 22, 23, 17, 14, 29,  1, 21, 16,  3, 37,
213
214         40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
215         22, 44,  7,  1,  2, 10, 23, 14, 50,  3,  8, 29,
216         48, 54, 12, 32, 20, 38,  5,  6, 18, 33, 41, 46,
217         9, 49, 36, 37,  0, 28, 43, 15, 35, 30, 17, 51,
218
219         54, 33, 25, 41, 38, 13, 27,  4,  6, 48, 53, 40,
220         36,  3, 21, 15, 16, 24, 37, 28,  9, 17, 22, 43,
221         5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
222         23,  8, 50, 51, 14, 42,  2, 29, 49, 44,  0, 10,
223
224         11, 47, 39, 55, 52, 27, 41, 18, 20,  5, 38, 54,
225         50, 17, 35, 29, 30,  7, 51, 42, 23,  0, 36,  2,
226         19, 25, 40, 31, 48, 13, 33, 34, 46,  4, 12, 45,
227         37, 22,  9, 10, 28,  1, 16, 43,  8,  3, 14, 24,
228
229         18, 54, 46,  5,  6, 34, 48, 25, 27, 12, 45,  4,
230         2, 24, 42, 36, 37, 14,  3, 49, 30,  7, 43,  9,
231         26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
232         44, 29, 16, 17, 35,  8, 23, 50, 15, 10, 21,  0,
233
234         32, 11, 31, 19, 20, 48,  5, 39, 41, 26,  6, 18,
235         16,  7,  1, 50, 51, 28, 17,  8, 44, 21,  2, 23,
236         40, 46,  4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
237         3, 43, 30,  0, 49, 22, 37,  9, 29, 24, 35, 14,
238
239         46, 25, 45, 33, 34,  5, 19, 53, 55, 40, 20, 32,
240         30, 21, 15,  9, 10, 42,  0, 22,  3, 35, 16, 37,
241         54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
242         17,  2, 44, 14,  8, 36, 51, 23, 43,  7, 49, 28,
243
244         31, 39,  6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
245         44, 35, 29, 23, 24,  1, 14, 36, 17, 49, 30, 51,
246         11, 45, 32, 27, 40,  5, 25, 26, 13, 53,  4, 41,
247         0, 16,  3, 28, 22, 50, 10, 37,  2, 21,  8, 42,
248
249         45, 53, 20,  4,  5, 33, 47, 52, 26, 11, 48, 31,
250         3, 49, 43, 37,  7, 15, 28, 50,  0,  8, 44, 10,
251         25,  6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
252         14, 30, 17, 42, 36,  9, 24, 51, 16, 35, 22,  1,
253
254         6, 38, 34, 18, 19, 47,  4, 13, 40, 25,  5, 45,
255         17,  8,  2, 51, 21, 29, 42,  9, 14, 22,  3, 24,
256         39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
257         28, 44,  0,  1, 50, 23,  7, 10, 30, 49, 36, 15,
258
259         20, 52, 48, 32, 33,  4, 18, 27, 54, 39, 19,  6,
260         0, 22, 16, 10, 35, 43,  1, 23, 28, 36, 17,  7,
261         53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
262         42,  3, 14, 15,  9, 37, 21, 24, 44,  8, 50, 29,
263
264         27,  6, 55, 39, 40, 11, 25, 34,  4, 46, 26, 13,
265         7, 29, 23, 17, 42, 50,  8, 30, 35, 43, 24, 14,
266         31, 41, 52, 19, 32, 54, 45, 18,  5, 20, 53, 33,
267         49, 10, 21, 22, 16, 44, 28,  0, 51, 15,  2, 36,
268 };
269
270 static const u8 parity[] = {
271         8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
272         0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
273         0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
274         8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
275         0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
276         8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
277         8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
278         4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
279 };
280
281
282 static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src)
283 {
284         u32 x, y, z;
285         
286         x  = src[7];
287         x <<= 8;
288         x |= src[6];
289         x <<= 8;
290         x |= src[5];
291         x <<= 8;
292         x |= src[4];
293         y  = src[3];
294         y <<= 8;
295         y |= src[2];
296         y <<= 8;
297         y |= src[1];
298         y <<= 8;
299         y |= src[0];
300         z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
301         x ^= z << 004;
302         y ^= z;
303         z  = ((y >> 020) ^ x) & 0x0000FFFFL;
304         y ^= z << 020;
305         x ^= z;
306         z  = ((x >> 002) ^ y) & 0x33333333L;
307         x ^= z << 002;
308         y ^= z;
309         z  = ((y >> 010) ^ x) & 0x00FF00FFL;
310         y ^= z << 010;
311         x ^= z;
312         x  = x >> 1 | x << 31;
313         z  = (x ^ y) & 0x55555555L;
314         y ^= z;
315         x ^= z;
316         y  = y >> 1 | y << 31;
317         z  = expkey[0];
318         z ^= y;
319         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
320         z >>= 8;
321         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
322         z >>= 8;
323         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
324         z >>= 8;
325         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
326         z  = expkey[1];
327         z ^= y;
328         z  = z << 4 | z >> 28;
329         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
330         z >>= 8;
331         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
332         z >>= 8;
333         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
334         z >>= 8;
335         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
336         z  = expkey[2];
337         z ^= x;
338         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
339         z >>= 8;
340         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
341         z >>= 8;
342         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
343         z >>= 8;
344         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
345         z  = expkey[3];
346         z ^= x;
347         z  = z << 4 | z >> 28;
348         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
349         z >>= 8;
350         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
351         z >>= 8;
352         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
353         z >>= 8;
354         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
355         z  = expkey[4];
356         z ^= y;
357         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
358         z >>= 8;
359         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
360         z >>= 8;
361         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
362         z >>= 8;
363         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
364         z  = expkey[5];
365         z ^= y;
366         z  = z << 4 | z >> 28;
367         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
368         z >>= 8;
369         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
370         z >>= 8;
371         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
372         z >>= 8;
373         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
374         z  = expkey[6];
375         z ^= x;
376         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
377         z >>= 8;
378         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
379         z >>= 8;
380         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
381         z >>= 8;
382         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
383         z  = expkey[7];
384         z ^= x;
385         z  = z << 4 | z >> 28;
386         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
387         z >>= 8;
388         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
389         z >>= 8;
390         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
391         z >>= 8;
392         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
393         z  = expkey[8];
394         z ^= y;
395         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
396         z >>= 8;
397         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
398         z >>= 8;
399         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
400         z >>= 8;
401         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
402         z  = expkey[9];
403         z ^= y;
404         z  = z << 4 | z >> 28;
405         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
406         z >>= 8;
407         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
408         z >>= 8;
409         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
410         z >>= 8;
411         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
412         z  = expkey[10];
413         z ^= x;
414         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
415         z >>= 8;
416         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
417         z >>= 8;
418         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
419         z >>= 8;
420         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
421         z  = expkey[11];
422         z ^= x;
423         z  = z << 4 | z >> 28;
424         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
425         z >>= 8;
426         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
427         z >>= 8;
428         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
429         z >>= 8;
430         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
431         z  = expkey[12];
432         z ^= y;
433         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
434         z >>= 8;
435         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
436         z >>= 8;
437         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
438         z >>= 8;
439         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
440         z  = expkey[13];
441         z ^= y;
442         z  = z << 4 | z >> 28;
443         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
444         z >>= 8;
445         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
446         z >>= 8;
447         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
448         z >>= 8;
449         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
450         z  = expkey[14];
451         z ^= x;
452         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
453         z >>= 8;
454         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
455         z >>= 8;
456         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
457         z >>= 8;
458         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
459         z  = expkey[15];
460         z ^= x;
461         z  = z << 4 | z >> 28;
462         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
463         z >>= 8;
464         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
465         z >>= 8;
466         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
467         z >>= 8;
468         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
469         z  = expkey[16];
470         z ^= y;
471         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
472         z >>= 8;
473         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
474         z >>= 8;
475         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
476         z >>= 8;
477         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
478         z  = expkey[17];
479         z ^= y;
480         z  = z << 4 | z >> 28;
481         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
482         z >>= 8;
483         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
484         z >>= 8;
485         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
486         z >>= 8;
487         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
488         z  = expkey[18];
489         z ^= x;
490         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
491         z >>= 8;
492         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
493         z >>= 8;
494         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
495         z >>= 8;
496         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
497         z  = expkey[19];
498         z ^= x;
499         z  = z << 4 | z >> 28;
500         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
501         z >>= 8;
502         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
503         z >>= 8;
504         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
505         z >>= 8;
506         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
507         z  = expkey[20];
508         z ^= y;
509         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
510         z >>= 8;
511         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
512         z >>= 8;
513         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
514         z >>= 8;
515         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
516         z  = expkey[21];
517         z ^= y;
518         z  = z << 4 | z >> 28;
519         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
520         z >>= 8;
521         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
522         z >>= 8;
523         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
524         z >>= 8;
525         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
526         z  = expkey[22];
527         z ^= x;
528         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
529         z >>= 8;
530         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
531         z >>= 8;
532         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
533         z >>= 8;
534         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
535         z  = expkey[23];
536         z ^= x;
537         z  = z << 4 | z >> 28;
538         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
539         z >>= 8;
540         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
541         z >>= 8;
542         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
543         z >>= 8;
544         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
545         z  = expkey[24];
546         z ^= y;
547         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
548         z >>= 8;
549         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
550         z >>= 8;
551         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
552         z >>= 8;
553         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
554         z  = expkey[25];
555         z ^= y;
556         z  = z << 4 | z >> 28;
557         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
558         z >>= 8;
559         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
560         z >>= 8;
561         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
562         z >>= 8;
563         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
564         z  = expkey[26];
565         z ^= x;
566         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
567         z >>= 8;
568         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
569         z >>= 8;
570         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
571         z >>= 8;
572         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
573         z  = expkey[27];
574         z ^= x;
575         z  = z << 4 | z >> 28;
576         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
577         z >>= 8;
578         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
579         z >>= 8;
580         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
581         z >>= 8;
582         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
583         z  = expkey[28];
584         z ^= y;
585         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
586         z >>= 8;
587         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
588         z >>= 8;
589         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
590         z >>= 8;
591         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
592         z  = expkey[29];
593         z ^= y;
594         z  = z << 4 | z >> 28;
595         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
596         z >>= 8;
597         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
598         z >>= 8;
599         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
600         z >>= 8;
601         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
602         z  = expkey[30];
603         z ^= x;
604         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
605         z >>= 8;
606         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
607         z >>= 8;
608         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
609         z >>= 8;
610         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
611         z  = expkey[31];
612         z ^= x;
613         z  = z << 4 | z >> 28;
614         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
615         z >>= 8;
616         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
617         z >>= 8;
618         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
619         z >>= 8;
620         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
621         x  = x << 1 | x >> 31;
622         z  = (x ^ y) & 0x55555555L;
623         y ^= z;
624         x ^= z;
625         y  = y << 1 | y >> 31;
626         z  = ((x >> 010) ^ y) & 0x00FF00FFL;
627         x ^= z << 010;
628         y ^= z;
629         z  = ((y >> 002) ^ x) & 0x33333333L;
630         y ^= z << 002;
631         x ^= z;
632         z  = ((x >> 020) ^ y) & 0x0000FFFFL;
633         x ^= z << 020;
634         y ^= z;
635         z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
636         y ^= z << 004;
637         x ^= z;
638         dst[0] = x;
639         x >>= 8;
640         dst[1] = x;
641         x >>= 8;
642         dst[2] = x;
643         x >>= 8;
644         dst[3] = x;
645         dst[4] = y;
646         y >>= 8;
647         dst[5] = y;
648         y >>= 8;
649         dst[6] = y;
650         y >>= 8;
651         dst[7] = y;
652 }
653
654 static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src)
655 {
656         u32 x, y, z;
657         
658         x  = src[7];
659         x <<= 8;
660         x |= src[6];
661         x <<= 8;
662         x |= src[5];
663         x <<= 8;
664         x |= src[4];
665         y  = src[3];
666         y <<= 8;
667         y |= src[2];
668         y <<= 8;
669         y |= src[1];
670         y <<= 8;
671         y |= src[0];
672         z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
673         x ^= z << 004;
674         y ^= z;
675         z  = ((y >> 020) ^ x) & 0x0000FFFFL;
676         y ^= z << 020;
677         x ^= z;
678         z  = ((x >> 002) ^ y) & 0x33333333L;
679         x ^= z << 002;
680         y ^= z;
681         z  = ((y >> 010) ^ x) & 0x00FF00FFL;
682         y ^= z << 010;
683         x ^= z;
684         x  = x >> 1 | x << 31;
685         z  = (x ^ y) & 0x55555555L;
686         y ^= z;
687         x ^= z;
688         y  = y >> 1 | y << 31;
689         z  = expkey[31];
690         z ^= y;
691         z  = z << 4 | z >> 28;
692         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
693         z >>= 8;
694         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
695         z >>= 8;
696         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
697         z >>= 8;
698         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
699         z  = expkey[30];
700         z ^= y;
701         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
702         z >>= 8;
703         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
704         z >>= 8;
705         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
706         z >>= 8;
707         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
708         z  = expkey[29];
709         z ^= x;
710         z  = z << 4 | z >> 28;
711         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
712         z >>= 8;
713         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
714         z >>= 8;
715         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
716         z >>= 8;
717         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
718         z  = expkey[28];
719         z ^= x;
720         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
721         z >>= 8;
722         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
723         z >>= 8;
724         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
725         z >>= 8;
726         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
727         z  = expkey[27];
728         z ^= y;
729         z  = z << 4 | z >> 28;
730         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
731         z >>= 8;
732         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
733         z >>= 8;
734         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
735         z >>= 8;
736         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
737         z  = expkey[26];
738         z ^= y;
739         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
740         z >>= 8;
741         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
742         z >>= 8;
743         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
744         z >>= 8;
745         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
746         z  = expkey[25];
747         z ^= x;
748         z  = z << 4 | z >> 28;
749         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
750         z >>= 8;
751         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
752         z >>= 8;
753         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
754         z >>= 8;
755         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
756         z  = expkey[24];
757         z ^= x;
758         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
759         z >>= 8;
760         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
761         z >>= 8;
762         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
763         z >>= 8;
764         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
765         z  = expkey[23];
766         z ^= y;
767         z  = z << 4 | z >> 28;
768         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
769         z >>= 8;
770         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
771         z >>= 8;
772         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
773         z >>= 8;
774         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
775         z  = expkey[22];
776         z ^= y;
777         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
778         z >>= 8;
779         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
780         z >>= 8;
781         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
782         z >>= 8;
783         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
784         z  = expkey[21];
785         z ^= x;
786         z  = z << 4 | z >> 28;
787         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
788         z >>= 8;
789         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
790         z >>= 8;
791         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
792         z >>= 8;
793         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
794         z  = expkey[20];
795         z ^= x;
796         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
797         z >>= 8;
798         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
799         z >>= 8;
800         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
801         z >>= 8;
802         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
803         z  = expkey[19];
804         z ^= y;
805         z  = z << 4 | z >> 28;
806         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
807         z >>= 8;
808         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
809         z >>= 8;
810         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
811         z >>= 8;
812         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
813         z  = expkey[18];
814         z ^= y;
815         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
816         z >>= 8;
817         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
818         z >>= 8;
819         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
820         z >>= 8;
821         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
822         z  = expkey[17];
823         z ^= x;
824         z  = z << 4 | z >> 28;
825         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
826         z >>= 8;
827         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
828         z >>= 8;
829         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
830         z >>= 8;
831         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
832         z  = expkey[16];
833         z ^= x;
834         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
835         z >>= 8;
836         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
837         z >>= 8;
838         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
839         z >>= 8;
840         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
841         z  = expkey[15];
842         z ^= y;
843         z  = z << 4 | z >> 28;
844         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
845         z >>= 8;
846         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
847         z >>= 8;
848         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
849         z >>= 8;
850         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
851         z  = expkey[14];
852         z ^= y;
853         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
854         z >>= 8;
855         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
856         z >>= 8;
857         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
858         z >>= 8;
859         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
860         z  = expkey[13];
861         z ^= x;
862         z  = z << 4 | z >> 28;
863         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
864         z >>= 8;
865         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
866         z >>= 8;
867         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
868         z >>= 8;
869         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
870         z  = expkey[12];
871         z ^= x;
872         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
873         z >>= 8;
874         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
875         z >>= 8;
876         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
877         z >>= 8;
878         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
879         z  = expkey[11];
880         z ^= y;
881         z  = z << 4 | z >> 28;
882         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
883         z >>= 8;
884         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
885         z >>= 8;
886         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
887         z >>= 8;
888         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
889         z  = expkey[10];
890         z ^= y;
891         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
892         z >>= 8;
893         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
894         z >>= 8;
895         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
896         z >>= 8;
897         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
898         z  = expkey[9];
899         z ^= x;
900         z  = z << 4 | z >> 28;
901         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
902         z >>= 8;
903         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
904         z >>= 8;
905         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
906         z >>= 8;
907         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
908         z  = expkey[8];
909         z ^= x;
910         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
911         z >>= 8;
912         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
913         z >>= 8;
914         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
915         z >>= 8;
916         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
917         z  = expkey[7];
918         z ^= y;
919         z  = z << 4 | z >> 28;
920         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
921         z >>= 8;
922         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
923         z >>= 8;
924         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
925         z >>= 8;
926         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
927         z  = expkey[6];
928         z ^= y;
929         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
930         z >>= 8;
931         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
932         z >>= 8;
933         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
934         z >>= 8;
935         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
936         z  = expkey[5];
937         z ^= x;
938         z  = z << 4 | z >> 28;
939         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
940         z >>= 8;
941         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
942         z >>= 8;
943         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
944         z >>= 8;
945         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
946         z  = expkey[4];
947         z ^= x;
948         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
949         z >>= 8;
950         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
951         z >>= 8;
952         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
953         z >>= 8;
954         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
955         z  = expkey[3];
956         z ^= y;
957         z  = z << 4 | z >> 28;
958         x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
959         z >>= 8;
960         x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
961         z >>= 8;
962         x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
963         z >>= 8;
964         x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
965         z  = expkey[2];
966         z ^= y;
967         x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
968         z >>= 8;
969         x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
970         z >>= 8;
971         x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
972         z >>= 8;
973         x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
974         z  = expkey[1];
975         z ^= x;
976         z  = z << 4 | z >> 28;
977         y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
978         z >>= 8;
979         y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
980         z >>= 8;
981         y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
982         z >>= 8;
983         y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
984         z  = expkey[0];
985         z ^= x;
986         y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
987         z >>= 8;
988         y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
989         z >>= 8;
990         y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
991         z >>= 8;
992         y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
993         x  = x << 1 | x >> 31;
994         z  = (x ^ y) & 0x55555555L;
995         y ^= z;
996         x ^= z;
997         y  = y << 1 | y >> 31;
998         z  = ((x >> 010) ^ y) & 0x00FF00FFL;
999         x ^= z << 010;
1000         y ^= z;
1001         z  = ((y >> 002) ^ x) & 0x33333333L;
1002         y ^= z << 002;
1003         x ^= z;
1004         z  = ((x >> 020) ^ y) & 0x0000FFFFL;
1005         x ^= z << 020;
1006         y ^= z;
1007         z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
1008         y ^= z << 004;
1009         x ^= z;
1010         dst[0] = x;
1011         x >>= 8;
1012         dst[1] = x;
1013         x >>= 8;
1014         dst[2] = x;
1015         x >>= 8;
1016         dst[3] = x;
1017         dst[4] = y;
1018         y >>= 8;
1019         dst[5] = y;
1020         y >>= 8;
1021         dst[6] = y;
1022         y >>= 8;
1023         dst[7] = y;
1024 }
1025
1026 /*
1027  * RFC2451: Weak key checks SHOULD be performed.
1028  */
1029 static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags)
1030 {
1031         const u8 *k;
1032         u8 *b0, *b1;
1033         u32 n, w;
1034         u8 bits0[56], bits1[56];
1035
1036         n  = parity[key[0]]; n <<= 4;
1037         n |= parity[key[1]]; n <<= 4;
1038         n |= parity[key[2]]; n <<= 4;
1039         n |= parity[key[3]]; n <<= 4;
1040         n |= parity[key[4]]; n <<= 4;
1041         n |= parity[key[5]]; n <<= 4;
1042         n |= parity[key[6]]; n <<= 4;
1043         n |= parity[key[7]];
1044         w = 0x88888888L;
1045         
1046         if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
1047             && !((n - (w >> 3)) & w)) {  /* 1 in 10^10 keys passes this test */
1048                 if (n < 0x41415151) {
1049                         if (n < 0x31312121) {
1050                                 if (n < 0x14141515) {
1051                                         /* 01 01 01 01 01 01 01 01 */
1052                                         if (n == 0x11111111) goto weak;
1053                                         /* 01 1F 01 1F 01 0E 01 0E */
1054                                         if (n == 0x13131212) goto weak;
1055                                 } else {
1056                                         /* 01 E0 01 E0 01 F1 01 F1 */
1057                                         if (n == 0x14141515) goto weak;
1058                                         /* 01 FE 01 FE 01 FE 01 FE */
1059                                         if (n == 0x16161616) goto weak;
1060                                 }
1061                         } else {
1062                                 if (n < 0x34342525) {
1063                                         /* 1F 01 1F 01 0E 01 0E 01 */
1064                                         if (n == 0x31312121) goto weak;
1065                                         /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
1066                                         if (n == 0x33332222) goto weak;
1067                                 } else {
1068                                         /* 1F E0 1F E0 0E F1 0E F1 */
1069                                         if (n == 0x34342525) goto weak;
1070                                         /* 1F FE 1F FE 0E FE 0E FE */
1071                                         if (n == 0x36362626) goto weak;
1072                                 }
1073                         }
1074                 } else {
1075                         if (n < 0x61616161) {
1076                                 if (n < 0x44445555) {
1077                                         /* E0 01 E0 01 F1 01 F1 01 */
1078                                         if (n == 0x41415151) goto weak;
1079                                         /* E0 1F E0 1F F1 0E F1 0E */
1080                                         if (n == 0x43435252) goto weak;
1081                                 } else {
1082                                         /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
1083                                         if (n == 0x44445555) goto weak;
1084                                         /* E0 FE E0 FE F1 FE F1 FE */
1085                                         if (n == 0x46465656) goto weak;
1086                                 }
1087                         } else {
1088                                 if (n < 0x64646565) {
1089                                         /* FE 01 FE 01 FE 01 FE 01 */
1090                                         if (n == 0x61616161) goto weak;
1091                                         /* FE 1F FE 1F FE 0E FE 0E */
1092                                         if (n == 0x63636262) goto weak;
1093                                 } else {
1094                                         /* FE E0 FE E0 FE F1 FE F1 */
1095                                         if (n == 0x64646565) goto weak;
1096                                         /* FE FE FE FE FE FE FE FE */
1097                                         if (n == 0x66666666) goto weak;
1098                                 }
1099                         }
1100                 }
1101         
1102                 goto not_weak;
1103 weak:
1104                 *flags |= CRYPTO_TFM_RES_WEAK_KEY;
1105                 return -EINVAL;
1106         }
1107
1108 not_weak:
1109
1110         /* explode the bits */
1111         n = 56;
1112         b0 = bits0;
1113         b1 = bits1;
1114         
1115         do {
1116                 w = (256 | *key++) << 2;
1117                 do {
1118                         --n;
1119                         b1[n] = 8 & w;
1120                         w >>= 1;
1121                         b0[n] = 4 & w;
1122                 } while ( w >= 16 );
1123         } while ( n );
1124         
1125         /* put the bits in the correct places */
1126         n = 16;
1127         k = rotors;
1128         
1129         do {
1130                 w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
1131                 w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
1132                 w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
1133                 w <<= 8;
1134                 w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
1135                 w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
1136                 w  |=  b1[k[10   ]] | b0[k[11   ]];
1137                 w <<= 8;
1138                 w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
1139                 w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
1140                 w  |=  b1[k[16   ]] | b0[k[17   ]];
1141                 w <<= 8;
1142                 w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
1143                 w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
1144                 w  |=  b1[k[22   ]] | b0[k[23   ]];
1145                 expkey[0] = w;
1146                 
1147                 w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
1148                 w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
1149                 w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
1150                 w <<= 8;
1151                 w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
1152                 w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
1153                 w  |=  b1[k[10+24]] | b0[k[11+24]];
1154                 w <<= 8;
1155                 w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
1156                 w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
1157                 w  |=  b1[k[16+24]] | b0[k[17+24]];
1158                 w <<= 8;
1159                 w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
1160                 w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
1161                 w  |=  b1[k[22+24]] | b0[k[23+24]];
1162                 
1163                 ROR(w, 4, 28);      /* could be eliminated */
1164                 expkey[1] = w;
1165
1166                 k += 48;
1167                 expkey += 2;
1168         } while (--n);
1169
1170         return 0;
1171 }
1172
1173 static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
1174 {
1175         return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags);
1176 }
1177
1178 static void des_encrypt(void *ctx, u8 *dst, const u8 *src)
1179 {
1180         des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src);
1181 }
1182
1183 static void des_decrypt(void *ctx, u8 *dst, const u8 *src)
1184 {
1185         des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src);
1186 }
1187
1188 /* 
1189  * RFC2451:
1190  *
1191  *   For DES-EDE3, there is no known need to reject weak or
1192  *   complementation keys.  Any weakness is obviated by the use of
1193  *   multiple keys.
1194  *
1195  *   However, if the first two or last two independent 64-bit keys are
1196  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
1197  *   same as DES.  Implementers MUST reject keys that exhibit this
1198  *   property.
1199  *
1200  */
1201 static int des3_ede_setkey(void *ctx, const u8 *key,
1202                            unsigned int keylen, u32 *flags)
1203 {
1204         unsigned int i, off;
1205         struct des3_ede_ctx *dctx = ctx;
1206
1207         if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 
1208             memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
1209                                                 DES_KEY_SIZE))) {
1210
1211                 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
1212                 return -EINVAL;
1213         }
1214         
1215         for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS,
1216                                                         key += DES_KEY_SIZE) {
1217                 int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags);
1218                 if (ret < 0)
1219                         return ret;
1220         }       
1221         return 0;
1222 }
1223
1224 static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src)
1225 {
1226         struct des3_ede_ctx *dctx = ctx;
1227         
1228         des_small_fips_encrypt(dctx->expkey, dst, src);
1229         des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
1230         des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst);
1231 }
1232
1233 static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src)
1234 {
1235         struct des3_ede_ctx *dctx = ctx;
1236
1237         des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src);
1238         des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
1239         des_small_fips_decrypt(dctx->expkey, dst, dst);
1240 }
1241
1242 static struct crypto_alg des_alg = {
1243         .cra_name               =       "des",
1244         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
1245         .cra_blocksize          =       DES_BLOCK_SIZE,
1246         .cra_ctxsize            =       sizeof(struct des_ctx),
1247         .cra_module             =       THIS_MODULE,
1248         .cra_list               =       LIST_HEAD_INIT(des_alg.cra_list),
1249         .cra_u                  =       { .cipher = {
1250         .cia_min_keysize        =       DES_KEY_SIZE,
1251         .cia_max_keysize        =       DES_KEY_SIZE,
1252         .cia_setkey             =       des_setkey,
1253         .cia_encrypt            =       des_encrypt,
1254         .cia_decrypt            =       des_decrypt } }
1255 };
1256
1257 static struct crypto_alg des3_ede_alg = {
1258         .cra_name               =       "des3_ede",
1259         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
1260         .cra_blocksize          =       DES3_EDE_BLOCK_SIZE,
1261         .cra_ctxsize            =       sizeof(struct des3_ede_ctx),
1262         .cra_module             =       THIS_MODULE,
1263         .cra_list               =       LIST_HEAD_INIT(des3_ede_alg.cra_list),
1264         .cra_u                  =       { .cipher = {
1265         .cia_min_keysize        =       DES3_EDE_KEY_SIZE,
1266         .cia_max_keysize        =       DES3_EDE_KEY_SIZE,
1267         .cia_setkey             =       des3_ede_setkey,
1268         .cia_encrypt            =       des3_ede_encrypt,
1269         .cia_decrypt            =       des3_ede_decrypt } }
1270 };
1271
1272 MODULE_ALIAS("des3_ede");
1273
1274 static int __init init(void)
1275 {
1276         int ret = 0;
1277         
1278         ret = crypto_register_alg(&des_alg);
1279         if (ret < 0)
1280                 goto out;
1281
1282         ret = crypto_register_alg(&des3_ede_alg);
1283         if (ret < 0)
1284                 crypto_unregister_alg(&des_alg);
1285 out:    
1286         return ret;
1287 }
1288
1289 static void __exit fini(void)
1290 {
1291         crypto_unregister_alg(&des3_ede_alg);
1292         crypto_unregister_alg(&des_alg);
1293 }
1294
1295 module_init(init);
1296 module_exit(fini);
1297
1298 MODULE_LICENSE("GPL");
1299 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");