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 ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
40 (((unsigned long) (x) & 0xFFFFFFFFUL) >> \
41 (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
42 #define RORc(x, y) \
43 (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \
44 (unsigned long) ((y) & 31)) | \
45 ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \
46 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
cookey(const u32 * raw1,u32 * keyout)249 static void cookey(const u32 *raw1, u32 *keyout)
250 {
251 u32 *cook;
252 const u32 *raw0;
253 u32 dough[32];
254 int i;
255
256 cook = dough;
257 for (i = 0; i < 16; i++, raw1++) {
258 raw0 = raw1++;
259 *cook = (*raw0 & 0x00fc0000L) << 6;
260 *cook |= (*raw0 & 0x00000fc0L) << 10;
261 *cook |= (*raw1 & 0x00fc0000L) >> 10;
262 *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
263 *cook = (*raw0 & 0x0003f000L) << 12;
264 *cook |= (*raw0 & 0x0000003fL) << 16;
265 *cook |= (*raw1 & 0x0003f000L) >> 4;
266 *cook++ |= (*raw1 & 0x0000003fL);
267 }
268
269 os_memcpy(keyout, dough, sizeof(dough));
270 }
271
272
deskey(const u8 * key,int decrypt,u32 * keyout)273 static void deskey(const u8 *key, int decrypt, u32 *keyout)
274 {
275 u32 i, j, l, m, n, kn[32];
276 u8 pc1m[56], pcr[56];
277
278 for (j = 0; j < 56; j++) {
279 l = (u32) pc1[j];
280 m = l & 7;
281 pc1m[j] = (u8)
282 ((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0);
283 }
284
285 for (i = 0; i < 16; i++) {
286 if (decrypt)
287 m = (15 - i) << 1;
288 else
289 m = i << 1;
290 n = m + 1;
291 kn[m] = kn[n] = 0L;
292 for (j = 0; j < 28; j++) {
293 l = j + (u32) totrot[i];
294 if (l < 28)
295 pcr[j] = pc1m[l];
296 else
297 pcr[j] = pc1m[l - 28];
298 }
299 for (/* j = 28 */; j < 56; j++) {
300 l = j + (u32) totrot[i];
301 if (l < 56)
302 pcr[j] = pc1m[l];
303 else
304 pcr[j] = pc1m[l - 28];
305 }
306 for (j = 0; j < 24; j++) {
307 if ((int) pcr[(int) pc2[j]] != 0)
308 kn[m] |= bigbyte[j];
309 if ((int) pcr[(int) pc2[j + 24]] != 0)
310 kn[n] |= bigbyte[j];
311 }
312 }
313
314 cookey(kn, keyout);
315 }
316
317
desfunc(u32 * block,const u32 * keys)318 static void desfunc(u32 *block, const u32 *keys)
319 {
320 u32 work, right, leftt;
321 int cur_round;
322
323 leftt = block[0];
324 right = block[1];
325
326 work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
327 right ^= work;
328 leftt ^= (work << 4);
329
330 work = ((leftt >> 16) ^ right) & 0x0000ffffL;
331 right ^= work;
332 leftt ^= (work << 16);
333
334 work = ((right >> 2) ^ leftt) & 0x33333333L;
335 leftt ^= work;
336 right ^= (work << 2);
337
338 work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
339 leftt ^= work;
340 right ^= (work << 8);
341
342 right = ROLc(right, 1);
343 work = (leftt ^ right) & 0xaaaaaaaaL;
344
345 leftt ^= work;
346 right ^= work;
347 leftt = ROLc(leftt, 1);
348
349 for (cur_round = 0; cur_round < 8; cur_round++) {
350 work = RORc(right, 4) ^ *keys++;
351 leftt ^= SP7[work & 0x3fL]
352 ^ SP5[(work >> 8) & 0x3fL]
353 ^ SP3[(work >> 16) & 0x3fL]
354 ^ SP1[(work >> 24) & 0x3fL];
355 work = right ^ *keys++;
356 leftt ^= SP8[ work & 0x3fL]
357 ^ SP6[(work >> 8) & 0x3fL]
358 ^ SP4[(work >> 16) & 0x3fL]
359 ^ SP2[(work >> 24) & 0x3fL];
360
361 work = RORc(leftt, 4) ^ *keys++;
362 right ^= SP7[ work & 0x3fL]
363 ^ SP5[(work >> 8) & 0x3fL]
364 ^ SP3[(work >> 16) & 0x3fL]
365 ^ SP1[(work >> 24) & 0x3fL];
366 work = leftt ^ *keys++;
367 right ^= SP8[ work & 0x3fL]
368 ^ SP6[(work >> 8) & 0x3fL]
369 ^ SP4[(work >> 16) & 0x3fL]
370 ^ SP2[(work >> 24) & 0x3fL];
371 }
372
373 right = RORc(right, 1);
374 work = (leftt ^ right) & 0xaaaaaaaaL;
375 leftt ^= work;
376 right ^= work;
377 leftt = RORc(leftt, 1);
378 work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
379 right ^= work;
380 leftt ^= (work << 8);
381 /* -- */
382 work = ((leftt >> 2) ^ right) & 0x33333333L;
383 right ^= work;
384 leftt ^= (work << 2);
385 work = ((right >> 16) ^ leftt) & 0x0000ffffL;
386 leftt ^= work;
387 right ^= (work << 16);
388 work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
389 leftt ^= work;
390 right ^= (work << 4);
391
392 block[0] = right;
393 block[1] = leftt;
394 }
395
396
397 /* wpa_supplicant/hostapd specific wrapper */
398
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)399 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
400 {
401 u8 pkey[8], next, tmp;
402 int i;
403 u32 ek[32], work[2];
404
405 /* Add parity bits to the key */
406 next = 0;
407 for (i = 0; i < 7; i++) {
408 tmp = key[i];
409 pkey[i] = (tmp >> i) | next | 1;
410 next = tmp << (7 - i);
411 }
412 pkey[i] = next | 1;
413
414 deskey(pkey, 0, ek);
415
416 work[0] = WPA_GET_BE32(clear);
417 work[1] = WPA_GET_BE32(clear + 4);
418 desfunc(work, ek);
419 WPA_PUT_BE32(cypher, work[0]);
420 WPA_PUT_BE32(cypher + 4, work[1]);
421
422 os_memset(pkey, 0, sizeof(pkey));
423 os_memset(ek, 0, sizeof(ek));
424 return 0;
425 }
426
427
des_key_setup(const u8 * key,u32 * ek,u32 * dk)428 void des_key_setup(const u8 *key, u32 *ek, u32 *dk)
429 {
430 deskey(key, 0, ek);
431 deskey(key, 1, dk);
432 }
433
434
des_block_encrypt(const u8 * plain,const u32 * ek,u8 * crypt)435 void des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt)
436 {
437 u32 work[2];
438 work[0] = WPA_GET_BE32(plain);
439 work[1] = WPA_GET_BE32(plain + 4);
440 desfunc(work, ek);
441 WPA_PUT_BE32(crypt, work[0]);
442 WPA_PUT_BE32(crypt + 4, work[1]);
443 }
444
445
des_block_decrypt(const u8 * crypt,const u32 * dk,u8 * plain)446 void des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain)
447 {
448 u32 work[2];
449 work[0] = WPA_GET_BE32(crypt);
450 work[1] = WPA_GET_BE32(crypt + 4);
451 desfunc(work, dk);
452 WPA_PUT_BE32(plain, work[0]);
453 WPA_PUT_BE32(plain + 4, work[1]);
454 }
455
456
des3_key_setup(const u8 * key,struct des3_key_s * dkey)457 void des3_key_setup(const u8 *key, struct des3_key_s *dkey)
458 {
459 deskey(key, 0, dkey->ek[0]);
460 deskey(key + 8, 1, dkey->ek[1]);
461 deskey(key + 16, 0, dkey->ek[2]);
462
463 deskey(key, 1, dkey->dk[2]);
464 deskey(key + 8, 0, dkey->dk[1]);
465 deskey(key + 16, 1, dkey->dk[0]);
466 }
467
468
des3_encrypt(const u8 * plain,const struct des3_key_s * key,u8 * crypt)469 void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt)
470 {
471 u32 work[2];
472
473 work[0] = WPA_GET_BE32(plain);
474 work[1] = WPA_GET_BE32(plain + 4);
475 desfunc(work, key->ek[0]);
476 desfunc(work, key->ek[1]);
477 desfunc(work, key->ek[2]);
478 WPA_PUT_BE32(crypt, work[0]);
479 WPA_PUT_BE32(crypt + 4, work[1]);
480 }
481
482
des3_decrypt(const u8 * crypt,const struct des3_key_s * key,u8 * plain)483 void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain)
484 {
485 u32 work[2];
486
487 work[0] = WPA_GET_BE32(crypt);
488 work[1] = WPA_GET_BE32(crypt + 4);
489 desfunc(work, key->dk[0]);
490 desfunc(work, key->dk[1]);
491 desfunc(work, key->dk[2]);
492 WPA_PUT_BE32(plain, work[0]);
493 WPA_PUT_BE32(plain + 4, work[1]);
494 }
495