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