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