]> Pileus Git - ~andy/linux/blob - drivers/staging/vt6655/tkip.c
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
[~andy/linux] / drivers / staging / vt6655 / tkip.c
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 /************************************************************/
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
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  */
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 }