xref: /freebsd/contrib/wpa/src/crypto/des-internal.c (revision 1c05a6ea6b849ff95e539c31adea887c644a6a01)
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 
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 
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 
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 
399 void 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 }
425 
426 
427 void des_key_setup(const u8 *key, u32 *ek, u32 *dk)
428 {
429 	deskey(key, 0, ek);
430 	deskey(key, 1, dk);
431 }
432 
433 
434 void des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt)
435 {
436 	u32 work[2];
437 	work[0] = WPA_GET_BE32(plain);
438 	work[1] = WPA_GET_BE32(plain + 4);
439 	desfunc(work, ek);
440 	WPA_PUT_BE32(crypt, work[0]);
441 	WPA_PUT_BE32(crypt + 4, work[1]);
442 }
443 
444 
445 void des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain)
446 {
447 	u32 work[2];
448 	work[0] = WPA_GET_BE32(crypt);
449 	work[1] = WPA_GET_BE32(crypt + 4);
450 	desfunc(work, dk);
451 	WPA_PUT_BE32(plain, work[0]);
452 	WPA_PUT_BE32(plain + 4, work[1]);
453 }
454 
455 
456 void des3_key_setup(const u8 *key, struct des3_key_s *dkey)
457 {
458 	deskey(key, 0, dkey->ek[0]);
459 	deskey(key + 8, 1, dkey->ek[1]);
460 	deskey(key + 16, 0, dkey->ek[2]);
461 
462 	deskey(key, 1, dkey->dk[2]);
463 	deskey(key + 8, 0, dkey->dk[1]);
464 	deskey(key + 16, 1, dkey->dk[0]);
465 }
466 
467 
468 void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt)
469 {
470 	u32 work[2];
471 
472 	work[0] = WPA_GET_BE32(plain);
473 	work[1] = WPA_GET_BE32(plain + 4);
474 	desfunc(work, key->ek[0]);
475 	desfunc(work, key->ek[1]);
476 	desfunc(work, key->ek[2]);
477 	WPA_PUT_BE32(crypt, work[0]);
478 	WPA_PUT_BE32(crypt + 4, work[1]);
479 }
480 
481 
482 void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain)
483 {
484 	u32 work[2];
485 
486 	work[0] = WPA_GET_BE32(crypt);
487 	work[1] = WPA_GET_BE32(crypt + 4);
488 	desfunc(work, key->dk[0]);
489 	desfunc(work, key->dk[1]);
490 	desfunc(work, key->dk[2]);
491 	WPA_PUT_BE32(plain, work[0]);
492 	WPA_PUT_BE32(plain + 4, work[1]);
493 }
494