blob: 42912948776b1426ec71f2e6fe3d5debd3d67e72 [file] [log] [blame]
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * Cryptographic API.
3 *
4 * DES & Triple DES EDE Cipher Algorithms.
5 *
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -07006 * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
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 */
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -070014
Herbert Xu06ace7a2005-10-30 21:25:15 +110015#include <asm/byteorder.h>
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -070016#include <linux/bitops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <linux/init.h>
18#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/errno.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/crypto.h>
Herbert Xu06ace7a2005-10-30 21:25:15 +110021#include <linux/types.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022
Evgeniy Polyakov16d004a2007-10-11 19:48:58 +080023#include <crypto/des.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -070025#define ROL(x, r) ((x) = rol32((x), (r)))
26#define ROR(x, r) ((x) = ror32((x), (r)))
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
28struct des_ctx {
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 u32 expkey[DES_EXPKEY_WORDS];
30};
31
32struct des3_ede_ctx {
Linus Torvalds1da177e2005-04-16 15:20:36 -070033 u32 expkey[DES3_EDE_EXPKEY_WORDS];
34};
35
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -070036/* Lookup tables for key expansion */
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -070038static 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070071};
72
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -070073static 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106};
107
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700108static 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366};
367
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700368/* S-box lookup tables */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700370static 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
David Howellsdb36b902010-10-07 14:08:50 +0100617#define DES_PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a))
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700618
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 */
Evgeniy Polyakovc3041f92007-10-11 19:58:16 +0800631unsigned long des_ekey(u32 *pe, const u8 *k)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632{
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700633 /* K&R: long is at least 32 bits */
634 unsigned long a, b, c, d, w;
635 const u32 *pt = pc2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700637 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
David Howellsdb36b902010-10-07 14:08:50 +0100642 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);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700658
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
David Howellsdb36b902010-10-07 14:08:50 +0100673 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);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700689
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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705}
Evgeniy Polyakovc3041f92007-10-11 19:58:16 +0800706EXPORT_SYMBOL_GPL(des_ekey);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707
708/*
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700709 * Decryption key expansion
710 *
711 * No weak key checking is performed, as this is only used by triple DES
712 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 */
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700714static void dkey(u32 *pe, const u8 *k)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715{
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700716 /* K&R: long is at least 32 bits */
717 unsigned long a, b, c, d;
718 const u32 *pt = pc2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700720 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
David Howellsdb36b902010-10-07 14:08:50 +0100725 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);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700741
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
David Howellsdb36b902010-10-07 14:08:50 +0100750 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);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700766
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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779}
780
Herbert Xu6c2bb982006-05-16 22:09:29 +1000781static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
Herbert Xu560c06a2006-08-13 14:16:39 +1000782 unsigned int keylen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000784 struct des_ctx *dctx = crypto_tfm_ctx(tfm);
Herbert Xu560c06a2006-08-13 14:16:39 +1000785 u32 *flags = &tfm->crt_flags;
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700786 u32 tmp[DES_EXPKEY_WORDS];
787 int ret;
788
789 /* Expand to tmp */
Evgeniy Polyakovc3041f92007-10-11 19:58:16 +0800790 ret = des_ekey(tmp, key);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700791
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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801}
802
Herbert Xu6c2bb982006-05-16 22:09:29 +1000803static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000805 struct des_ctx *ctx = crypto_tfm_ctx(tfm);
806 const u32 *K = ctx->expkey;
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700807 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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824}
825
Herbert Xu6c2bb982006-05-16 22:09:29 +1000826static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000828 struct des_ctx *ctx = crypto_tfm_ctx(tfm);
829 const u32 *K = ctx->expkey + DES_EXPKEY_WORDS - 2;
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700830 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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847}
848
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700849/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 * 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 */
Jussi Kivilinna6574e6c2014-06-09 20:59:54 +0300862int __des3_ede_setkey(u32 *expkey, u32 *flags, const u8 *key,
863 unsigned int keylen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864{
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700865 const u32 *K = (const u32 *)key;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700867 if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
Jarod Wilsonad79cdd2008-12-17 16:51:13 +1100868 !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
Richard Hartmanna5011212010-02-16 20:32:31 +0800869 (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
Jarod Wilsonad79cdd2008-12-17 16:51:13 +1100870 *flags |= CRYPTO_TFM_RES_WEAK_KEY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 return -EINVAL;
872 }
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700873
Evgeniy Polyakovc3041f92007-10-11 19:58:16 +0800874 des_ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700875 dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
Evgeniy Polyakovc3041f92007-10-11 19:58:16 +0800876 des_ekey(expkey, key);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700877
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 return 0;
879}
Jussi Kivilinna6574e6c2014-06-09 20:59:54 +0300880EXPORT_SYMBOL_GPL(__des3_ede_setkey);
881
882static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
883 unsigned int keylen)
884{
885 struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
886 u32 *flags = &tfm->crt_flags;
887 u32 *expkey = dctx->expkey;
888
889 return __des3_ede_setkey(expkey, flags, key, keylen);
890}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
Herbert Xu6c2bb982006-05-16 22:09:29 +1000892static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000894 struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700895 const u32 *K = dctx->expkey;
896 const __le32 *s = (const __le32 *)src;
897 __le32 *d = (__le32 *)dst;
898 u32 L, R, A, B;
899 int i;
900
901 L = le32_to_cpu(s[0]);
902 R = le32_to_cpu(s[1]);
903
904 IP(L, R, A);
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 for (i = 0; i < 8; i++) {
910 ROUND(R, L, A, B, K, 2);
911 ROUND(L, R, A, B, K, 2);
912 }
913 for (i = 0; i < 8; i++) {
914 ROUND(L, R, A, B, K, 2);
915 ROUND(R, L, A, B, K, 2);
916 }
917 FP(R, L, A);
918
919 d[0] = cpu_to_le32(R);
920 d[1] = cpu_to_le32(L);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921}
922
Herbert Xu6c2bb982006-05-16 22:09:29 +1000923static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000925 struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700926 const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
927 const __le32 *s = (const __le32 *)src;
928 __le32 *d = (__le32 *)dst;
929 u32 L, R, A, B;
930 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700932 L = le32_to_cpu(s[0]);
933 R = le32_to_cpu(s[1]);
934
935 IP(L, R, A);
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 for (i = 0; i < 8; i++) {
941 ROUND(R, L, A, B, K, -2);
942 ROUND(L, R, A, B, K, -2);
943 }
944 for (i = 0; i < 8; i++) {
945 ROUND(L, R, A, B, K, -2);
946 ROUND(R, L, A, B, K, -2);
947 }
948 FP(R, L, A);
949
950 d[0] = cpu_to_le32(R);
951 d[1] = cpu_to_le32(L);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952}
953
Jussi Kivilinna9935e6d2012-07-11 14:20:05 +0300954static struct crypto_alg des_algs[2] = { {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 .cra_name = "des",
Jussi Kivilinna6574e6c2014-06-09 20:59:54 +0300956 .cra_driver_name = "des-generic",
957 .cra_priority = 100,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
959 .cra_blocksize = DES_BLOCK_SIZE,
960 .cra_ctxsize = sizeof(struct des_ctx),
961 .cra_module = THIS_MODULE,
Herbert Xua429d262006-01-07 16:38:15 +1100962 .cra_alignmask = 3,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 .cra_u = { .cipher = {
964 .cia_min_keysize = DES_KEY_SIZE,
965 .cia_max_keysize = DES_KEY_SIZE,
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700966 .cia_setkey = des_setkey,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 .cia_encrypt = des_encrypt,
968 .cia_decrypt = des_decrypt } }
Jussi Kivilinna9935e6d2012-07-11 14:20:05 +0300969}, {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 .cra_name = "des3_ede",
Jussi Kivilinna6574e6c2014-06-09 20:59:54 +0300971 .cra_driver_name = "des3_ede-generic",
972 .cra_priority = 100,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
974 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
975 .cra_ctxsize = sizeof(struct des3_ede_ctx),
976 .cra_module = THIS_MODULE,
Atsushi Nemoto20ea3402006-03-13 21:30:29 +1100977 .cra_alignmask = 3,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 .cra_u = { .cipher = {
979 .cia_min_keysize = DES3_EDE_KEY_SIZE,
980 .cia_max_keysize = DES3_EDE_KEY_SIZE,
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -0700981 .cia_setkey = des3_ede_setkey,
982 .cia_encrypt = des3_ede_encrypt,
983 .cia_decrypt = des3_ede_decrypt } }
Jussi Kivilinna9935e6d2012-07-11 14:20:05 +0300984} };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
Kees Cook5d26a102014-11-20 17:05:53 -0800986MODULE_ALIAS_CRYPTO("des3_ede");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Kamalesh Babulal3af5b902008-04-05 21:00:57 +0800988static int __init des_generic_mod_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989{
Jussi Kivilinna9935e6d2012-07-11 14:20:05 +0300990 return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991}
992
Kamalesh Babulal3af5b902008-04-05 21:00:57 +0800993static void __exit des_generic_mod_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994{
Jussi Kivilinna9935e6d2012-07-11 14:20:05 +0300995 crypto_unregister_algs(des_algs, ARRAY_SIZE(des_algs));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996}
997
Kamalesh Babulal3af5b902008-04-05 21:00:57 +0800998module_init(des_generic_mod_init);
999module_exit(des_generic_mod_fini);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000
1001MODULE_LICENSE("GPL");
1002MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
Dag Arne Osvike1d5dea2005-07-06 13:55:44 -07001003MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");
Sebastian Siewiorc5a511f2007-10-05 16:42:03 +08001004MODULE_ALIAS("des");