[PATCH] Sparsemem build fix
[linux-2.6] / crypto / des.c
1 /*
2  * Cryptographic API.
3  *
4  * DES & Triple DES EDE Cipher Algorithms.
5  *
6  * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  */
14
15 #include <asm/byteorder.h>
16 #include <linux/bitops.h>
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/errno.h>
20 #include <linux/crypto.h>
21 #include <linux/types.h>
22
23 #define DES_KEY_SIZE            8
24 #define DES_EXPKEY_WORDS        32
25 #define DES_BLOCK_SIZE          8
26
27 #define DES3_EDE_KEY_SIZE       (3 * DES_KEY_SIZE)
28 #define DES3_EDE_EXPKEY_WORDS   (3 * DES_EXPKEY_WORDS)
29 #define DES3_EDE_BLOCK_SIZE     DES_BLOCK_SIZE
30
31 #define ROL(x, r) ((x) = rol32((x), (r)))
32 #define ROR(x, r) ((x) = ror32((x), (r)))
33
34 struct des_ctx {
35         u32 expkey[DES_EXPKEY_WORDS];
36 };
37
38 struct des3_ede_ctx {
39         u32 expkey[DES3_EDE_EXPKEY_WORDS];
40 };
41
42 /* Lookup tables for key expansion */
43
44 static const u8 pc1[256] = {
45         0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14,
46         0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54,
47         0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16,
48         0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56,
49         0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c,
50         0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c,
51         0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e,
52         0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e,
53         0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34,
54         0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74,
55         0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36,
56         0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76,
57         0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c,
58         0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c,
59         0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e,
60         0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e,
61         0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94,
62         0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4,
63         0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96,
64         0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6,
65         0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c,
66         0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc,
67         0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e,
68         0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde,
69         0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4,
70         0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4,
71         0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6,
72         0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6,
73         0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc,
74         0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc,
75         0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe,
76         0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe
77 };
78
79 static const u8 rs[256] = {
80         0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82,
81         0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86,
82         0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a,
83         0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e,
84         0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92,
85         0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96,
86         0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a,
87         0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e,
88         0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2,
89         0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6,
90         0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa,
91         0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae,
92         0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2,
93         0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6,
94         0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba,
95         0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe,
96         0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2,
97         0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6,
98         0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca,
99         0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce,
100         0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2,
101         0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6,
102         0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda,
103         0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde,
104         0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2,
105         0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6,
106         0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea,
107         0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee,
108         0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2,
109         0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6,
110         0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa,
111         0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe
112 };
113
114 static const u32 pc2[1024] = {
115         0x00000000, 0x00000000, 0x00000000, 0x00000000,
116         0x00040000, 0x00000000, 0x04000000, 0x00100000,
117         0x00400000, 0x00000008, 0x00000800, 0x40000000,
118         0x00440000, 0x00000008, 0x04000800, 0x40100000,
119         0x00000400, 0x00000020, 0x08000000, 0x00000100,
120         0x00040400, 0x00000020, 0x0c000000, 0x00100100,
121         0x00400400, 0x00000028, 0x08000800, 0x40000100,
122         0x00440400, 0x00000028, 0x0c000800, 0x40100100,
123         0x80000000, 0x00000010, 0x00000000, 0x00800000,
124         0x80040000, 0x00000010, 0x04000000, 0x00900000,
125         0x80400000, 0x00000018, 0x00000800, 0x40800000,
126         0x80440000, 0x00000018, 0x04000800, 0x40900000,
127         0x80000400, 0x00000030, 0x08000000, 0x00800100,
128         0x80040400, 0x00000030, 0x0c000000, 0x00900100,
129         0x80400400, 0x00000038, 0x08000800, 0x40800100,
130         0x80440400, 0x00000038, 0x0c000800, 0x40900100,
131         0x10000000, 0x00000000, 0x00200000, 0x00001000,
132         0x10040000, 0x00000000, 0x04200000, 0x00101000,
133         0x10400000, 0x00000008, 0x00200800, 0x40001000,
134         0x10440000, 0x00000008, 0x04200800, 0x40101000,
135         0x10000400, 0x00000020, 0x08200000, 0x00001100,
136         0x10040400, 0x00000020, 0x0c200000, 0x00101100,
137         0x10400400, 0x00000028, 0x08200800, 0x40001100,
138         0x10440400, 0x00000028, 0x0c200800, 0x40101100,
139         0x90000000, 0x00000010, 0x00200000, 0x00801000,
140         0x90040000, 0x00000010, 0x04200000, 0x00901000,
141         0x90400000, 0x00000018, 0x00200800, 0x40801000,
142         0x90440000, 0x00000018, 0x04200800, 0x40901000,
143         0x90000400, 0x00000030, 0x08200000, 0x00801100,
144         0x90040400, 0x00000030, 0x0c200000, 0x00901100,
145         0x90400400, 0x00000038, 0x08200800, 0x40801100,
146         0x90440400, 0x00000038, 0x0c200800, 0x40901100,
147         0x00000200, 0x00080000, 0x00000000, 0x00000004,
148         0x00040200, 0x00080000, 0x04000000, 0x00100004,
149         0x00400200, 0x00080008, 0x00000800, 0x40000004,
150         0x00440200, 0x00080008, 0x04000800, 0x40100004,
151         0x00000600, 0x00080020, 0x08000000, 0x00000104,
152         0x00040600, 0x00080020, 0x0c000000, 0x00100104,
153         0x00400600, 0x00080028, 0x08000800, 0x40000104,
154         0x00440600, 0x00080028, 0x0c000800, 0x40100104,
155         0x80000200, 0x00080010, 0x00000000, 0x00800004,
156         0x80040200, 0x00080010, 0x04000000, 0x00900004,
157         0x80400200, 0x00080018, 0x00000800, 0x40800004,
158         0x80440200, 0x00080018, 0x04000800, 0x40900004,
159         0x80000600, 0x00080030, 0x08000000, 0x00800104,
160         0x80040600, 0x00080030, 0x0c000000, 0x00900104,
161         0x80400600, 0x00080038, 0x08000800, 0x40800104,
162         0x80440600, 0x00080038, 0x0c000800, 0x40900104,
163         0x10000200, 0x00080000, 0x00200000, 0x00001004,
164         0x10040200, 0x00080000, 0x04200000, 0x00101004,
165         0x10400200, 0x00080008, 0x00200800, 0x40001004,
166         0x10440200, 0x00080008, 0x04200800, 0x40101004,
167         0x10000600, 0x00080020, 0x08200000, 0x00001104,
168         0x10040600, 0x00080020, 0x0c200000, 0x00101104,
169         0x10400600, 0x00080028, 0x08200800, 0x40001104,
170         0x10440600, 0x00080028, 0x0c200800, 0x40101104,
171         0x90000200, 0x00080010, 0x00200000, 0x00801004,
172         0x90040200, 0x00080010, 0x04200000, 0x00901004,
173         0x90400200, 0x00080018, 0x00200800, 0x40801004,
174         0x90440200, 0x00080018, 0x04200800, 0x40901004,
175         0x90000600, 0x00080030, 0x08200000, 0x00801104,
176         0x90040600, 0x00080030, 0x0c200000, 0x00901104,
177         0x90400600, 0x00080038, 0x08200800, 0x40801104,
178         0x90440600, 0x00080038, 0x0c200800, 0x40901104,
179         0x00000002, 0x00002000, 0x20000000, 0x00000001,
180         0x00040002, 0x00002000, 0x24000000, 0x00100001,
181         0x00400002, 0x00002008, 0x20000800, 0x40000001,
182         0x00440002, 0x00002008, 0x24000800, 0x40100001,
183         0x00000402, 0x00002020, 0x28000000, 0x00000101,
184         0x00040402, 0x00002020, 0x2c000000, 0x00100101,
185         0x00400402, 0x00002028, 0x28000800, 0x40000101,
186         0x00440402, 0x00002028, 0x2c000800, 0x40100101,
187         0x80000002, 0x00002010, 0x20000000, 0x00800001,
188         0x80040002, 0x00002010, 0x24000000, 0x00900001,
189         0x80400002, 0x00002018, 0x20000800, 0x40800001,
190         0x80440002, 0x00002018, 0x24000800, 0x40900001,
191         0x80000402, 0x00002030, 0x28000000, 0x00800101,
192         0x80040402, 0x00002030, 0x2c000000, 0x00900101,
193         0x80400402, 0x00002038, 0x28000800, 0x40800101,
194         0x80440402, 0x00002038, 0x2c000800, 0x40900101,
195         0x10000002, 0x00002000, 0x20200000, 0x00001001,
196         0x10040002, 0x00002000, 0x24200000, 0x00101001,
197         0x10400002, 0x00002008, 0x20200800, 0x40001001,
198         0x10440002, 0x00002008, 0x24200800, 0x40101001,
199         0x10000402, 0x00002020, 0x28200000, 0x00001101,
200         0x10040402, 0x00002020, 0x2c200000, 0x00101101,
201         0x10400402, 0x00002028, 0x28200800, 0x40001101,
202         0x10440402, 0x00002028, 0x2c200800, 0x40101101,
203         0x90000002, 0x00002010, 0x20200000, 0x00801001,
204         0x90040002, 0x00002010, 0x24200000, 0x00901001,
205         0x90400002, 0x00002018, 0x20200800, 0x40801001,
206         0x90440002, 0x00002018, 0x24200800, 0x40901001,
207         0x90000402, 0x00002030, 0x28200000, 0x00801101,
208         0x90040402, 0x00002030, 0x2c200000, 0x00901101,
209         0x90400402, 0x00002038, 0x28200800, 0x40801101,
210         0x90440402, 0x00002038, 0x2c200800, 0x40901101,
211         0x00000202, 0x00082000, 0x20000000, 0x00000005,
212         0x00040202, 0x00082000, 0x24000000, 0x00100005,
213         0x00400202, 0x00082008, 0x20000800, 0x40000005,
214         0x00440202, 0x00082008, 0x24000800, 0x40100005,
215         0x00000602, 0x00082020, 0x28000000, 0x00000105,
216         0x00040602, 0x00082020, 0x2c000000, 0x00100105,
217         0x00400602, 0x00082028, 0x28000800, 0x40000105,
218         0x00440602, 0x00082028, 0x2c000800, 0x40100105,
219         0x80000202, 0x00082010, 0x20000000, 0x00800005,
220         0x80040202, 0x00082010, 0x24000000, 0x00900005,
221         0x80400202, 0x00082018, 0x20000800, 0x40800005,
222         0x80440202, 0x00082018, 0x24000800, 0x40900005,
223         0x80000602, 0x00082030, 0x28000000, 0x00800105,
224         0x80040602, 0x00082030, 0x2c000000, 0x00900105,
225         0x80400602, 0x00082038, 0x28000800, 0x40800105,
226         0x80440602, 0x00082038, 0x2c000800, 0x40900105,
227         0x10000202, 0x00082000, 0x20200000, 0x00001005,
228         0x10040202, 0x00082000, 0x24200000, 0x00101005,
229         0x10400202, 0x00082008, 0x20200800, 0x40001005,
230         0x10440202, 0x00082008, 0x24200800, 0x40101005,
231         0x10000602, 0x00082020, 0x28200000, 0x00001105,
232         0x10040602, 0x00082020, 0x2c200000, 0x00101105,
233         0x10400602, 0x00082028, 0x28200800, 0x40001105,
234         0x10440602, 0x00082028, 0x2c200800, 0x40101105,
235         0x90000202, 0x00082010, 0x20200000, 0x00801005,
236         0x90040202, 0x00082010, 0x24200000, 0x00901005,
237         0x90400202, 0x00082018, 0x20200800, 0x40801005,
238         0x90440202, 0x00082018, 0x24200800, 0x40901005,
239         0x90000602, 0x00082030, 0x28200000, 0x00801105,
240         0x90040602, 0x00082030, 0x2c200000, 0x00901105,
241         0x90400602, 0x00082038, 0x28200800, 0x40801105,
242         0x90440602, 0x00082038, 0x2c200800, 0x40901105,
243
244         0x00000000, 0x00000000, 0x00000000, 0x00000000,
245         0x00000000, 0x00000008, 0x00080000, 0x10000000,
246         0x02000000, 0x00000000, 0x00000080, 0x00001000,
247         0x02000000, 0x00000008, 0x00080080, 0x10001000,
248         0x00004000, 0x00000000, 0x00000040, 0x00040000,
249         0x00004000, 0x00000008, 0x00080040, 0x10040000,
250         0x02004000, 0x00000000, 0x000000c0, 0x00041000,
251         0x02004000, 0x00000008, 0x000800c0, 0x10041000,
252         0x00020000, 0x00008000, 0x08000000, 0x00200000,
253         0x00020000, 0x00008008, 0x08080000, 0x10200000,
254         0x02020000, 0x00008000, 0x08000080, 0x00201000,
255         0x02020000, 0x00008008, 0x08080080, 0x10201000,
256         0x00024000, 0x00008000, 0x08000040, 0x00240000,
257         0x00024000, 0x00008008, 0x08080040, 0x10240000,
258         0x02024000, 0x00008000, 0x080000c0, 0x00241000,
259         0x02024000, 0x00008008, 0x080800c0, 0x10241000,
260         0x00000000, 0x01000000, 0x00002000, 0x00000020,
261         0x00000000, 0x01000008, 0x00082000, 0x10000020,
262         0x02000000, 0x01000000, 0x00002080, 0x00001020,
263         0x02000000, 0x01000008, 0x00082080, 0x10001020,
264         0x00004000, 0x01000000, 0x00002040, 0x00040020,
265         0x00004000, 0x01000008, 0x00082040, 0x10040020,
266         0x02004000, 0x01000000, 0x000020c0, 0x00041020,
267         0x02004000, 0x01000008, 0x000820c0, 0x10041020,
268         0x00020000, 0x01008000, 0x08002000, 0x00200020,
269         0x00020000, 0x01008008, 0x08082000, 0x10200020,
270         0x02020000, 0x01008000, 0x08002080, 0x00201020,
271         0x02020000, 0x01008008, 0x08082080, 0x10201020,
272         0x00024000, 0x01008000, 0x08002040, 0x00240020,
273         0x00024000, 0x01008008, 0x08082040, 0x10240020,
274         0x02024000, 0x01008000, 0x080020c0, 0x00241020,
275         0x02024000, 0x01008008, 0x080820c0, 0x10241020,
276         0x00000400, 0x04000000, 0x00100000, 0x00000004,
277         0x00000400, 0x04000008, 0x00180000, 0x10000004,
278         0x02000400, 0x04000000, 0x00100080, 0x00001004,
279         0x02000400, 0x04000008, 0x00180080, 0x10001004,
280         0x00004400, 0x04000000, 0x00100040, 0x00040004,
281         0x00004400, 0x04000008, 0x00180040, 0x10040004,
282         0x02004400, 0x04000000, 0x001000c0, 0x00041004,
283         0x02004400, 0x04000008, 0x001800c0, 0x10041004,
284         0x00020400, 0x04008000, 0x08100000, 0x00200004,
285         0x00020400, 0x04008008, 0x08180000, 0x10200004,
286         0x02020400, 0x04008000, 0x08100080, 0x00201004,
287         0x02020400, 0x04008008, 0x08180080, 0x10201004,
288         0x00024400, 0x04008000, 0x08100040, 0x00240004,
289         0x00024400, 0x04008008, 0x08180040, 0x10240004,
290         0x02024400, 0x04008000, 0x081000c0, 0x00241004,
291         0x02024400, 0x04008008, 0x081800c0, 0x10241004,
292         0x00000400, 0x05000000, 0x00102000, 0x00000024,
293         0x00000400, 0x05000008, 0x00182000, 0x10000024,
294         0x02000400, 0x05000000, 0x00102080, 0x00001024,
295         0x02000400, 0x05000008, 0x00182080, 0x10001024,
296         0x00004400, 0x05000000, 0x00102040, 0x00040024,
297         0x00004400, 0x05000008, 0x00182040, 0x10040024,
298         0x02004400, 0x05000000, 0x001020c0, 0x00041024,
299         0x02004400, 0x05000008, 0x001820c0, 0x10041024,
300         0x00020400, 0x05008000, 0x08102000, 0x00200024,
301         0x00020400, 0x05008008, 0x08182000, 0x10200024,
302         0x02020400, 0x05008000, 0x08102080, 0x00201024,
303         0x02020400, 0x05008008, 0x08182080, 0x10201024,
304         0x00024400, 0x05008000, 0x08102040, 0x00240024,
305         0x00024400, 0x05008008, 0x08182040, 0x10240024,
306         0x02024400, 0x05008000, 0x081020c0, 0x00241024,
307         0x02024400, 0x05008008, 0x081820c0, 0x10241024,
308         0x00000800, 0x00010000, 0x20000000, 0x00000010,
309         0x00000800, 0x00010008, 0x20080000, 0x10000010,
310         0x02000800, 0x00010000, 0x20000080, 0x00001010,
311         0x02000800, 0x00010008, 0x20080080, 0x10001010,
312         0x00004800, 0x00010000, 0x20000040, 0x00040010,
313         0x00004800, 0x00010008, 0x20080040, 0x10040010,
314         0x02004800, 0x00010000, 0x200000c0, 0x00041010,
315         0x02004800, 0x00010008, 0x200800c0, 0x10041010,
316         0x00020800, 0x00018000, 0x28000000, 0x00200010,
317         0x00020800, 0x00018008, 0x28080000, 0x10200010,
318         0x02020800, 0x00018000, 0x28000080, 0x00201010,
319         0x02020800, 0x00018008, 0x28080080, 0x10201010,
320         0x00024800, 0x00018000, 0x28000040, 0x00240010,
321         0x00024800, 0x00018008, 0x28080040, 0x10240010,
322         0x02024800, 0x00018000, 0x280000c0, 0x00241010,
323         0x02024800, 0x00018008, 0x280800c0, 0x10241010,
324         0x00000800, 0x01010000, 0x20002000, 0x00000030,
325         0x00000800, 0x01010008, 0x20082000, 0x10000030,
326         0x02000800, 0x01010000, 0x20002080, 0x00001030,
327         0x02000800, 0x01010008, 0x20082080, 0x10001030,
328         0x00004800, 0x01010000, 0x20002040, 0x00040030,
329         0x00004800, 0x01010008, 0x20082040, 0x10040030,
330         0x02004800, 0x01010000, 0x200020c0, 0x00041030,
331         0x02004800, 0x01010008, 0x200820c0, 0x10041030,
332         0x00020800, 0x01018000, 0x28002000, 0x00200030,
333         0x00020800, 0x01018008, 0x28082000, 0x10200030,
334         0x02020800, 0x01018000, 0x28002080, 0x00201030,
335         0x02020800, 0x01018008, 0x28082080, 0x10201030,
336         0x00024800, 0x01018000, 0x28002040, 0x00240030,
337         0x00024800, 0x01018008, 0x28082040, 0x10240030,
338         0x02024800, 0x01018000, 0x280020c0, 0x00241030,
339         0x02024800, 0x01018008, 0x280820c0, 0x10241030,
340         0x00000c00, 0x04010000, 0x20100000, 0x00000014,
341         0x00000c00, 0x04010008, 0x20180000, 0x10000014,
342         0x02000c00, 0x04010000, 0x20100080, 0x00001014,
343         0x02000c00, 0x04010008, 0x20180080, 0x10001014,
344         0x00004c00, 0x04010000, 0x20100040, 0x00040014,
345         0x00004c00, 0x04010008, 0x20180040, 0x10040014,
346         0x02004c00, 0x04010000, 0x201000c0, 0x00041014,
347         0x02004c00, 0x04010008, 0x201800c0, 0x10041014,
348         0x00020c00, 0x04018000, 0x28100000, 0x00200014,
349         0x00020c00, 0x04018008, 0x28180000, 0x10200014,
350         0x02020c00, 0x04018000, 0x28100080, 0x00201014,
351         0x02020c00, 0x04018008, 0x28180080, 0x10201014,
352         0x00024c00, 0x04018000, 0x28100040, 0x00240014,
353         0x00024c00, 0x04018008, 0x28180040, 0x10240014,
354         0x02024c00, 0x04018000, 0x281000c0, 0x00241014,
355         0x02024c00, 0x04018008, 0x281800c0, 0x10241014,
356         0x00000c00, 0x05010000, 0x20102000, 0x00000034,
357         0x00000c00, 0x05010008, 0x20182000, 0x10000034,
358         0x02000c00, 0x05010000, 0x20102080, 0x00001034,
359         0x02000c00, 0x05010008, 0x20182080, 0x10001034,
360         0x00004c00, 0x05010000, 0x20102040, 0x00040034,
361         0x00004c00, 0x05010008, 0x20182040, 0x10040034,
362         0x02004c00, 0x05010000, 0x201020c0, 0x00041034,
363         0x02004c00, 0x05010008, 0x201820c0, 0x10041034,
364         0x00020c00, 0x05018000, 0x28102000, 0x00200034,
365         0x00020c00, 0x05018008, 0x28182000, 0x10200034,
366         0x02020c00, 0x05018000, 0x28102080, 0x00201034,
367         0x02020c00, 0x05018008, 0x28182080, 0x10201034,
368         0x00024c00, 0x05018000, 0x28102040, 0x00240034,
369         0x00024c00, 0x05018008, 0x28182040, 0x10240034,
370         0x02024c00, 0x05018000, 0x281020c0, 0x00241034,
371         0x02024c00, 0x05018008, 0x281820c0, 0x10241034
372 };
373
374 /* S-box lookup tables */
375
376 static const u32 S1[64] = {
377         0x01010400, 0x00000000, 0x00010000, 0x01010404,
378         0x01010004, 0x00010404, 0x00000004, 0x00010000,
379         0x00000400, 0x01010400, 0x01010404, 0x00000400,
380         0x01000404, 0x01010004, 0x01000000, 0x00000004,
381         0x00000404, 0x01000400, 0x01000400, 0x00010400,
382         0x00010400, 0x01010000, 0x01010000, 0x01000404,
383         0x00010004, 0x01000004, 0x01000004, 0x00010004,
384         0x00000000, 0x00000404, 0x00010404, 0x01000000,
385         0x00010000, 0x01010404, 0x00000004, 0x01010000,
386         0x01010400, 0x01000000, 0x01000000, 0x00000400,
387         0x01010004, 0x00010000, 0x00010400, 0x01000004,
388         0x00000400, 0x00000004, 0x01000404, 0x00010404,
389         0x01010404, 0x00010004, 0x01010000, 0x01000404,
390         0x01000004, 0x00000404, 0x00010404, 0x01010400,
391         0x00000404, 0x01000400, 0x01000400, 0x00000000,
392         0x00010004, 0x00010400, 0x00000000, 0x01010004
393 };
394
395 static const u32 S2[64] = {
396         0x80108020, 0x80008000, 0x00008000, 0x00108020,
397         0x00100000, 0x00000020, 0x80100020, 0x80008020,
398         0x80000020, 0x80108020, 0x80108000, 0x80000000,
399         0x80008000, 0x00100000, 0x00000020, 0x80100020,
400         0x00108000, 0x00100020, 0x80008020, 0x00000000,
401         0x80000000, 0x00008000, 0x00108020, 0x80100000,
402         0x00100020, 0x80000020, 0x00000000, 0x00108000,
403         0x00008020, 0x80108000, 0x80100000, 0x00008020,
404         0x00000000, 0x00108020, 0x80100020, 0x00100000,
405         0x80008020, 0x80100000, 0x80108000, 0x00008000,
406         0x80100000, 0x80008000, 0x00000020, 0x80108020,
407         0x00108020, 0x00000020, 0x00008000, 0x80000000,
408         0x00008020, 0x80108000, 0x00100000, 0x80000020,
409         0x00100020, 0x80008020, 0x80000020, 0x00100020,
410         0x00108000, 0x00000000, 0x80008000, 0x00008020,
411         0x80000000, 0x80100020, 0x80108020, 0x00108000
412 };
413
414 static const u32 S3[64] = {
415         0x00000208, 0x08020200, 0x00000000, 0x08020008,
416         0x08000200, 0x00000000, 0x00020208, 0x08000200,
417         0x00020008, 0x08000008, 0x08000008, 0x00020000,
418         0x08020208, 0x00020008, 0x08020000, 0x00000208,
419         0x08000000, 0x00000008, 0x08020200, 0x00000200,
420         0x00020200, 0x08020000, 0x08020008, 0x00020208,
421         0x08000208, 0x00020200, 0x00020000, 0x08000208,
422         0x00000008, 0x08020208, 0x00000200, 0x08000000,
423         0x08020200, 0x08000000, 0x00020008, 0x00000208,
424         0x00020000, 0x08020200, 0x08000200, 0x00000000,
425         0x00000200, 0x00020008, 0x08020208, 0x08000200,
426         0x08000008, 0x00000200, 0x00000000, 0x08020008,
427         0x08000208, 0x00020000, 0x08000000, 0x08020208,
428         0x00000008, 0x00020208, 0x00020200, 0x08000008,
429         0x08020000, 0x08000208, 0x00000208, 0x08020000,
430         0x00020208, 0x00000008, 0x08020008, 0x00020200
431 };
432
433 static const u32 S4[64] = {
434         0x00802001, 0x00002081, 0x00002081, 0x00000080,
435         0x00802080, 0x00800081, 0x00800001, 0x00002001,
436         0x00000000, 0x00802000, 0x00802000, 0x00802081,
437         0x00000081, 0x00000000, 0x00800080, 0x00800001,
438         0x00000001, 0x00002000, 0x00800000, 0x00802001,
439         0x00000080, 0x00800000, 0x00002001, 0x00002080,
440         0x00800081, 0x00000001, 0x00002080, 0x00800080,
441         0x00002000, 0x00802080, 0x00802081, 0x00000081,
442         0x00800080, 0x00800001, 0x00802000, 0x00802081,
443         0x00000081, 0x00000000, 0x00000000, 0x00802000,
444         0x00002080, 0x00800080, 0x00800081, 0x00000001,
445         0x00802001, 0x00002081, 0x00002081, 0x00000080,
446         0x00802081, 0x00000081, 0x00000001, 0x00002000,
447         0x00800001, 0x00002001, 0x00802080, 0x00800081,
448         0x00002001, 0x00002080, 0x00800000, 0x00802001,
449         0x00000080, 0x00800000, 0x00002000, 0x00802080
450 };
451
452 static const u32 S5[64] = {
453         0x00000100, 0x02080100, 0x02080000, 0x42000100,
454         0x00080000, 0x00000100, 0x40000000, 0x02080000,
455         0x40080100, 0x00080000, 0x02000100, 0x40080100,
456         0x42000100, 0x42080000, 0x00080100, 0x40000000,
457         0x02000000, 0x40080000, 0x40080000, 0x00000000,
458         0x40000100, 0x42080100, 0x42080100, 0x02000100,
459         0x42080000, 0x40000100, 0x00000000, 0x42000000,
460         0x02080100, 0x02000000, 0x42000000, 0x00080100,
461         0x00080000, 0x42000100, 0x00000100, 0x02000000,
462         0x40000000, 0x02080000, 0x42000100, 0x40080100,
463         0x02000100, 0x40000000, 0x42080000, 0x02080100,
464         0x40080100, 0x00000100, 0x02000000, 0x42080000,
465         0x42080100, 0x00080100, 0x42000000, 0x42080100,
466         0x02080000, 0x00000000, 0x40080000, 0x42000000,
467         0x00080100, 0x02000100, 0x40000100, 0x00080000,
468         0x00000000, 0x40080000, 0x02080100, 0x40000100
469 };
470
471 static const u32 S6[64] = {
472         0x20000010, 0x20400000, 0x00004000, 0x20404010,
473         0x20400000, 0x00000010, 0x20404010, 0x00400000,
474         0x20004000, 0x00404010, 0x00400000, 0x20000010,
475         0x00400010, 0x20004000, 0x20000000, 0x00004010,
476         0x00000000, 0x00400010, 0x20004010, 0x00004000,
477         0x00404000, 0x20004010, 0x00000010, 0x20400010,
478         0x20400010, 0x00000000, 0x00404010, 0x20404000,
479         0x00004010, 0x00404000, 0x20404000, 0x20000000,
480         0x20004000, 0x00000010, 0x20400010, 0x00404000,
481         0x20404010, 0x00400000, 0x00004010, 0x20000010,
482         0x00400000, 0x20004000, 0x20000000, 0x00004010,
483         0x20000010, 0x20404010, 0x00404000, 0x20400000,
484         0x00404010, 0x20404000, 0x00000000, 0x20400010,
485         0x00000010, 0x00004000, 0x20400000, 0x00404010,
486         0x00004000, 0x00400010, 0x20004010, 0x00000000,
487         0x20404000, 0x20000000, 0x00400010, 0x20004010
488 };
489
490 static const u32 S7[64] = {
491         0x00200000, 0x04200002, 0x04000802, 0x00000000,
492         0x00000800, 0x04000802, 0x00200802, 0x04200800,
493         0x04200802, 0x00200000, 0x00000000, 0x04000002,
494         0x00000002, 0x04000000, 0x04200002, 0x00000802,
495         0x04000800, 0x00200802, 0x00200002, 0x04000800,
496         0x04000002, 0x04200000, 0x04200800, 0x00200002,
497         0x04200000, 0x00000800, 0x00000802, 0x04200802,
498         0x00200800, 0x00000002, 0x04000000, 0x00200800,
499         0x04000000, 0x00200800, 0x00200000, 0x04000802,
500         0x04000802, 0x04200002, 0x04200002, 0x00000002,
501         0x00200002, 0x04000000, 0x04000800, 0x00200000,
502         0x04200800, 0x00000802, 0x00200802, 0x04200800,
503         0x00000802, 0x04000002, 0x04200802, 0x04200000,
504         0x00200800, 0x00000000, 0x00000002, 0x04200802,
505         0x00000000, 0x00200802, 0x04200000, 0x00000800,
506         0x04000002, 0x04000800, 0x00000800, 0x00200002
507 };
508
509 static const u32 S8[64] = {
510         0x10001040, 0x00001000, 0x00040000, 0x10041040,
511         0x10000000, 0x10001040, 0x00000040, 0x10000000,
512         0x00040040, 0x10040000, 0x10041040, 0x00041000,
513         0x10041000, 0x00041040, 0x00001000, 0x00000040,
514         0x10040000, 0x10000040, 0x10001000, 0x00001040,
515         0x00041000, 0x00040040, 0x10040040, 0x10041000,
516         0x00001040, 0x00000000, 0x00000000, 0x10040040,
517         0x10000040, 0x10001000, 0x00041040, 0x00040000,
518         0x00041040, 0x00040000, 0x10041000, 0x00001000,
519         0x00000040, 0x10040040, 0x00001000, 0x00041040,
520         0x10001000, 0x00000040, 0x10000040, 0x10040000,
521         0x10040040, 0x10000000, 0x00040000, 0x10001040,
522         0x00000000, 0x10041040, 0x00040040, 0x10000040,
523         0x10040000, 0x10001000, 0x10001040, 0x00000000,
524         0x10041040, 0x00041000, 0x00041000, 0x00001040,
525         0x00001040, 0x00040040, 0x10000000, 0x10041000
526 };
527
528 /* Encryption components: IP, FP, and round function */
529
530 #define IP(L, R, T)             \
531         ROL(R, 4);              \
532         T  = L;                 \
533         L ^= R;                 \
534         L &= 0xf0f0f0f0;        \
535         R ^= L;                 \
536         L ^= T;                 \
537         ROL(R, 12);             \
538         T  = L;                 \
539         L ^= R;                 \
540         L &= 0xffff0000;        \
541         R ^= L;                 \
542         L ^= T;                 \
543         ROR(R, 14);             \
544         T  = L;                 \
545         L ^= R;                 \
546         L &= 0xcccccccc;        \
547         R ^= L;                 \
548         L ^= T;                 \
549         ROL(R, 6);              \
550         T  = L;                 \
551         L ^= R;                 \
552         L &= 0xff00ff00;        \
553         R ^= L;                 \
554         L ^= T;                 \
555         ROR(R, 7);              \
556         T  = L;                 \
557         L ^= R;                 \
558         L &= 0xaaaaaaaa;        \
559         R ^= L;                 \
560         L ^= T;                 \
561         ROL(L, 1);
562
563 #define FP(L, R, T)             \
564         ROR(L, 1);              \
565         T  = L;                 \
566         L ^= R;                 \
567         L &= 0xaaaaaaaa;        \
568         R ^= L;                 \
569         L ^= T;                 \
570         ROL(R, 7);              \
571         T  = L;                 \
572         L ^= R;                 \
573         L &= 0xff00ff00;        \
574         R ^= L;                 \
575         L ^= T;                 \
576         ROR(R, 6);              \
577         T  = L;                 \
578         L ^= R;                 \
579         L &= 0xcccccccc;        \
580         R ^= L;                 \
581         L ^= T;                 \
582         ROL(R, 14);             \
583         T  = L;                 \
584         L ^= R;                 \
585         L &= 0xffff0000;        \
586         R ^= L;                 \
587         L ^= T;                 \
588         ROR(R, 12);             \
589         T  = L;                 \
590         L ^= R;                 \
591         L &= 0xf0f0f0f0;        \
592         R ^= L;                 \
593         L ^= T;                 \
594         ROR(R, 4);
595
596 #define ROUND(L, R, A, B, K, d)                                 \
597         B = K[0];                       A = K[1];       K += d; \
598         B ^= R;                         A ^= R;                 \
599         B &= 0x3f3f3f3f;                ROR(A, 4);              \
600         L ^= S8[0xff & B];              A &= 0x3f3f3f3f;        \
601         L ^= S6[0xff & (B >> 8)];       B >>= 16;               \
602         L ^= S7[0xff & A];                                      \
603         L ^= S5[0xff & (A >> 8)];       A >>= 16;               \
604         L ^= S4[0xff & B];                                      \
605         L ^= S2[0xff & (B >> 8)];                               \
606         L ^= S3[0xff & A];                                      \
607         L ^= S1[0xff & (A >> 8)];
608
609 /*
610  * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
611  * tables of 128 elements.  One set is for C_i and the other for D_i, while
612  * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i.
613  *
614  * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i
615  * or D_i in bits 7-1 (bit 0 being the least significant).
616  */
617
618 #define T1(x) pt[2 * (x) + 0]
619 #define T2(x) pt[2 * (x) + 1]
620 #define T3(x) pt[2 * (x) + 2]
621 #define T4(x) pt[2 * (x) + 3]
622
623 #define PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a))
624
625 /*
626  * Encryption key expansion
627  *
628  * RFC2451: Weak key checks SHOULD be performed.
629  *
630  * FIPS 74:
631  *
632  *   Keys having duals are keys which produce all zeros, all ones, or
633  *   alternating zero-one patterns in the C and D registers after Permuted
634  *   Choice 1 has operated on the key.
635  *
636  */
637 static unsigned long ekey(u32 *pe, const u8 *k)
638 {
639         /* K&R: long is at least 32 bits */
640         unsigned long a, b, c, d, w;
641         const u32 *pt = pc2;
642
643         d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
644         c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
645         b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
646         a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
647
648         pe[15 * 2 + 0] = PC2(a, b, c, d); d = rs[d];
649         pe[14 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
650         pe[13 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
651         pe[12 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
652         pe[11 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
653         pe[10 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
654         pe[ 9 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
655         pe[ 8 * 2 + 0] = PC2(d, a, b, c); c = rs[c];
656         pe[ 7 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
657         pe[ 6 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
658         pe[ 5 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
659         pe[ 4 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
660         pe[ 3 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
661         pe[ 2 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
662         pe[ 1 * 2 + 0] = PC2(c, d, a, b); b = rs[b];
663         pe[ 0 * 2 + 0] = PC2(b, c, d, a);
664
665         /* Check if first half is weak */
666         w  = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
667
668         /* Skip to next table set */
669         pt += 512;
670
671         d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
672         c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
673         b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
674         a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
675
676         /* Check if second half is weak */
677         w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
678
679         pe[15 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
680         pe[14 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
681         pe[13 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
682         pe[12 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
683         pe[11 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
684         pe[10 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
685         pe[ 9 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
686         pe[ 8 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
687         pe[ 7 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
688         pe[ 6 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
689         pe[ 5 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
690         pe[ 4 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
691         pe[ 3 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
692         pe[ 2 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
693         pe[ 1 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
694         pe[ 0 * 2 + 1] = PC2(b, c, d, a);
695
696         /* Fixup: 2413 5768 -> 1357 2468 */
697         for (d = 0; d < 16; ++d) {
698                 a = pe[2 * d];
699                 b = pe[2 * d + 1];
700                 c = a ^ b;
701                 c &= 0xffff0000;
702                 a ^= c;
703                 b ^= c;
704                 ROL(b, 18);
705                 pe[2 * d] = a;
706                 pe[2 * d + 1] = b;
707         }
708
709         /* Zero if weak key */
710         return w;
711 }
712
713 /*
714  * Decryption key expansion
715  *
716  * No weak key checking is performed, as this is only used by triple DES
717  *
718  */
719 static void dkey(u32 *pe, const u8 *k)
720 {
721         /* K&R: long is at least 32 bits */
722         unsigned long a, b, c, d;
723         const u32 *pt = pc2;
724
725         d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
726         c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
727         b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
728         a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
729
730         pe[ 0 * 2] = PC2(a, b, c, d); d = rs[d];
731         pe[ 1 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
732         pe[ 2 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
733         pe[ 3 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
734         pe[ 4 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
735         pe[ 5 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
736         pe[ 6 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
737         pe[ 7 * 2] = PC2(d, a, b, c); c = rs[c];
738         pe[ 8 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
739         pe[ 9 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
740         pe[10 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
741         pe[11 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
742         pe[12 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
743         pe[13 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
744         pe[14 * 2] = PC2(c, d, a, b); b = rs[b];
745         pe[15 * 2] = PC2(b, c, d, a);
746
747         /* Skip to next table set */
748         pt += 512;
749
750         d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
751         c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
752         b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
753         a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
754
755         pe[ 0 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
756         pe[ 1 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
757         pe[ 2 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
758         pe[ 3 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
759         pe[ 4 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
760         pe[ 5 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
761         pe[ 6 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
762         pe[ 7 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
763         pe[ 8 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
764         pe[ 9 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
765         pe[10 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
766         pe[11 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
767         pe[12 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
768         pe[13 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
769         pe[14 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
770         pe[15 * 2 + 1] = PC2(b, c, d, a);
771
772         /* Fixup: 2413 5768 -> 1357 2468 */
773         for (d = 0; d < 16; ++d) {
774                 a = pe[2 * d];
775                 b = pe[2 * d + 1];
776                 c = a ^ b;
777                 c &= 0xffff0000;
778                 a ^= c;
779                 b ^= c;
780                 ROL(b, 18);
781                 pe[2 * d] = a;
782                 pe[2 * d + 1] = b;
783         }
784 }
785
786 static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
787 {
788         struct des_ctx *dctx = ctx;
789         u32 tmp[DES_EXPKEY_WORDS];
790         int ret;
791
792         /* Expand to tmp */
793         ret = ekey(tmp, key);
794
795         if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
796                 *flags |= CRYPTO_TFM_RES_WEAK_KEY;
797                 return -EINVAL;
798         }
799
800         /* Copy to output */
801         memcpy(dctx->expkey, tmp, sizeof(dctx->expkey));
802
803         return 0;
804 }
805
806 static void des_encrypt(void *ctx, u8 *dst, const u8 *src)
807 {
808         const u32 *K = ((struct des_ctx *)ctx)->expkey;
809         const __le32 *s = (const __le32 *)src;
810         __le32 *d = (__le32 *)dst;
811         u32 L, R, A, B;
812         int i;
813
814         L = le32_to_cpu(s[0]);
815         R = le32_to_cpu(s[1]);
816
817         IP(L, R, A);
818         for (i = 0; i < 8; i++) {
819                 ROUND(L, R, A, B, K, 2);
820                 ROUND(R, L, A, B, K, 2);
821         }
822         FP(R, L, A);
823
824         d[0] = cpu_to_le32(R);
825         d[1] = cpu_to_le32(L);
826 }
827
828 static void des_decrypt(void *ctx, u8 *dst, const u8 *src)
829 {
830         const u32 *K = ((struct des_ctx *)ctx)->expkey + DES_EXPKEY_WORDS - 2;
831         const __le32 *s = (const __le32 *)src;
832         __le32 *d = (__le32 *)dst;
833         u32 L, R, A, B;
834         int i;
835
836         L = le32_to_cpu(s[0]);
837         R = le32_to_cpu(s[1]);
838
839         IP(L, R, A);
840         for (i = 0; i < 8; i++) {
841                 ROUND(L, R, A, B, K, -2);
842                 ROUND(R, L, A, B, K, -2);
843         }
844         FP(R, L, A);
845
846         d[0] = cpu_to_le32(R);
847         d[1] = cpu_to_le32(L);
848 }
849
850 /*
851  * RFC2451:
852  *
853  *   For DES-EDE3, there is no known need to reject weak or
854  *   complementation keys.  Any weakness is obviated by the use of
855  *   multiple keys.
856  *
857  *   However, if the first two or last two independent 64-bit keys are
858  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
859  *   same as DES.  Implementers MUST reject keys that exhibit this
860  *   property.
861  *
862  */
863 static int des3_ede_setkey(void *ctx, const u8 *key,
864                            unsigned int keylen, u32 *flags)
865 {
866         const u32 *K = (const u32 *)key;
867         struct des3_ede_ctx *dctx = ctx;
868         u32 *expkey = dctx->expkey;
869
870         if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
871                      !((K[2] ^ K[4]) | (K[3] ^ K[5]))))
872         {
873                 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
874                 return -EINVAL;
875         }
876
877         ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
878         dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
879         ekey(expkey, key);
880
881         return 0;
882 }
883
884 static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src)
885 {
886         struct des3_ede_ctx *dctx = ctx;
887         const u32 *K = dctx->expkey;
888         const __le32 *s = (const __le32 *)src;
889         __le32 *d = (__le32 *)dst;
890         u32 L, R, A, B;
891         int i;
892
893         L = le32_to_cpu(s[0]);
894         R = le32_to_cpu(s[1]);
895
896         IP(L, R, A);
897         for (i = 0; i < 8; i++) {
898                 ROUND(L, R, A, B, K, 2);
899                 ROUND(R, L, A, B, K, 2);
900         }
901         for (i = 0; i < 8; i++) {
902                 ROUND(R, L, A, B, K, 2);
903                 ROUND(L, R, A, B, K, 2);
904         }
905         for (i = 0; i < 8; i++) {
906                 ROUND(L, R, A, B, K, 2);
907                 ROUND(R, L, A, B, K, 2);
908         }
909         FP(R, L, A);
910
911         d[0] = cpu_to_le32(R);
912         d[1] = cpu_to_le32(L);
913 }
914
915 static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src)
916 {
917         struct des3_ede_ctx *dctx = ctx;
918         const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
919         const __le32 *s = (const __le32 *)src;
920         __le32 *d = (__le32 *)dst;
921         u32 L, R, A, B;
922         int i;
923
924         L = le32_to_cpu(s[0]);
925         R = le32_to_cpu(s[1]);
926
927         IP(L, R, A);
928         for (i = 0; i < 8; i++) {
929                 ROUND(L, R, A, B, K, -2);
930                 ROUND(R, L, A, B, K, -2);
931         }
932         for (i = 0; i < 8; i++) {
933                 ROUND(R, L, A, B, K, -2);
934                 ROUND(L, R, A, B, K, -2);
935         }
936         for (i = 0; i < 8; i++) {
937                 ROUND(L, R, A, B, K, -2);
938                 ROUND(R, L, A, B, K, -2);
939         }
940         FP(R, L, A);
941
942         d[0] = cpu_to_le32(R);
943         d[1] = cpu_to_le32(L);
944 }
945
946 static struct crypto_alg des_alg = {
947         .cra_name               =       "des",
948         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
949         .cra_blocksize          =       DES_BLOCK_SIZE,
950         .cra_ctxsize            =       sizeof(struct des_ctx),
951         .cra_module             =       THIS_MODULE,
952         .cra_alignmask          =       3,
953         .cra_list               =       LIST_HEAD_INIT(des_alg.cra_list),
954         .cra_u                  =       { .cipher = {
955         .cia_min_keysize        =       DES_KEY_SIZE,
956         .cia_max_keysize        =       DES_KEY_SIZE,
957         .cia_setkey             =       des_setkey,
958         .cia_encrypt            =       des_encrypt,
959         .cia_decrypt            =       des_decrypt } }
960 };
961
962 static struct crypto_alg des3_ede_alg = {
963         .cra_name               =       "des3_ede",
964         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
965         .cra_blocksize          =       DES3_EDE_BLOCK_SIZE,
966         .cra_ctxsize            =       sizeof(struct des3_ede_ctx),
967         .cra_module             =       THIS_MODULE,
968         .cra_alignmask          =       3,
969         .cra_list               =       LIST_HEAD_INIT(des3_ede_alg.cra_list),
970         .cra_u                  =       { .cipher = {
971         .cia_min_keysize        =       DES3_EDE_KEY_SIZE,
972         .cia_max_keysize        =       DES3_EDE_KEY_SIZE,
973         .cia_setkey             =       des3_ede_setkey,
974         .cia_encrypt            =       des3_ede_encrypt,
975         .cia_decrypt            =       des3_ede_decrypt } }
976 };
977
978 MODULE_ALIAS("des3_ede");
979
980 static int __init init(void)
981 {
982         int ret = 0;
983
984         ret = crypto_register_alg(&des_alg);
985         if (ret < 0)
986                 goto out;
987
988         ret = crypto_register_alg(&des3_ede_alg);
989         if (ret < 0)
990                 crypto_unregister_alg(&des_alg);
991 out:
992         return ret;
993 }
994
995 static void __exit fini(void)
996 {
997         crypto_unregister_alg(&des3_ede_alg);
998         crypto_unregister_alg(&des_alg);
999 }
1000
1001 module_init(init);
1002 module_exit(fini);
1003
1004 MODULE_LICENSE("GPL");
1005 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
1006 MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");