xref: /linux/crypto/des_generic.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
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 DES_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] = DES_PC2(a, b, c, d); d = rs[d];
643 	pe[14 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
644 	pe[13 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
645 	pe[12 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
646 	pe[11 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
647 	pe[10 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
648 	pe[ 9 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
649 	pe[ 8 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c];
650 	pe[ 7 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
651 	pe[ 6 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
652 	pe[ 5 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
653 	pe[ 4 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
654 	pe[ 3 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
655 	pe[ 2 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
656 	pe[ 1 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b];
657 	pe[ 0 * 2 + 0] = DES_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] = DES_PC2(a, b, c, d); d = rs[d];
674 	pe[14 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
675 	pe[13 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
676 	pe[12 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
677 	pe[11 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
678 	pe[10 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
679 	pe[ 9 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
680 	pe[ 8 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c];
681 	pe[ 7 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
682 	pe[ 6 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
683 	pe[ 5 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
684 	pe[ 4 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
685 	pe[ 3 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
686 	pe[ 2 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
687 	pe[ 1 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b];
688 	pe[ 0 * 2 + 1] = DES_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] = DES_PC2(a, b, c, d); d = rs[d];
726 	pe[ 1 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
727 	pe[ 2 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
728 	pe[ 3 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
729 	pe[ 4 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
730 	pe[ 5 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
731 	pe[ 6 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
732 	pe[ 7 * 2] = DES_PC2(d, a, b, c); c = rs[c];
733 	pe[ 8 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
734 	pe[ 9 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
735 	pe[10 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
736 	pe[11 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
737 	pe[12 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
738 	pe[13 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
739 	pe[14 * 2] = DES_PC2(c, d, a, b); b = rs[b];
740 	pe[15 * 2] = DES_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] = DES_PC2(a, b, c, d); d = rs[d];
751 	pe[ 1 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
752 	pe[ 2 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
753 	pe[ 3 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
754 	pe[ 4 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
755 	pe[ 5 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
756 	pe[ 6 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
757 	pe[ 7 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c];
758 	pe[ 8 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
759 	pe[ 9 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
760 	pe[10 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
761 	pe[11 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
762 	pe[12 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
763 	pe[13 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
764 	pe[14 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b];
765 	pe[15 * 2 + 1] = DES_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 int __des3_ede_setkey(u32 *expkey, u32 *flags, const u8 *key,
863 		      unsigned int keylen)
864 {
865 	const u32 *K = (const u32 *)key;
866 
867 	if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
868 		     !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
869 		     (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
870 		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
871 		return -EINVAL;
872 	}
873 
874 	des_ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
875 	dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
876 	des_ekey(expkey, key);
877 
878 	return 0;
879 }
880 EXPORT_SYMBOL_GPL(__des3_ede_setkey);
881 
882 static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
883 			   unsigned int keylen)
884 {
885 	struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
886 	u32 *flags = &tfm->crt_flags;
887 	u32 *expkey = dctx->expkey;
888 
889 	return __des3_ede_setkey(expkey, flags, key, keylen);
890 }
891 
892 static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
893 {
894 	struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
895 	const u32 *K = dctx->expkey;
896 	const __le32 *s = (const __le32 *)src;
897 	__le32 *d = (__le32 *)dst;
898 	u32 L, R, A, B;
899 	int i;
900 
901 	L = le32_to_cpu(s[0]);
902 	R = le32_to_cpu(s[1]);
903 
904 	IP(L, R, A);
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 	for (i = 0; i < 8; i++) {
910 		ROUND(R, L, A, B, K, 2);
911 		ROUND(L, R, A, B, K, 2);
912 	}
913 	for (i = 0; i < 8; i++) {
914 		ROUND(L, R, A, B, K, 2);
915 		ROUND(R, L, A, B, K, 2);
916 	}
917 	FP(R, L, A);
918 
919 	d[0] = cpu_to_le32(R);
920 	d[1] = cpu_to_le32(L);
921 }
922 
923 static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
924 {
925 	struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
926 	const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
927 	const __le32 *s = (const __le32 *)src;
928 	__le32 *d = (__le32 *)dst;
929 	u32 L, R, A, B;
930 	int i;
931 
932 	L = le32_to_cpu(s[0]);
933 	R = le32_to_cpu(s[1]);
934 
935 	IP(L, R, A);
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 	for (i = 0; i < 8; i++) {
941 		ROUND(R, L, A, B, K, -2);
942 		ROUND(L, R, A, B, K, -2);
943 	}
944 	for (i = 0; i < 8; i++) {
945 		ROUND(L, R, A, B, K, -2);
946 		ROUND(R, L, A, B, K, -2);
947 	}
948 	FP(R, L, A);
949 
950 	d[0] = cpu_to_le32(R);
951 	d[1] = cpu_to_le32(L);
952 }
953 
954 static struct crypto_alg des_algs[2] = { {
955 	.cra_name		=	"des",
956 	.cra_driver_name	=	"des-generic",
957 	.cra_priority		=	100,
958 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
959 	.cra_blocksize		=	DES_BLOCK_SIZE,
960 	.cra_ctxsize		=	sizeof(struct des_ctx),
961 	.cra_module		=	THIS_MODULE,
962 	.cra_alignmask		=	3,
963 	.cra_u			=	{ .cipher = {
964 	.cia_min_keysize	=	DES_KEY_SIZE,
965 	.cia_max_keysize	=	DES_KEY_SIZE,
966 	.cia_setkey		=	des_setkey,
967 	.cia_encrypt		=	des_encrypt,
968 	.cia_decrypt		=	des_decrypt } }
969 }, {
970 	.cra_name		=	"des3_ede",
971 	.cra_driver_name	=	"des3_ede-generic",
972 	.cra_priority		=	100,
973 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
974 	.cra_blocksize		=	DES3_EDE_BLOCK_SIZE,
975 	.cra_ctxsize		=	sizeof(struct des3_ede_ctx),
976 	.cra_module		=	THIS_MODULE,
977 	.cra_alignmask		=	3,
978 	.cra_u			=	{ .cipher = {
979 	.cia_min_keysize	=	DES3_EDE_KEY_SIZE,
980 	.cia_max_keysize	=	DES3_EDE_KEY_SIZE,
981 	.cia_setkey		=	des3_ede_setkey,
982 	.cia_encrypt		=	des3_ede_encrypt,
983 	.cia_decrypt		=	des3_ede_decrypt } }
984 } };
985 
986 static int __init des_generic_mod_init(void)
987 {
988 	return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs));
989 }
990 
991 static void __exit des_generic_mod_fini(void)
992 {
993 	crypto_unregister_algs(des_algs, ARRAY_SIZE(des_algs));
994 }
995 
996 module_init(des_generic_mod_init);
997 module_exit(des_generic_mod_fini);
998 
999 MODULE_LICENSE("GPL");
1000 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
1001 MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");
1002 MODULE_ALIAS_CRYPTO("des");
1003 MODULE_ALIAS_CRYPTO("des-generic");
1004 MODULE_ALIAS_CRYPTO("des3_ede");
1005 MODULE_ALIAS_CRYPTO("des3_ede-generic");
1006