/src/hostap/src/crypto/des-internal.c
Line | Count | Source |
1 | | /* |
2 | | * DES and 3DES-EDE ciphers |
3 | | * |
4 | | * Modifications to LibTomCrypt implementation: |
5 | | * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi> |
6 | | * |
7 | | * This software may be distributed under the terms of the BSD license. |
8 | | * See README for more details. |
9 | | */ |
10 | | |
11 | | #include "includes.h" |
12 | | |
13 | | #include "common.h" |
14 | | #include "crypto.h" |
15 | | #include "des_i.h" |
16 | | |
17 | | /* |
18 | | * This implementation is based on a DES implementation included in |
19 | | * LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd |
20 | | * coding style. |
21 | | */ |
22 | | |
23 | | /* LibTomCrypt, modular cryptographic library -- Tom St Denis |
24 | | * |
25 | | * LibTomCrypt is a library that provides various cryptographic |
26 | | * algorithms in a highly modular and flexible manner. |
27 | | * |
28 | | * The library is free for all purposes without any express |
29 | | * guarantee it works. |
30 | | * |
31 | | * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com |
32 | | */ |
33 | | |
34 | | /** |
35 | | DES code submitted by Dobes Vandermeer |
36 | | */ |
37 | | |
38 | | #define ROLc(x, y) \ |
39 | 0 | ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \ |
40 | 0 | (((unsigned long) (x) & 0xFFFFFFFFUL) >> \ |
41 | 0 | (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) |
42 | | #define RORc(x, y) \ |
43 | 0 | (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \ |
44 | 0 | (unsigned long) ((y) & 31)) | \ |
45 | 0 | ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \ |
46 | 0 | 0xFFFFFFFFUL) |
47 | | |
48 | | |
49 | | static const u32 bytebit[8] = |
50 | | { |
51 | | 0200, 0100, 040, 020, 010, 04, 02, 01 |
52 | | }; |
53 | | |
54 | | static const u32 bigbyte[24] = |
55 | | { |
56 | | 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, |
57 | | 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, |
58 | | 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, |
59 | | 0x800UL, 0x400UL, 0x200UL, 0x100UL, |
60 | | 0x80UL, 0x40UL, 0x20UL, 0x10UL, |
61 | | 0x8UL, 0x4UL, 0x2UL, 0x1L |
62 | | }; |
63 | | |
64 | | /* Use the key schedule specific in the standard (ANSI X3.92-1981) */ |
65 | | |
66 | | static const u8 pc1[56] = { |
67 | | 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, |
68 | | 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, |
69 | | 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, |
70 | | 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 |
71 | | }; |
72 | | |
73 | | static const u8 totrot[16] = { |
74 | | 1, 2, 4, 6, |
75 | | 8, 10, 12, 14, |
76 | | 15, 17, 19, 21, |
77 | | 23, 25, 27, 28 |
78 | | }; |
79 | | |
80 | | static const u8 pc2[48] = { |
81 | | 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, |
82 | | 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, |
83 | | 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, |
84 | | 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 |
85 | | }; |
86 | | |
87 | | |
88 | | static const u32 SP1[64] = |
89 | | { |
90 | | 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, |
91 | | 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, |
92 | | 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, |
93 | | 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, |
94 | | 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, |
95 | | 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, |
96 | | 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, |
97 | | 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, |
98 | | 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, |
99 | | 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, |
100 | | 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, |
101 | | 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, |
102 | | 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, |
103 | | 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, |
104 | | 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, |
105 | | 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL |
106 | | }; |
107 | | |
108 | | static const u32 SP2[64] = |
109 | | { |
110 | | 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, |
111 | | 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, |
112 | | 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, |
113 | | 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, |
114 | | 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, |
115 | | 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, |
116 | | 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, |
117 | | 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, |
118 | | 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, |
119 | | 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, |
120 | | 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, |
121 | | 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, |
122 | | 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, |
123 | | 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, |
124 | | 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, |
125 | | 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL |
126 | | }; |
127 | | |
128 | | static const u32 SP3[64] = |
129 | | { |
130 | | 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, |
131 | | 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, |
132 | | 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, |
133 | | 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, |
134 | | 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, |
135 | | 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, |
136 | | 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, |
137 | | 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, |
138 | | 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, |
139 | | 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, |
140 | | 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, |
141 | | 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, |
142 | | 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, |
143 | | 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, |
144 | | 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, |
145 | | 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL |
146 | | }; |
147 | | |
148 | | static const u32 SP4[64] = |
149 | | { |
150 | | 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, |
151 | | 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, |
152 | | 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, |
153 | | 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, |
154 | | 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, |
155 | | 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, |
156 | | 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, |
157 | | 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, |
158 | | 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, |
159 | | 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, |
160 | | 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, |
161 | | 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, |
162 | | 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, |
163 | | 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, |
164 | | 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, |
165 | | 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL |
166 | | }; |
167 | | |
168 | | static const u32 SP5[64] = |
169 | | { |
170 | | 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, |
171 | | 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, |
172 | | 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, |
173 | | 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, |
174 | | 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, |
175 | | 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, |
176 | | 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, |
177 | | 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, |
178 | | 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, |
179 | | 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, |
180 | | 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, |
181 | | 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, |
182 | | 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, |
183 | | 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, |
184 | | 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, |
185 | | 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL |
186 | | }; |
187 | | |
188 | | static const u32 SP6[64] = |
189 | | { |
190 | | 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, |
191 | | 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, |
192 | | 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, |
193 | | 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, |
194 | | 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, |
195 | | 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, |
196 | | 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, |
197 | | 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, |
198 | | 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, |
199 | | 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, |
200 | | 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, |
201 | | 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, |
202 | | 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, |
203 | | 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, |
204 | | 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, |
205 | | 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL |
206 | | }; |
207 | | |
208 | | static const u32 SP7[64] = |
209 | | { |
210 | | 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, |
211 | | 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, |
212 | | 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, |
213 | | 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, |
214 | | 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, |
215 | | 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, |
216 | | 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, |
217 | | 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, |
218 | | 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, |
219 | | 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, |
220 | | 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, |
221 | | 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, |
222 | | 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, |
223 | | 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, |
224 | | 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, |
225 | | 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL |
226 | | }; |
227 | | |
228 | | static const u32 SP8[64] = |
229 | | { |
230 | | 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, |
231 | | 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, |
232 | | 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, |
233 | | 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, |
234 | | 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, |
235 | | 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, |
236 | | 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, |
237 | | 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, |
238 | | 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, |
239 | | 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, |
240 | | 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, |
241 | | 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, |
242 | | 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, |
243 | | 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, |
244 | | 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, |
245 | | 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL |
246 | | }; |
247 | | |
248 | | |
249 | | static void cookey(const u32 *raw1, u32 *keyout) |
250 | 0 | { |
251 | 0 | u32 *cook; |
252 | 0 | const u32 *raw0; |
253 | 0 | u32 dough[32]; |
254 | 0 | int i; |
255 | |
|
256 | 0 | cook = dough; |
257 | 0 | for (i = 0; i < 16; i++, raw1++) { |
258 | 0 | raw0 = raw1++; |
259 | 0 | *cook = (*raw0 & 0x00fc0000L) << 6; |
260 | 0 | *cook |= (*raw0 & 0x00000fc0L) << 10; |
261 | 0 | *cook |= (*raw1 & 0x00fc0000L) >> 10; |
262 | 0 | *cook++ |= (*raw1 & 0x00000fc0L) >> 6; |
263 | 0 | *cook = (*raw0 & 0x0003f000L) << 12; |
264 | 0 | *cook |= (*raw0 & 0x0000003fL) << 16; |
265 | 0 | *cook |= (*raw1 & 0x0003f000L) >> 4; |
266 | 0 | *cook++ |= (*raw1 & 0x0000003fL); |
267 | 0 | } |
268 | |
|
269 | 0 | os_memcpy(keyout, dough, sizeof(dough)); |
270 | 0 | } |
271 | | |
272 | | |
273 | | static void deskey(const u8 *key, int decrypt, u32 *keyout) |
274 | 0 | { |
275 | 0 | u32 i, j, l, m, n, kn[32]; |
276 | 0 | u8 pc1m[56], pcr[56]; |
277 | |
|
278 | 0 | for (j = 0; j < 56; j++) { |
279 | 0 | l = (u32) pc1[j]; |
280 | 0 | m = l & 7; |
281 | 0 | pc1m[j] = (u8) |
282 | 0 | ((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); |
283 | 0 | } |
284 | |
|
285 | 0 | for (i = 0; i < 16; i++) { |
286 | 0 | if (decrypt) |
287 | 0 | m = (15 - i) << 1; |
288 | 0 | else |
289 | 0 | m = i << 1; |
290 | 0 | n = m + 1; |
291 | 0 | kn[m] = kn[n] = 0L; |
292 | 0 | for (j = 0; j < 28; j++) { |
293 | 0 | l = j + (u32) totrot[i]; |
294 | 0 | if (l < 28) |
295 | 0 | pcr[j] = pc1m[l]; |
296 | 0 | else |
297 | 0 | pcr[j] = pc1m[l - 28]; |
298 | 0 | } |
299 | 0 | for (/* j = 28 */; j < 56; j++) { |
300 | 0 | l = j + (u32) totrot[i]; |
301 | 0 | if (l < 56) |
302 | 0 | pcr[j] = pc1m[l]; |
303 | 0 | else |
304 | 0 | pcr[j] = pc1m[l - 28]; |
305 | 0 | } |
306 | 0 | for (j = 0; j < 24; j++) { |
307 | 0 | if ((int) pcr[(int) pc2[j]] != 0) |
308 | 0 | kn[m] |= bigbyte[j]; |
309 | 0 | if ((int) pcr[(int) pc2[j + 24]] != 0) |
310 | 0 | kn[n] |= bigbyte[j]; |
311 | 0 | } |
312 | 0 | } |
313 | |
|
314 | 0 | cookey(kn, keyout); |
315 | 0 | } |
316 | | |
317 | | |
318 | | static void desfunc(u32 *block, const u32 *keys) |
319 | 0 | { |
320 | 0 | u32 work, right, leftt; |
321 | 0 | int cur_round; |
322 | |
|
323 | 0 | leftt = block[0]; |
324 | 0 | right = block[1]; |
325 | |
|
326 | 0 | work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; |
327 | 0 | right ^= work; |
328 | 0 | leftt ^= (work << 4); |
329 | |
|
330 | 0 | work = ((leftt >> 16) ^ right) & 0x0000ffffL; |
331 | 0 | right ^= work; |
332 | 0 | leftt ^= (work << 16); |
333 | |
|
334 | 0 | work = ((right >> 2) ^ leftt) & 0x33333333L; |
335 | 0 | leftt ^= work; |
336 | 0 | right ^= (work << 2); |
337 | |
|
338 | 0 | work = ((right >> 8) ^ leftt) & 0x00ff00ffL; |
339 | 0 | leftt ^= work; |
340 | 0 | right ^= (work << 8); |
341 | |
|
342 | 0 | right = ROLc(right, 1); |
343 | 0 | work = (leftt ^ right) & 0xaaaaaaaaL; |
344 | |
|
345 | 0 | leftt ^= work; |
346 | 0 | right ^= work; |
347 | 0 | leftt = ROLc(leftt, 1); |
348 | |
|
349 | 0 | for (cur_round = 0; cur_round < 8; cur_round++) { |
350 | 0 | work = RORc(right, 4) ^ *keys++; |
351 | 0 | leftt ^= SP7[work & 0x3fL] |
352 | 0 | ^ SP5[(work >> 8) & 0x3fL] |
353 | 0 | ^ SP3[(work >> 16) & 0x3fL] |
354 | 0 | ^ SP1[(work >> 24) & 0x3fL]; |
355 | 0 | work = right ^ *keys++; |
356 | 0 | leftt ^= SP8[ work & 0x3fL] |
357 | 0 | ^ SP6[(work >> 8) & 0x3fL] |
358 | 0 | ^ SP4[(work >> 16) & 0x3fL] |
359 | 0 | ^ SP2[(work >> 24) & 0x3fL]; |
360 | |
|
361 | 0 | work = RORc(leftt, 4) ^ *keys++; |
362 | 0 | right ^= SP7[ work & 0x3fL] |
363 | 0 | ^ SP5[(work >> 8) & 0x3fL] |
364 | 0 | ^ SP3[(work >> 16) & 0x3fL] |
365 | 0 | ^ SP1[(work >> 24) & 0x3fL]; |
366 | 0 | work = leftt ^ *keys++; |
367 | 0 | right ^= SP8[ work & 0x3fL] |
368 | 0 | ^ SP6[(work >> 8) & 0x3fL] |
369 | 0 | ^ SP4[(work >> 16) & 0x3fL] |
370 | 0 | ^ SP2[(work >> 24) & 0x3fL]; |
371 | 0 | } |
372 | |
|
373 | 0 | right = RORc(right, 1); |
374 | 0 | work = (leftt ^ right) & 0xaaaaaaaaL; |
375 | 0 | leftt ^= work; |
376 | 0 | right ^= work; |
377 | 0 | leftt = RORc(leftt, 1); |
378 | 0 | work = ((leftt >> 8) ^ right) & 0x00ff00ffL; |
379 | 0 | right ^= work; |
380 | 0 | leftt ^= (work << 8); |
381 | | /* -- */ |
382 | 0 | work = ((leftt >> 2) ^ right) & 0x33333333L; |
383 | 0 | right ^= work; |
384 | 0 | leftt ^= (work << 2); |
385 | 0 | work = ((right >> 16) ^ leftt) & 0x0000ffffL; |
386 | 0 | leftt ^= work; |
387 | 0 | right ^= (work << 16); |
388 | 0 | work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; |
389 | 0 | leftt ^= work; |
390 | 0 | right ^= (work << 4); |
391 | |
|
392 | 0 | block[0] = right; |
393 | 0 | block[1] = leftt; |
394 | 0 | } |
395 | | |
396 | | |
397 | | /* wpa_supplicant/hostapd specific wrapper */ |
398 | | |
399 | | int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) |
400 | 0 | { |
401 | 0 | u8 pkey[8], next, tmp; |
402 | 0 | int i; |
403 | 0 | u32 ek[32], work[2]; |
404 | | |
405 | | /* Add parity bits to the key */ |
406 | 0 | next = 0; |
407 | 0 | for (i = 0; i < 7; i++) { |
408 | 0 | tmp = key[i]; |
409 | 0 | pkey[i] = (tmp >> i) | next | 1; |
410 | 0 | next = tmp << (7 - i); |
411 | 0 | } |
412 | 0 | pkey[i] = next | 1; |
413 | |
|
414 | 0 | deskey(pkey, 0, ek); |
415 | |
|
416 | 0 | work[0] = WPA_GET_BE32(clear); |
417 | 0 | work[1] = WPA_GET_BE32(clear + 4); |
418 | 0 | desfunc(work, ek); |
419 | 0 | WPA_PUT_BE32(cypher, work[0]); |
420 | 0 | WPA_PUT_BE32(cypher + 4, work[1]); |
421 | |
|
422 | 0 | os_memset(pkey, 0, sizeof(pkey)); |
423 | 0 | os_memset(ek, 0, sizeof(ek)); |
424 | 0 | return 0; |
425 | 0 | } |
426 | | |
427 | | |
428 | | void des_key_setup(const u8 *key, u32 *ek, u32 *dk) |
429 | 0 | { |
430 | 0 | deskey(key, 0, ek); |
431 | 0 | deskey(key, 1, dk); |
432 | 0 | } |
433 | | |
434 | | |
435 | | void des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt) |
436 | 0 | { |
437 | 0 | u32 work[2]; |
438 | 0 | work[0] = WPA_GET_BE32(plain); |
439 | 0 | work[1] = WPA_GET_BE32(plain + 4); |
440 | 0 | desfunc(work, ek); |
441 | 0 | WPA_PUT_BE32(crypt, work[0]); |
442 | 0 | WPA_PUT_BE32(crypt + 4, work[1]); |
443 | 0 | } |
444 | | |
445 | | |
446 | | void des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain) |
447 | 0 | { |
448 | 0 | u32 work[2]; |
449 | 0 | work[0] = WPA_GET_BE32(crypt); |
450 | 0 | work[1] = WPA_GET_BE32(crypt + 4); |
451 | 0 | desfunc(work, dk); |
452 | 0 | WPA_PUT_BE32(plain, work[0]); |
453 | 0 | WPA_PUT_BE32(plain + 4, work[1]); |
454 | 0 | } |
455 | | |
456 | | |
457 | | void des3_key_setup(const u8 *key, struct des3_key_s *dkey) |
458 | 0 | { |
459 | 0 | deskey(key, 0, dkey->ek[0]); |
460 | 0 | deskey(key + 8, 1, dkey->ek[1]); |
461 | 0 | deskey(key + 16, 0, dkey->ek[2]); |
462 | |
|
463 | 0 | deskey(key, 1, dkey->dk[2]); |
464 | 0 | deskey(key + 8, 0, dkey->dk[1]); |
465 | 0 | deskey(key + 16, 1, dkey->dk[0]); |
466 | 0 | } |
467 | | |
468 | | |
469 | | void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt) |
470 | 0 | { |
471 | 0 | u32 work[2]; |
472 | |
|
473 | 0 | work[0] = WPA_GET_BE32(plain); |
474 | 0 | work[1] = WPA_GET_BE32(plain + 4); |
475 | 0 | desfunc(work, key->ek[0]); |
476 | 0 | desfunc(work, key->ek[1]); |
477 | 0 | desfunc(work, key->ek[2]); |
478 | 0 | WPA_PUT_BE32(crypt, work[0]); |
479 | 0 | WPA_PUT_BE32(crypt + 4, work[1]); |
480 | 0 | } |
481 | | |
482 | | |
483 | | void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain) |
484 | 0 | { |
485 | 0 | u32 work[2]; |
486 | |
|
487 | 0 | work[0] = WPA_GET_BE32(crypt); |
488 | 0 | work[1] = WPA_GET_BE32(crypt + 4); |
489 | 0 | desfunc(work, key->dk[0]); |
490 | 0 | desfunc(work, key->dk[1]); |
491 | 0 | desfunc(work, key->dk[2]); |
492 | 0 | WPA_PUT_BE32(plain, work[0]); |
493 | 0 | WPA_PUT_BE32(plain + 4, work[1]); |
494 | 0 | } |