1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *
20  * File: tkip.c
21  *
22  * Purpose: Implement functions for 802.11i TKIP
23  *
24  * Author: Jerry Chen
25  *
26  * Date: Mar. 11, 2003
27  *
28  * Functions:
29  *      TKIPvMixKey - Get TKIP RC4 Key from TK,TA, and TSC
30  *
31  * Revision History:
32  *
33  */
34 
35 #include "tmacro.h"
36 #include "tkip.h"
37 
38 /*---------------------  Static Definitions -------------------------*/
39 
40 /*---------------------  Static Classes  ----------------------------*/
41 
42 /*---------------------  Static Variables  --------------------------*/
43 
44 /*---------------------  Static Functions  --------------------------*/
45 
46 /*---------------------  Export Variables  --------------------------*/
47 
48 /*---------------------  Static Definitions -------------------------*/
49 
50 /*---------------------  Static Classes  ----------------------------*/
51 
52 /*---------------------  Static Variables  --------------------------*/
53 
54 /* The Sbox is reduced to 2 16-bit wide tables, each with 256 entries. */
55 /* The 2nd table is the same as the 1st but with the upper and lower   */
56 /* bytes swapped. To allow an endian tolerant implementation, the byte */
57 /* halves have been expressed independently here.                      */
58 const BYTE TKIP_Sbox_Lower[256] = {
59     0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
60     0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
61     0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
62     0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
63     0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
64     0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
65     0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
66     0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
67     0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
68     0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
69     0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
70     0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
71     0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
72     0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
73     0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
74     0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
75     0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
76     0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
77     0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
78     0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
79     0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
80     0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
81     0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
82     0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
83     0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
84     0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
85     0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
86     0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
87     0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
88     0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
89     0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
90     0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
91 };
92 
93 const BYTE TKIP_Sbox_Upper[256] = {
94     0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
95     0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
96     0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
97     0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
98     0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
99     0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
100     0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
101     0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
102     0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
103     0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
104     0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
105     0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
106     0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
107     0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
108     0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
109     0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
110     0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
111     0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
112     0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
113     0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
114     0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
115     0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
116     0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
117     0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
118     0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
119     0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
120     0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
121     0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
122     0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
123     0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
124     0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
125     0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
126 };
127 
128 
129 //STKIPKeyManagement  sTKIPKeyTable[MAX_TKIP_KEY];
130 
131 /*---------------------  Static Functions  --------------------------*/
132 
133 /*---------------------  Export Variables  --------------------------*/
134 
135 /************************************************************/
136 /* tkip_sbox()                                              */
137 /* Returns a 16 bit value from a 64K entry table. The Table */
138 /* is synthesized from two 256 entry byte wide tables.      */
139 /************************************************************/
tkip_sbox(unsigned int index)140 static unsigned int tkip_sbox(unsigned int index)
141 {
142     unsigned int index_low;
143     unsigned int index_high;
144     unsigned int left, right;
145 
146     index_low = (index % 256);
147     index_high = ((index >> 8) % 256);
148 
149     left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256);
150     right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256);
151 
152     return (left ^ right);
153 };
154 
155 
rotr1(unsigned int a)156 static unsigned int rotr1(unsigned int a)
157 {
158     unsigned int b;
159 
160     if ((a & 0x01) == 0x01) {
161         b = (a >> 1) | 0x8000;
162     } else {
163         b = (a >> 1) & 0x7fff;
164     }
165     b = b % 65536;
166     return b;
167 }
168 
169 
170 /*
171  * Description: Caculate RC4Key fom TK, TA, and TSC
172  *
173  * Parameters:
174  *  In:
175  *      pbyTKey         - TKey
176  *      pbyTA           - TA
177  *      dwTSC           - TSC
178  *  Out:
179  *      pbyRC4Key       - RC4Key
180  *
181  * Return Value: none
182  *
183  */
TKIPvMixKey(PBYTE pbyTKey,PBYTE pbyTA,WORD wTSC15_0,DWORD dwTSC47_16,PBYTE pbyRC4Key)184 void TKIPvMixKey(
185     PBYTE   pbyTKey,
186     PBYTE   pbyTA,
187     WORD    wTSC15_0,
188     DWORD   dwTSC47_16,
189     PBYTE   pbyRC4Key
190     )
191 {
192     unsigned int p1k[5];
193 //    unsigned int ttak0, ttak1, ttak2, ttak3, ttak4;
194     unsigned int tsc0, tsc1, tsc2;
195     unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
196     unsigned long int pnl,pnh;
197 
198     int i, j;
199 
200     pnl = wTSC15_0;
201     pnh = dwTSC47_16;
202 
203     tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
204     tsc1 = (unsigned int)(pnh % 65536);
205     tsc2 = (unsigned int)(pnl % 65536); /* lsb */
206 
207     /* Phase 1, step 1 */
208     p1k[0] = tsc1;
209     p1k[1] = tsc0;
210     p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256));
211     p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256));
212     p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256));
213 
214     /* Phase 1, step 2 */
215     for (i=0; i<8; i++) {
216         j = 2*(i & 1);
217         p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536;
218         p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536;
219         p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536;
220         p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536;
221         p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536;
222         p1k[4] = (p1k[4] + i) % 65536;
223     }
224 
225     /* Phase 2, Step 1 */
226     ppk0 = p1k[0];
227     ppk1 = p1k[1];
228     ppk2 = p1k[2];
229     ppk3 = p1k[3];
230     ppk4 = p1k[4];
231     ppk5 = (p1k[4] + tsc2) % 65536;
232 
233     /* Phase2, Step 2 */
234 	ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536);
235 	ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536);
236 	ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536);
237 	ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536);
238 	ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536);
239 	ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536);
240 
241 	ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12]));
242 	ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14]));
243 	ppk2 = ppk2 + rotr1(ppk1);
244 	ppk3 = ppk3 + rotr1(ppk2);
245 	ppk4 = ppk4 + rotr1(ppk3);
246 	ppk5 = ppk5 + rotr1(ppk4);
247 
248     /* Phase 2, Step 3 */
249     pbyRC4Key[0] = (tsc2 >> 8) % 256;
250     pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
251     pbyRC4Key[2] = tsc2 % 256;
252     pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256;
253 
254     pbyRC4Key[4] = ppk0 % 256;
255     pbyRC4Key[5] = (ppk0 >> 8) % 256;
256 
257     pbyRC4Key[6] = ppk1 % 256;
258     pbyRC4Key[7] = (ppk1 >> 8) % 256;
259 
260     pbyRC4Key[8] = ppk2 % 256;
261     pbyRC4Key[9] = (ppk2 >> 8) % 256;
262 
263     pbyRC4Key[10] = ppk3 % 256;
264     pbyRC4Key[11] = (ppk3 >> 8) % 256;
265 
266     pbyRC4Key[12] = ppk4 % 256;
267     pbyRC4Key[13] = (ppk4 >> 8) % 256;
268 
269     pbyRC4Key[14] = ppk5 % 256;
270     pbyRC4Key[15] = (ppk5 >> 8) % 256;
271 }
272