Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
des_generic.c
Go to the documentation of this file.
1 /*
2  * Cryptographic API.
3  *
4  * DES & Triple DES EDE Cipher Algorithms.
5  *
6  * Copyright (c) 2005 Dag Arne Osvik <[email protected]>
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 
28 struct des_ctx {
30 };
31 
32 struct des3_ede_ctx {
34 };
35 
36 /* Lookup tables for key expansion */
37 
38 static 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 
73 static 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 
108 static 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 
370 static 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 
389 static 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 
408 static 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 
427 static 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 
446 static 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 
465 static 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 
484 static 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 
503 static 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 DES_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  */
631 unsigned 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] = DES_PC2(a, b, c, d); d = rs[d];
643  pe[14 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
644  pe[13 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
645  pe[12 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
646  pe[11 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
647  pe[10 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
648  pe[ 9 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
649  pe[ 8 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c];
650  pe[ 7 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
651  pe[ 6 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
652  pe[ 5 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
653  pe[ 4 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
654  pe[ 3 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
655  pe[ 2 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
656  pe[ 1 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b];
657  pe[ 0 * 2 + 0] = DES_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] = DES_PC2(a, b, c, d); d = rs[d];
674  pe[14 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
675  pe[13 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
676  pe[12 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
677  pe[11 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
678  pe[10 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
679  pe[ 9 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
680  pe[ 8 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c];
681  pe[ 7 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
682  pe[ 6 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
683  pe[ 5 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
684  pe[ 4 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
685  pe[ 3 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
686  pe[ 2 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
687  pe[ 1 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b];
688  pe[ 0 * 2 + 1] = DES_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 }
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 static 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;
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 
803 static 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 
826 static 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  */
862 static 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 
884 static 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 
915 static 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 
946 static struct crypto_alg des_algs[2] = { {
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_u = { .cipher = {
954  .cia_min_keysize = DES_KEY_SIZE,
955  .cia_max_keysize = DES_KEY_SIZE,
956  .cia_setkey = des_setkey,
957  .cia_encrypt = des_encrypt,
958  .cia_decrypt = des_decrypt } }
959 }, {
960  .cra_name = "des3_ede",
961  .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
962  .cra_blocksize = DES3_EDE_BLOCK_SIZE,
963  .cra_ctxsize = sizeof(struct des3_ede_ctx),
964  .cra_module = THIS_MODULE,
965  .cra_alignmask = 3,
966  .cra_u = { .cipher = {
967  .cia_min_keysize = DES3_EDE_KEY_SIZE,
968  .cia_max_keysize = DES3_EDE_KEY_SIZE,
969  .cia_setkey = des3_ede_setkey,
970  .cia_encrypt = des3_ede_encrypt,
971  .cia_decrypt = des3_ede_decrypt } }
972 } };
973 
974 MODULE_ALIAS("des3_ede");
975 
976 static int __init des_generic_mod_init(void)
977 {
978  return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs));
979 }
980 
981 static void __exit des_generic_mod_fini(void)
982 {
983  crypto_unregister_algs(des_algs, ARRAY_SIZE(des_algs));
984 }
985 
986 module_init(des_generic_mod_init);
987 module_exit(des_generic_mod_fini);
988 
989 MODULE_LICENSE("GPL");
990 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
991 MODULE_AUTHOR("Dag Arne Osvik <[email protected]>");
992 MODULE_ALIAS("des");