blob: fc056fc6199516cfe7d7f63fdecd5548e9f2e72f [file] [log] [blame]
Forest Bond5449c682009-04-25 10:30:44 -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: 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
Forest Bond5449c682009-04-25 10:30:44 -040036#include "device.h"
Forest Bond5449c682009-04-25 10:30:44 -040037#include "80211hdr.h"
Forest Bond5449c682009-04-25 10:30:44 -040038
39/*--------------------- Static Definitions -------------------------*/
40
41/*--------------------- Static Classes ----------------------------*/
42
43/*--------------------- Static Variables --------------------------*/
44
45/*
46 * SBOX Table
47 */
48
Charles Clément3fc9b582010-06-24 11:02:27 -070049unsigned char sbox_table[256] =
Forest Bond5449c682009-04-25 10:30:44 -040050{
Joe Perches659b4d92013-03-18 10:44:37 -070051 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
Forest Bond5449c682009-04-25 10:30:44 -040067};
68
Charles Clément3fc9b582010-06-24 11:02:27 -070069unsigned char dot2_table[256] = {
Joe Perches659b4d92013-03-18 10:44:37 -070070 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
Forest Bond5449c682009-04-25 10:30:44 -040086};
87
Charles Clément3fc9b582010-06-24 11:02:27 -070088unsigned char dot3_table[256] = {
Joe Perches659b4d92013-03-18 10:44:37 -070089 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
Forest Bond5449c682009-04-25 10:30:44 -0400105};
106
107/*--------------------- Static Functions --------------------------*/
108
109/*--------------------- Export Variables --------------------------*/
110
111/*--------------------- Export Functions --------------------------*/
112
Charles Clément3fc9b582010-06-24 11:02:27 -0700113void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
Forest Bond5449c682009-04-25 10:30:44 -0400114{
Joe Perches659b4d92013-03-18 10:44:37 -0700115 unsigned long *dwPtrA = (unsigned long *)a;
116 unsigned long *dwPtrB = (unsigned long *)b;
117 unsigned long *dwPtrOut = (unsigned long *)out;
Forest Bond5449c682009-04-25 10:30:44 -0400118
Joe Perches659b4d92013-03-18 10:44:37 -0700119 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
120 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
121 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
122 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
Forest Bond5449c682009-04-25 10:30:44 -0400123}
124
Charles Clément3fc9b582010-06-24 11:02:27 -0700125void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
Forest Bond5449c682009-04-25 10:30:44 -0400126{
Joe Perches659b4d92013-03-18 10:44:37 -0700127 unsigned long *dwPtrA = (unsigned long *)a;
128 unsigned long *dwPtrB = (unsigned long *)b;
129 unsigned long *dwPtrOut = (unsigned long *)out;
Forest Bond5449c682009-04-25 10:30:44 -0400130
Joe Perches659b4d92013-03-18 10:44:37 -0700131 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
Forest Bond5449c682009-04-25 10:30:44 -0400132}
133
Charles Clément3fc9b582010-06-24 11:02:27 -0700134void AddRoundKey(unsigned char *key, int round)
Forest Bond5449c682009-04-25 10:30:44 -0400135{
Joe Perches659b4d92013-03-18 10:44:37 -0700136 unsigned char sbox_key[4];
137 unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
Forest Bond5449c682009-04-25 10:30:44 -0400138
Joe Perches659b4d92013-03-18 10:44:37 -0700139 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]];
Forest Bond5449c682009-04-25 10:30:44 -0400143
Joe Perches659b4d92013-03-18 10:44:37 -0700144 key[0] = key[0] ^ rcon_table[round];
145 xor_32(&key[0], sbox_key, &key[0]);
Forest Bond5449c682009-04-25 10:30:44 -0400146
Joe Perches659b4d92013-03-18 10:44:37 -0700147 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]);
Forest Bond5449c682009-04-25 10:30:44 -0400150}
151
Charles Clément3fc9b582010-06-24 11:02:27 -0700152void SubBytes(unsigned char *in, unsigned char *out)
Forest Bond5449c682009-04-25 10:30:44 -0400153{
Joe Perches659b4d92013-03-18 10:44:37 -0700154 int i;
Forest Bond5449c682009-04-25 10:30:44 -0400155
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700156 for (i = 0; i < 16; i++) {
Joe Perches659b4d92013-03-18 10:44:37 -0700157 out[i] = sbox_table[in[i]];
158 }
Forest Bond5449c682009-04-25 10:30:44 -0400159}
160
Charles Clément3fc9b582010-06-24 11:02:27 -0700161void ShiftRows(unsigned char *in, unsigned char *out)
Forest Bond5449c682009-04-25 10:30:44 -0400162{
Joe Perches659b4d92013-03-18 10:44:37 -0700163 out[0] = in[0];
164 out[1] = in[5];
165 out[2] = in[10];
166 out[3] = in[15];
167 out[4] = in[4];
168 out[5] = in[9];
169 out[6] = in[14];
170 out[7] = in[3];
171 out[8] = in[8];
172 out[9] = in[13];
173 out[10] = in[2];
174 out[11] = in[7];
175 out[12] = in[12];
176 out[13] = in[1];
177 out[14] = in[6];
178 out[15] = in[11];
Forest Bond5449c682009-04-25 10:30:44 -0400179}
180
Charles Clément3fc9b582010-06-24 11:02:27 -0700181void MixColumns(unsigned char *in, unsigned char *out)
Forest Bond5449c682009-04-25 10:30:44 -0400182{
Joe Perches659b4d92013-03-18 10:44:37 -0700183 out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
184 out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
185 out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
186 out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
Forest Bond5449c682009-04-25 10:30:44 -0400187}
188
Charles Clément3fc9b582010-06-24 11:02:27 -0700189void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
Forest Bond5449c682009-04-25 10:30:44 -0400190{
Joe Perches659b4d92013-03-18 10:44:37 -0700191 int i;
192 int round;
193 unsigned char TmpdataA[16];
194 unsigned char TmpdataB[16];
195 unsigned char abyRoundKey[16];
Forest Bond5449c682009-04-25 10:30:44 -0400196
Joe Perches659b4d92013-03-18 10:44:37 -0700197 for (i = 0; i < 16; i++)
198 abyRoundKey[i] = key[i];
Forest Bond5449c682009-04-25 10:30:44 -0400199
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700200 for (round = 0; round < 11; round++) {
201 if (round == 0) {
Joe Perches659b4d92013-03-18 10:44:37 -0700202 xor_128(abyRoundKey, data, ciphertext);
203 AddRoundKey(abyRoundKey, round);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700204 } else if (round == 10) {
Joe Perches659b4d92013-03-18 10:44:37 -0700205 SubBytes(ciphertext, TmpdataA);
206 ShiftRows(TmpdataA, TmpdataB);
207 xor_128(TmpdataB, abyRoundKey, ciphertext);
Tülin İzer600816c2013-05-15 23:41:28 +0300208 } else /* round 1 ~ 9 */
Joe Perches659b4d92013-03-18 10:44:37 -0700209 {
210 SubBytes(ciphertext, TmpdataA);
211 ShiftRows(TmpdataA, TmpdataB);
212 MixColumns(&TmpdataB[0], &TmpdataA[0]);
213 MixColumns(&TmpdataB[4], &TmpdataA[4]);
214 MixColumns(&TmpdataB[8], &TmpdataA[8]);
215 MixColumns(&TmpdataB[12], &TmpdataA[12]);
216 xor_128(TmpdataA, abyRoundKey, ciphertext);
217 AddRoundKey(abyRoundKey, round);
218 }
219 }
Forest Bond5449c682009-04-25 10:30:44 -0400220}
221
222/*
223 * Description: AES decryption
224 *
225 * Parameters:
226 * In:
227 * pbyRxKey - The key used to decrypt
228 * pbyFrame - Starting address of packet header
229 * wFrameSize - Total packet size including CRC
230 * Out:
231 * none
232 *
233 * Return Value: MIC compare result
234 *
235 */
Charles Clément7b6a0012010-08-01 17:15:50 +0200236bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize)
Forest Bond5449c682009-04-25 10:30:44 -0400237{
Joe Perches659b4d92013-03-18 10:44:37 -0700238 unsigned char abyNonce[13];
239 unsigned char MIC_IV[16];
240 unsigned char MIC_HDR1[16];
241 unsigned char MIC_HDR2[16];
242 unsigned char abyMIC[16];
243 unsigned char abyCTRPLD[16];
244 unsigned char abyTmp[16];
245 unsigned char abyPlainText[16];
246 unsigned char abyLastCipher[16];
Forest Bond5449c682009-04-25 10:30:44 -0400247
Joe Perches659b4d92013-03-18 10:44:37 -0700248 PS802_11Header pMACHeader = (PS802_11Header) pbyFrame;
249 unsigned char *pbyIV;
250 unsigned char *pbyPayload;
251 unsigned short wHLen = 22;
Tülin İzer600816c2013-05-15 23:41:28 +0300252 unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;/* 8 is IV, 8 is MIC, 4 is CRC */
Joe Perches659b4d92013-03-18 10:44:37 -0700253 bool bA4 = false;
254 unsigned char byTmp;
255 unsigned short wCnt;
256 int ii, jj, kk;
Forest Bond5449c682009-04-25 10:30:44 -0400257
Joe Perches659b4d92013-03-18 10:44:37 -0700258 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
259 if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
260 WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
261 bA4 = true;
Tülin İzer600816c2013-05-15 23:41:28 +0300262 pbyIV += 6; /* 6 is 802.11 address4 */
Joe Perches659b4d92013-03-18 10:44:37 -0700263 wHLen += 6;
264 wPayloadSize -= 6;
265 }
Tülin İzer600816c2013-05-15 23:41:28 +0300266 pbyPayload = pbyIV + 8; /* IV-length */
Forest Bond5449c682009-04-25 10:30:44 -0400267
Tülin İzer600816c2013-05-15 23:41:28 +0300268 abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */
Joe Perches659b4d92013-03-18 10:44:37 -0700269 memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN);
270 abyNonce[7] = pbyIV[7];
271 abyNonce[8] = pbyIV[6];
272 abyNonce[9] = pbyIV[5];
273 abyNonce[10] = pbyIV[4];
274 abyNonce[11] = pbyIV[1];
275 abyNonce[12] = pbyIV[0];
Forest Bond5449c682009-04-25 10:30:44 -0400276
Tülin İzer600816c2013-05-15 23:41:28 +0300277 /* MIC_IV */
Joe Perches659b4d92013-03-18 10:44:37 -0700278 MIC_IV[0] = 0x59;
279 memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
280 MIC_IV[14] = (unsigned char)(wPayloadSize >> 8);
281 MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff);
Forest Bond5449c682009-04-25 10:30:44 -0400282
Tülin İzer600816c2013-05-15 23:41:28 +0300283 /* MIC_HDR1 */
Joe Perches659b4d92013-03-18 10:44:37 -0700284 MIC_HDR1[0] = (unsigned char)(wHLen >> 8);
285 MIC_HDR1[1] = (unsigned char)(wHLen & 0xff);
286 byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff);
287 MIC_HDR1[2] = byTmp & 0x8f;
288 byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8);
289 byTmp &= 0x87;
290 MIC_HDR1[3] = byTmp | 0x40;
291 memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN);
292 memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN);
Forest Bond5449c682009-04-25 10:30:44 -0400293
Tülin İzer600816c2013-05-15 23:41:28 +0300294 /* MIC_HDR2 */
Joe Perches659b4d92013-03-18 10:44:37 -0700295 memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN);
296 byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff);
297 MIC_HDR2[6] = byTmp & 0x0f;
298 MIC_HDR2[7] = 0;
299 if (bA4) {
300 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN);
301 } else {
302 MIC_HDR2[8] = 0x00;
303 MIC_HDR2[9] = 0x00;
304 MIC_HDR2[10] = 0x00;
305 MIC_HDR2[11] = 0x00;
306 MIC_HDR2[12] = 0x00;
307 MIC_HDR2[13] = 0x00;
308 }
309 MIC_HDR2[14] = 0x00;
310 MIC_HDR2[15] = 0x00;
Forest Bond5449c682009-04-25 10:30:44 -0400311
Tülin İzer600816c2013-05-15 23:41:28 +0300312 /* CCMP */
Joe Perches659b4d92013-03-18 10:44:37 -0700313 AESv128(pbyRxKey, MIC_IV, abyMIC);
314 for (kk = 0; kk < 16; kk++) {
315 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
316 }
317 AESv128(pbyRxKey, abyTmp, abyMIC);
318 for (kk = 0; kk < 16; kk++) {
319 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
320 }
321 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond5449c682009-04-25 10:30:44 -0400322
Joe Perches659b4d92013-03-18 10:44:37 -0700323 wCnt = 1;
324 abyCTRPLD[0] = 0x01;
325 memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
Forest Bond5449c682009-04-25 10:30:44 -0400326
Joe Perches659b4d92013-03-18 10:44:37 -0700327 for (jj = wPayloadSize; jj > 16; jj = jj - 16) {
Joe Perches659b4d92013-03-18 10:44:37 -0700328 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
329 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
Forest Bond5449c682009-04-25 10:30:44 -0400330
Joe Perches659b4d92013-03-18 10:44:37 -0700331 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
Forest Bond5449c682009-04-25 10:30:44 -0400332
Joe Perches659b4d92013-03-18 10:44:37 -0700333 for (kk = 0; kk < 16; kk++) {
334 abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
335 }
336 for (kk = 0; kk < 16; kk++) {
337 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
338 }
339 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond5449c682009-04-25 10:30:44 -0400340
Joe Perches659b4d92013-03-18 10:44:37 -0700341 memcpy(pbyPayload, abyPlainText, 16);
342 wCnt++;
343 pbyPayload += 16;
Tülin İzer600816c2013-05-15 23:41:28 +0300344 } /* for wPayloadSize */
Forest Bond5449c682009-04-25 10:30:44 -0400345
Tülin İzer600816c2013-05-15 23:41:28 +0300346 /* last payload */
Joe Perches659b4d92013-03-18 10:44:37 -0700347 memcpy(&(abyLastCipher[0]), pbyPayload, jj);
348 for (ii = jj; ii < 16; ii++) {
349 abyLastCipher[ii] = 0x00;
350 }
Forest Bond5449c682009-04-25 10:30:44 -0400351
Joe Perches659b4d92013-03-18 10:44:37 -0700352 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
353 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
Forest Bond5449c682009-04-25 10:30:44 -0400354
Joe Perches659b4d92013-03-18 10:44:37 -0700355 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
356 for (kk = 0; kk < 16; kk++) {
357 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
358 }
359 memcpy(pbyPayload, abyPlainText, jj);
360 pbyPayload += jj;
Forest Bond5449c682009-04-25 10:30:44 -0400361
Tülin İzer600816c2013-05-15 23:41:28 +0300362 /* for MIC calculation */
Joe Perches659b4d92013-03-18 10:44:37 -0700363 for (ii = jj; ii < 16; ii++) {
364 abyPlainText[ii] = 0x00;
365 }
366 for (kk = 0; kk < 16; kk++) {
367 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
368 }
369 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond5449c682009-04-25 10:30:44 -0400370
Tülin İzer600816c2013-05-15 23:41:28 +0300371 /* =>above is the calculate MIC */
372 /* -------------------------------------------- */
Forest Bond5449c682009-04-25 10:30:44 -0400373
Joe Perches659b4d92013-03-18 10:44:37 -0700374 wCnt = 0;
375 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
376 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
377 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
378 for (kk = 0; kk < 8; kk++) {
379 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
380 }
Tülin İzer600816c2013-05-15 23:41:28 +0300381 /* =>above is the dec-MIC from packet */
382 /* -------------------------------------------- */
Forest Bond5449c682009-04-25 10:30:44 -0400383
John B. Wyatt IV2b8d5e52013-06-19 23:56:45 -0700384 if (!memcmp(abyMIC, abyTmp, 8))
Joe Perches659b4d92013-03-18 10:44:37 -0700385 return true;
John B. Wyatt IV2b8d5e52013-06-19 23:56:45 -0700386 else
Joe Perches659b4d92013-03-18 10:44:37 -0700387 return false;
Forest Bond5449c682009-04-25 10:30:44 -0400388}