Root/crypto/des_generic.c

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 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 */
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] = 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}
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] = 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
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

Archive Download this file



interactive