blob: 0715636cb9cb1f5cbe1fe8a07c5bf1bf9af7b195 [file] [log] [blame]
Forest Bond92b96792009-06-13 07:38:31 -04001/*
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
Forest Bond92b96792009-06-13 07:38:31 -040035#include "tmacro.h"
Forest Bond92b96792009-06-13 07:38:31 -040036#include "tkip.h"
Forest Bond92b96792009-06-13 07:38:31 -040037
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. */
58const 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
93const 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 --------------------------*/
Forest Bond92b96792009-06-13 07:38:31 -0400132
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/************************************************************/
Otavio Salvadord5006482010-05-21 19:08:14 -0300140static unsigned int tkip_sbox(unsigned int index)
Forest Bond92b96792009-06-13 07:38:31 -0400141{
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
Otavio Salvadord5006482010-05-21 19:08:14 -0300156static unsigned int rotr1(unsigned int a)
Forest Bond92b96792009-06-13 07:38:31 -0400157{
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 */
Andres More8611a292010-05-01 14:25:00 -0300184void TKIPvMixKey(
Forest Bond92b96792009-06-13 07:38:31 -0400185 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);
Ariel Savini99b7bbb2010-10-29 19:19:20 -0300217 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;
Forest Bond92b96792009-06-13 07:38:31 -0400222 p1k[4] = (p1k[4] + i) % 65536;
223 }
Ariel Savini99b7bbb2010-10-29 19:19:20 -0300224
Forest Bond92b96792009-06-13 07:38:31 -0400225 /* 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 */
Ariel Savini99b7bbb2010-10-29 19:19:20 -0300234 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);
Forest Bond92b96792009-06-13 07:38:31 -0400240
Ariel Savini99b7bbb2010-10-29 19:19:20 -0300241 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);
Forest Bond92b96792009-06-13 07:38:31 -0400247
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}