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