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