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