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
40 /*--------------------- Static Definitions -------------------------*/
42 /*--------------------- Static Classes ----------------------------*/
44 /*--------------------- Static Variables --------------------------*/
50 static unsigned char sbox_table[256] = {
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
69 static unsigned char 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
88 static unsigned char 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
107 /*--------------------- Static Functions --------------------------*/
109 /*--------------------- Export Variables --------------------------*/
111 /*--------------------- Export Functions --------------------------*/
113 static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
115 unsigned long *dwPtrA = (unsigned long *)a;
116 unsigned long *dwPtrB = (unsigned long *)b;
117 unsigned long *dwPtrOut = (unsigned long *)out;
119 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
120 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
121 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
122 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
125 static void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
127 unsigned long *dwPtrA = (unsigned long *)a;
128 unsigned long *dwPtrB = (unsigned long *)b;
129 unsigned long *dwPtrOut = (unsigned long *)out;
131 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
134 static void AddRoundKey(unsigned char *key, int round)
136 unsigned char sbox_key[4];
137 unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
139 sbox_key[0] = sbox_table[key[13]];
140 sbox_key[1] = sbox_table[key[14]];
141 sbox_key[2] = sbox_table[key[15]];
142 sbox_key[3] = sbox_table[key[12]];
144 key[0] = key[0] ^ rcon_table[round];
145 xor_32(&key[0], sbox_key, &key[0]);
147 xor_32(&key[4], &key[0], &key[4]);
148 xor_32(&key[8], &key[4], &key[8]);
149 xor_32(&key[12], &key[8], &key[12]);
152 static void SubBytes(unsigned char *in, unsigned char *out)
156 for (i = 0; i < 16; i++)
157 out[i] = sbox_table[in[i]];
160 static void ShiftRows(unsigned char *in, unsigned char *out)
180 static void MixColumns(unsigned char *in, unsigned char *out)
182 out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
183 out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
184 out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
185 out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
188 static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
192 unsigned char TmpdataA[16];
193 unsigned char TmpdataB[16];
194 unsigned char abyRoundKey[16];
196 for (i = 0; i < 16; i++)
197 abyRoundKey[i] = key[i];
199 for (round = 0; round < 11; round++) {
201 xor_128(abyRoundKey, data, ciphertext);
202 AddRoundKey(abyRoundKey, round);
203 } else if (round == 10) {
204 SubBytes(ciphertext, TmpdataA);
205 ShiftRows(TmpdataA, TmpdataB);
206 xor_128(TmpdataB, abyRoundKey, ciphertext);
207 } else /* round 1 ~ 9 */{
208 SubBytes(ciphertext, TmpdataA);
209 ShiftRows(TmpdataA, TmpdataB);
210 MixColumns(&TmpdataB[0], &TmpdataA[0]);
211 MixColumns(&TmpdataB[4], &TmpdataA[4]);
212 MixColumns(&TmpdataB[8], &TmpdataA[8]);
213 MixColumns(&TmpdataB[12], &TmpdataA[12]);
214 xor_128(TmpdataA, abyRoundKey, ciphertext);
215 AddRoundKey(abyRoundKey, round);
221 * Description: AES decryption
225 * pbyRxKey - The key used to decrypt
226 * pbyFrame - Starting address of packet header
227 * wFrameSize - Total packet size including CRC
231 * Return Value: MIC compare result
234 bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize)
236 unsigned char abyNonce[13];
237 unsigned char MIC_IV[16];
238 unsigned char MIC_HDR1[16];
239 unsigned char MIC_HDR2[16];
240 unsigned char abyMIC[16];
241 unsigned char abyCTRPLD[16];
242 unsigned char abyTmp[16];
243 unsigned char abyPlainText[16];
244 unsigned char abyLastCipher[16];
246 PS802_11Header pMACHeader = (PS802_11Header) pbyFrame;
247 unsigned char *pbyIV;
248 unsigned char *pbyPayload;
249 unsigned short wHLen = 22;
250 unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;/* 8 is IV, 8 is MIC, 4 is CRC */
256 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
257 if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
258 WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
260 pbyIV += 6; /* 6 is 802.11 address4 */
264 pbyPayload = pbyIV + 8; /* IV-length */
266 abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */
267 memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN);
268 abyNonce[7] = pbyIV[7];
269 abyNonce[8] = pbyIV[6];
270 abyNonce[9] = pbyIV[5];
271 abyNonce[10] = pbyIV[4];
272 abyNonce[11] = pbyIV[1];
273 abyNonce[12] = pbyIV[0];
277 memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
278 MIC_IV[14] = (unsigned char)(wPayloadSize >> 8);
279 MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff);
282 MIC_HDR1[0] = (unsigned char)(wHLen >> 8);
283 MIC_HDR1[1] = (unsigned char)(wHLen & 0xff);
284 byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff);
285 MIC_HDR1[2] = byTmp & 0x8f;
286 byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8);
288 MIC_HDR1[3] = byTmp | 0x40;
289 memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN);
290 memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN);
293 memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN);
294 byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff);
295 MIC_HDR2[6] = byTmp & 0x0f;
298 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN);
311 AESv128(pbyRxKey, MIC_IV, abyMIC);
312 for (kk = 0; kk < 16; kk++)
313 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
314 AESv128(pbyRxKey, abyTmp, abyMIC);
315 for (kk = 0; kk < 16; kk++)
316 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
317 AESv128(pbyRxKey, abyTmp, abyMIC);
321 memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
323 for (jj = wPayloadSize; jj > 16; jj = jj - 16) {
324 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
325 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
327 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
329 for (kk = 0; kk < 16; kk++)
330 abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
331 for (kk = 0; kk < 16; kk++)
332 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
333 AESv128(pbyRxKey, abyTmp, abyMIC);
335 memcpy(pbyPayload, abyPlainText, 16);
338 } /* for wPayloadSize */
341 memcpy(&(abyLastCipher[0]), pbyPayload, jj);
342 for (ii = jj; ii < 16; ii++)
343 abyLastCipher[ii] = 0x00;
345 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
346 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
348 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
349 for (kk = 0; kk < 16; kk++)
350 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
351 memcpy(pbyPayload, abyPlainText, jj);
354 /* for MIC calculation */
355 for (ii = jj; ii < 16; ii++)
356 abyPlainText[ii] = 0x00;
357 for (kk = 0; kk < 16; kk++)
358 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
359 AESv128(pbyRxKey, abyTmp, abyMIC);
361 /* =>above is the calculate MIC */
362 /* -------------------------------------------- */
365 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
366 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
367 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
368 for (kk = 0; kk < 8; kk++)
369 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
370 /* =>above is the dec-MIC from packet */
371 /* -------------------------------------------- */
373 return !memcmp(abyMIC, abyTmp, 8);