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