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