Merge git://git.infradead.org/mtd-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / vt6655 / aes_ccmp.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: aes_ccmp.c
21 *
22 * Purpose: AES_CCMP decryption
23 *
24 * Author: Warren Hsu
25 *
26 * Date: Feb 15, 2005
27 *
28 * Functions:
29 * AESbGenCCMP - Parsing RX-packet
30 *
31 *
32 * Revision History:
33 *
34 */
35
36 #include "device.h"
37 #include "80211hdr.h"
38
39 /*--------------------- Static Definitions -------------------------*/
40
41 /*--------------------- Static Classes ----------------------------*/
42
43 /*--------------------- Static Variables --------------------------*/
44
45 /*
46 * SBOX Table
47 */
48
49 BYTE sbox_table[256] =
50 {
51 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
52 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
53 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
54 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
55 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
56 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
57 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
58 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
59 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
60 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
61 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
62 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
63 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
64 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
65 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
66 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
67 };
68
69 BYTE dot2_table[256] = {
70 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
71 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
72 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
73 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
74 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
75 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
76 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
77 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
78 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
79 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
80 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
81 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
82 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
83 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
84 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
85 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
86 };
87
88 BYTE dot3_table[256] = {
89 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
90 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
91 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
92 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
93 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
94 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
95 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
96 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
97 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
98 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
99 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
100 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
101 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
102 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
103 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
104 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
105 };
106
107 /*--------------------- Static Functions --------------------------*/
108
109 /*--------------------- Export Variables --------------------------*/
110
111 /*--------------------- Export Functions --------------------------*/
112
113 void xor_128(BYTE *a, BYTE *b, BYTE *out)
114 {
115 PDWORD dwPtrA = (PDWORD) a;
116 PDWORD dwPtrB = (PDWORD) b;
117 PDWORD dwPtrOut =(PDWORD) out;
118
119 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
120 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
121 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
122 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
123 }
124
125
126 void xor_32(BYTE *a, BYTE *b, BYTE *out)
127 {
128 PDWORD dwPtrA = (PDWORD) a;
129 PDWORD dwPtrB = (PDWORD) b;
130 PDWORD dwPtrOut =(PDWORD) out;
131
132 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
133 }
134
135 void AddRoundKey(BYTE *key, int round)
136 {
137 BYTE sbox_key[4];
138 BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
139
140 sbox_key[0] = sbox_table[key[13]];
141 sbox_key[1] = sbox_table[key[14]];
142 sbox_key[2] = sbox_table[key[15]];
143 sbox_key[3] = sbox_table[key[12]];
144
145 key[0] = key[0] ^ rcon_table[round];
146 xor_32(&key[0], sbox_key, &key[0]);
147
148 xor_32(&key[4], &key[0], &key[4]);
149 xor_32(&key[8], &key[4], &key[8]);
150 xor_32(&key[12], &key[8], &key[12]);
151 }
152
153 void SubBytes(BYTE *in, BYTE *out)
154 {
155 int i;
156
157 for (i=0; i< 16; i++)
158 {
159 out[i] = sbox_table[in[i]];
160 }
161 }
162
163 void ShiftRows(BYTE *in, BYTE *out)
164 {
165 out[0] = in[0];
166 out[1] = in[5];
167 out[2] = in[10];
168 out[3] = in[15];
169 out[4] = in[4];
170 out[5] = in[9];
171 out[6] = in[14];
172 out[7] = in[3];
173 out[8] = in[8];
174 out[9] = in[13];
175 out[10] = in[2];
176 out[11] = in[7];
177 out[12] = in[12];
178 out[13] = in[1];
179 out[14] = in[6];
180 out[15] = in[11];
181 }
182
183 void MixColumns(BYTE *in, BYTE *out)
184 {
185
186 out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
187 out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
188 out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
189 out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
190 }
191
192
193 void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext)
194 {
195 int i;
196 int round;
197 BYTE TmpdataA[16];
198 BYTE TmpdataB[16];
199 BYTE abyRoundKey[16];
200
201 for(i=0; i<16; i++)
202 abyRoundKey[i] = key[i];
203
204 for (round = 0; round < 11; round++)
205 {
206 if (round == 0)
207 {
208 xor_128(abyRoundKey, data, ciphertext);
209 AddRoundKey(abyRoundKey, round);
210 }
211 else if (round == 10)
212 {
213 SubBytes(ciphertext, TmpdataA);
214 ShiftRows(TmpdataA, TmpdataB);
215 xor_128(TmpdataB, abyRoundKey, ciphertext);
216 }
217 else // round 1 ~ 9
218 {
219 SubBytes(ciphertext, TmpdataA);
220 ShiftRows(TmpdataA, TmpdataB);
221 MixColumns(&TmpdataB[0], &TmpdataA[0]);
222 MixColumns(&TmpdataB[4], &TmpdataA[4]);
223 MixColumns(&TmpdataB[8], &TmpdataA[8]);
224 MixColumns(&TmpdataB[12], &TmpdataA[12]);
225 xor_128(TmpdataA, abyRoundKey, ciphertext);
226 AddRoundKey(abyRoundKey, round);
227 }
228 }
229
230 }
231
232 /*
233 * Description: AES decryption
234 *
235 * Parameters:
236 * In:
237 * pbyRxKey - The key used to decrypt
238 * pbyFrame - Starting address of packet header
239 * wFrameSize - Total packet size including CRC
240 * Out:
241 * none
242 *
243 * Return Value: MIC compare result
244 *
245 */
246 BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize)
247 {
248 BYTE abyNonce[13];
249 BYTE MIC_IV[16];
250 BYTE MIC_HDR1[16];
251 BYTE MIC_HDR2[16];
252 BYTE abyMIC[16];
253 BYTE abyCTRPLD[16];
254 BYTE abyTmp[16];
255 BYTE abyPlainText[16];
256 BYTE abyLastCipher[16];
257
258 PS802_11Header pMACHeader = (PS802_11Header) pbyFrame;
259 PBYTE pbyIV;
260 PBYTE pbyPayload;
261 WORD wHLen = 22;
262 WORD wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC
263 BOOL bA4 = FALSE;
264 BYTE byTmp;
265 WORD wCnt;
266 int ii,jj,kk;
267
268
269 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
270 if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
271 WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
272 bA4 = TRUE;
273 pbyIV += 6; // 6 is 802.11 address4
274 wHLen += 6;
275 wPayloadSize -= 6;
276 }
277 pbyPayload = pbyIV + 8; //IV-length
278
279 abyNonce[0] = 0x00; //now is 0, if Qos here will be priority
280 memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
281 abyNonce[7] = pbyIV[7];
282 abyNonce[8] = pbyIV[6];
283 abyNonce[9] = pbyIV[5];
284 abyNonce[10] = pbyIV[4];
285 abyNonce[11] = pbyIV[1];
286 abyNonce[12] = pbyIV[0];
287
288 //MIC_IV
289 MIC_IV[0] = 0x59;
290 memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
291 MIC_IV[14] = (BYTE)(wPayloadSize >> 8);
292 MIC_IV[15] = (BYTE)(wPayloadSize & 0xff);
293
294 //MIC_HDR1
295 MIC_HDR1[0] = (BYTE)(wHLen >> 8);
296 MIC_HDR1[1] = (BYTE)(wHLen & 0xff);
297 byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff);
298 MIC_HDR1[2] = byTmp & 0x8f;
299 byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8);
300 byTmp &= 0x87;
301 MIC_HDR1[3] = byTmp | 0x40;
302 memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, U_ETHER_ADDR_LEN);
303 memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
304
305 //MIC_HDR2
306 memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, U_ETHER_ADDR_LEN);
307 byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff);
308 MIC_HDR2[6] = byTmp & 0x0f;
309 MIC_HDR2[7] = 0;
310 if ( bA4 ) {
311 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, U_ETHER_ADDR_LEN);
312 } else {
313 MIC_HDR2[8] = 0x00;
314 MIC_HDR2[9] = 0x00;
315 MIC_HDR2[10] = 0x00;
316 MIC_HDR2[11] = 0x00;
317 MIC_HDR2[12] = 0x00;
318 MIC_HDR2[13] = 0x00;
319 }
320 MIC_HDR2[14] = 0x00;
321 MIC_HDR2[15] = 0x00;
322
323 //CCMP
324 AESv128(pbyRxKey,MIC_IV,abyMIC);
325 for ( kk=0; kk<16; kk++ ) {
326 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
327 }
328 AESv128(pbyRxKey,abyTmp,abyMIC);
329 for ( kk=0; kk<16; kk++ ) {
330 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
331 }
332 AESv128(pbyRxKey,abyTmp,abyMIC);
333
334 wCnt = 1;
335 abyCTRPLD[0] = 0x01;
336 memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
337
338 for(jj=wPayloadSize; jj>16; jj=jj-16) {
339
340 abyCTRPLD[14] = (BYTE) (wCnt >> 8);
341 abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
342
343 AESv128(pbyRxKey,abyCTRPLD,abyTmp);
344
345 for ( kk=0; kk<16; kk++ ) {
346 abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
347 }
348 for ( kk=0; kk<16; kk++ ) {
349 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
350 }
351 AESv128(pbyRxKey,abyTmp,abyMIC);
352
353 memcpy(pbyPayload, abyPlainText, 16);
354 wCnt++;
355 pbyPayload += 16;
356 } //for wPayloadSize
357
358 //last payload
359 memcpy(&(abyLastCipher[0]), pbyPayload, jj);
360 for ( ii=jj; ii<16; ii++ ) {
361 abyLastCipher[ii] = 0x00;
362 }
363
364 abyCTRPLD[14] = (BYTE) (wCnt >> 8);
365 abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
366
367 AESv128(pbyRxKey,abyCTRPLD,abyTmp);
368 for ( kk=0; kk<16; kk++ ) {
369 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
370 }
371 memcpy(pbyPayload, abyPlainText, jj);
372 pbyPayload += jj;
373
374 //for MIC calculation
375 for ( ii=jj; ii<16; ii++ ) {
376 abyPlainText[ii] = 0x00;
377 }
378 for ( kk=0; kk<16; kk++ ) {
379 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
380 }
381 AESv128(pbyRxKey,abyTmp,abyMIC);
382
383 //=>above is the calculate MIC
384 //--------------------------------------------
385
386 wCnt = 0;
387 abyCTRPLD[14] = (BYTE) (wCnt >> 8);
388 abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
389 AESv128(pbyRxKey,abyCTRPLD,abyTmp);
390 for ( kk=0; kk<8; kk++ ) {
391 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
392 }
393 //=>above is the dec-MIC from packet
394 //--------------------------------------------
395
396 if ( !memcmp(abyMIC,abyTmp,8) ) {
397 return TRUE;
398 } else {
399 return FALSE;
400 }
401
402 }