• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 unsigned char 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 unsigned char 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 //STKIPKeyManagement  sTKIPKeyTable[MAX_TKIP_KEY];
129 
130 /*---------------------  Static Functions  --------------------------*/
131 unsigned int tkip_sbox(unsigned int index);
132 unsigned int rotr1(unsigned int a);
133 
134 /*---------------------  Export Variables  --------------------------*/
135 
136 /************************************************************/
137 /* tkip_sbox()                                              */
138 /* Returns a 16 bit value from a 64K entry table. The Table */
139 /* is synthesized from two 256 entry byte wide tables.      */
140 /************************************************************/
tkip_sbox(unsigned int index)141 unsigned int tkip_sbox(unsigned int index)
142 {
143 	unsigned int index_low;
144 	unsigned int index_high;
145 	unsigned int left, right;
146 
147 	index_low = (index % 256);
148 	index_high = ((index >> 8) % 256);
149 
150 	left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256);
151 	right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256);
152 
153 	return left ^ right;
154 };
155 
rotr1(unsigned int a)156 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  * Description: Calculate RC4Key fom TK, TA, and TSC
171  *
172  * Parameters:
173  *  In:
174  *      pbyTKey         - TKey
175  *      pbyTA           - TA
176  *      dwTSC           - TSC
177  *  Out:
178  *      pbyRC4Key       - RC4Key
179  *
180  * Return Value: none
181  *
182  */
TKIPvMixKey(unsigned char * pbyTKey,unsigned char * pbyTA,unsigned short wTSC15_0,unsigned long dwTSC47_16,unsigned char * pbyRC4Key)183 void TKIPvMixKey(
184 	unsigned char *pbyTKey,
185 	unsigned char *pbyTA,
186 	unsigned short wTSC15_0,
187 	unsigned long dwTSC47_16,
188 	unsigned char *pbyRC4Key
189 )
190 {
191 	unsigned int p1k[5];
192 //    unsigned int ttak0, ttak1, ttak2, ttak3, ttak4;
193 	unsigned int tsc0, tsc1, tsc2;
194 	unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
195 	unsigned long int pnl, pnh;
196 
197 	int i, j;
198 
199 	pnl = wTSC15_0;
200 	pnh = dwTSC47_16;
201 
202 	tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
203 	tsc1 = (unsigned int)(pnh % 65536);
204 	tsc2 = (unsigned int)(pnl % 65536); /* lsb */
205 
206 	/* Phase 1, step 1 */
207 	p1k[0] = tsc1;
208 	p1k[1] = tsc0;
209 	p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256));
210 	p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256));
211 	p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256));
212 
213 	/* Phase 1, step 2 */
214 	for (i = 0; i < 8; i++) {
215 		j = 2 * (i & 1);
216 		p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536;
217 		p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536;
218 		p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536;
219 		p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536;
220 		p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536;
221 		p1k[4] = (p1k[4] + i) % 65536;
222 	}
223 	/* Phase 2, Step 1 */
224 	ppk0 = p1k[0];
225 	ppk1 = p1k[1];
226 	ppk2 = p1k[2];
227 	ppk3 = p1k[3];
228 	ppk4 = p1k[4];
229 	ppk5 = (p1k[4] + tsc2) % 65536;
230 
231 	/* Phase2, Step 2 */
232 	ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536);
233 	ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536);
234 	ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536);
235 	ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536);
236 	ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536);
237 	ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536);
238 
239 	ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12]));
240 	ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14]));
241 	ppk2 = ppk2 + rotr1(ppk1);
242 	ppk3 = ppk3 + rotr1(ppk2);
243 	ppk4 = ppk4 + rotr1(ppk3);
244 	ppk5 = ppk5 + rotr1(ppk4);
245 
246 	/* Phase 2, Step 3 */
247 	pbyRC4Key[0] = (tsc2 >> 8) % 256;
248 	pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
249 	pbyRC4Key[2] = tsc2 % 256;
250 	pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256;
251 
252 	pbyRC4Key[4] = ppk0 % 256;
253 	pbyRC4Key[5] = (ppk0 >> 8) % 256;
254 
255 	pbyRC4Key[6] = ppk1 % 256;
256 	pbyRC4Key[7] = (ppk1 >> 8) % 256;
257 
258 	pbyRC4Key[8] = ppk2 % 256;
259 	pbyRC4Key[9] = (ppk2 >> 8) % 256;
260 
261 	pbyRC4Key[10] = ppk3 % 256;
262 	pbyRC4Key[11] = (ppk3 >> 8) % 256;
263 
264 	pbyRC4Key[12] = ppk4 % 256;
265 	pbyRC4Key[13] = (ppk4 >> 8) % 256;
266 
267 	pbyRC4Key[14] = ppk5 % 256;
268 	pbyRC4Key[15] = (ppk5 >> 8) % 256;
269 }
270