Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-microblaze.git] / lib / crypto / des.c
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");