2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
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.
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.
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.
22 * Purpose: AES_CCMP decryption
29 * AESbGenCCMP - Parsing RX-packet
39 /*--------------------- Static Definitions -------------------------*/
41 /*--------------------- Static Classes ----------------------------*/
43 /*--------------------- Static Variables --------------------------*/
49 static unsigned char sbox_table[256] = {
50 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
51 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
52 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
53 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
54 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
55 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
56 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
57 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
58 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
59 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
60 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
61 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
62 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
63 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
64 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
65 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
68 static unsigned char dot2_table[256] = {
69 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
70 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
71 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
72 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
73 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
74 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
75 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
76 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
77 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
78 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
79 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
80 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
81 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
82 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
83 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
84 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
87 static unsigned char dot3_table[256] = {
88 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
89 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
90 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
91 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
92 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
93 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
94 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
95 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
96 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
97 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
98 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
99 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
100 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
101 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
102 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
103 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
106 /*--------------------- Static Functions --------------------------*/
108 /*--------------------- Export Variables --------------------------*/
110 /*--------------------- Export Functions --------------------------*/
112 static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
114 unsigned long *dwPtrA = (unsigned long *)a;
115 unsigned long *dwPtrB = (unsigned long *)b;
116 unsigned long *dwPtrOut = (unsigned long *)out;
118 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
119 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
120 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
121 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
124 static void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
126 unsigned long *dwPtrA = (unsigned long *)a;
127 unsigned long *dwPtrB = (unsigned long *)b;
128 unsigned long *dwPtrOut = (unsigned long *)out;
130 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
133 static void AddRoundKey(unsigned char *key, int round)
135 unsigned char sbox_key[4];
136 unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
138 sbox_key[0] = sbox_table[key[13]];
139 sbox_key[1] = sbox_table[key[14]];
140 sbox_key[2] = sbox_table[key[15]];
141 sbox_key[3] = sbox_table[key[12]];
143 key[0] = key[0] ^ rcon_table[round];
144 xor_32(&key[0], sbox_key, &key[0]);
146 xor_32(&key[4], &key[0], &key[4]);
147 xor_32(&key[8], &key[4], &key[8]);
148 xor_32(&key[12], &key[8], &key[12]);
151 static void SubBytes(unsigned char *in, unsigned char *out)
155 for (i = 0; i < 16; i++)
156 out[i] = sbox_table[in[i]];
159 static void ShiftRows(unsigned char *in, unsigned char *out)
179 static void MixColumns(unsigned char *in, unsigned char *out)
181 out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
182 out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
183 out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
184 out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
187 static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
191 unsigned char TmpdataA[16];
192 unsigned char TmpdataB[16];
193 unsigned char abyRoundKey[16];
195 for (i = 0; i < 16; i++)
196 abyRoundKey[i] = key[i];
198 for (round = 0; round < 11; round++) {
200 xor_128(abyRoundKey, data, ciphertext);
201 AddRoundKey(abyRoundKey, round);
202 } else if (round == 10) {
203 SubBytes(ciphertext, TmpdataA);
204 ShiftRows(TmpdataA, TmpdataB);
205 xor_128(TmpdataB, abyRoundKey, ciphertext);
206 } else /* round 1 ~ 9 */{
207 SubBytes(ciphertext, TmpdataA);
208 ShiftRows(TmpdataA, TmpdataB);
209 MixColumns(&TmpdataB[0], &TmpdataA[0]);
210 MixColumns(&TmpdataB[4], &TmpdataA[4]);
211 MixColumns(&TmpdataB[8], &TmpdataA[8]);
212 MixColumns(&TmpdataB[12], &TmpdataA[12]);
213 xor_128(TmpdataA, abyRoundKey, ciphertext);
214 AddRoundKey(abyRoundKey, round);
220 * Description: AES decryption
224 * pbyRxKey - The key used to decrypt
225 * pbyFrame - Starting address of packet header
226 * wFrameSize - Total packet size including CRC
230 * Return Value: MIC compare result
233 bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize)
235 unsigned char abyNonce[13];
236 unsigned char MIC_IV[16];
237 unsigned char MIC_HDR1[16];
238 unsigned char MIC_HDR2[16];
239 unsigned char abyMIC[16];
240 unsigned char abyCTRPLD[16];
241 unsigned char abyTmp[16];
242 unsigned char abyPlainText[16];
243 unsigned char abyLastCipher[16];
245 PS802_11Header pMACHeader = (PS802_11Header) pbyFrame;
246 unsigned char *pbyIV;
247 unsigned char *pbyPayload;
248 unsigned short wHLen = 22;
249 unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;/* 8 is IV, 8 is MIC, 4 is CRC */
255 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
256 if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
257 WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
259 pbyIV += 6; /* 6 is 802.11 address4 */
263 pbyPayload = pbyIV + 8; /* IV-length */
265 abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */
266 memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN);
267 abyNonce[7] = pbyIV[7];
268 abyNonce[8] = pbyIV[6];
269 abyNonce[9] = pbyIV[5];
270 abyNonce[10] = pbyIV[4];
271 abyNonce[11] = pbyIV[1];
272 abyNonce[12] = pbyIV[0];
276 memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
277 MIC_IV[14] = (unsigned char)(wPayloadSize >> 8);
278 MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff);
281 MIC_HDR1[0] = (unsigned char)(wHLen >> 8);
282 MIC_HDR1[1] = (unsigned char)(wHLen & 0xff);
283 byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff);
284 MIC_HDR1[2] = byTmp & 0x8f;
285 byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8);
287 MIC_HDR1[3] = byTmp | 0x40;
288 memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN);
289 memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN);
292 memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN);
293 byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff);
294 MIC_HDR2[6] = byTmp & 0x0f;
297 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN);
310 AESv128(pbyRxKey, MIC_IV, abyMIC);
311 for (kk = 0; kk < 16; kk++)
312 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
313 AESv128(pbyRxKey, abyTmp, abyMIC);
314 for (kk = 0; kk < 16; kk++)
315 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
316 AESv128(pbyRxKey, abyTmp, abyMIC);
320 memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
322 for (jj = wPayloadSize; jj > 16; jj = jj - 16) {
323 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
324 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
326 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
328 for (kk = 0; kk < 16; kk++)
329 abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
330 for (kk = 0; kk < 16; kk++)
331 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
332 AESv128(pbyRxKey, abyTmp, abyMIC);
334 memcpy(pbyPayload, abyPlainText, 16);
337 } /* for wPayloadSize */
340 memcpy(&(abyLastCipher[0]), pbyPayload, jj);
341 for (ii = jj; ii < 16; ii++)
342 abyLastCipher[ii] = 0x00;
344 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
345 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
347 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
348 for (kk = 0; kk < 16; kk++)
349 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
350 memcpy(pbyPayload, abyPlainText, jj);
353 /* for MIC calculation */
354 for (ii = jj; ii < 16; ii++)
355 abyPlainText[ii] = 0x00;
356 for (kk = 0; kk < 16; kk++)
357 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
358 AESv128(pbyRxKey, abyTmp, abyMIC);
360 /* =>above is the calculate MIC */
361 /* -------------------------------------------- */
364 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
365 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
366 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
367 for (kk = 0; kk < 8; kk++)
368 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
369 /* =>above is the dec-MIC from packet */
370 /* -------------------------------------------- */
372 if (!memcmp(abyMIC, abyTmp, 8))