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