blob: ef5bb8822abae437a9237f1fb7bb81dd327800cd [file] [log] [blame]
Ard Biesheuvel04007b02019-08-15 12:01:09 +03001// 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
30static 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
65static 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
100static 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
362static 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
381static 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
400static 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
419static 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
438static 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
457static 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
476static 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
495static 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 */
623static 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
699int 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}
706EXPORT_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 */
714static 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
781void 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}
800EXPORT_SYMBOL_GPL(des_encrypt);
801
802void 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}
821EXPORT_SYMBOL_GPL(des_decrypt);
822
823int 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}
842EXPORT_SYMBOL_GPL(des3_ede_expand_key);
843
844void 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}
871EXPORT_SYMBOL_GPL(des3_ede_encrypt);
872
873void 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}
900EXPORT_SYMBOL_GPL(des3_ede_decrypt);
901
902MODULE_LICENSE("GPL");