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