blob: 1dfcfcb3c69ce5b69dee4ea2f9db2e3148d141ff [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"
Guillaume Clemente7a3cd52014-07-22 22:08:27 +020038#include "aes_ccmp.h"
Forest Bond5449c682009-04-25 10:30:44 -040039
40/*--------------------- Static Definitions -------------------------*/
41
42/*--------------------- Static Classes ----------------------------*/
43
44/*--------------------- Static Variables --------------------------*/
45
46/*
47 * SBOX Table
48 */
49
Ashley Smith042bdad2014-03-11 12:27:23 -040050static unsigned char sbox_table[256] = {
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
Archana kumari8009ae12013-10-17 15:54:44 +053069static unsigned 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
Archana kumari8009ae12013-10-17 15:54:44 +053088static unsigned 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
Archana kumari8009ae12013-10-17 15:54:44 +0530113static void 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
Archana kumari8009ae12013-10-17 15:54:44 +0530125static void 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
Archana kumari8009ae12013-10-17 15:54:44 +0530134static void 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
Archana kumari8009ae12013-10-17 15:54:44 +0530152static void 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
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100156 for (i = 0; i < 16; i++)
Joe Perches659b4d92013-03-18 10:44:37 -0700157 out[i] = sbox_table[in[i]];
Forest Bond5449c682009-04-25 10:30:44 -0400158}
159
Archana kumari8009ae12013-10-17 15:54:44 +0530160static void ShiftRows(unsigned char *in, unsigned char *out)
Forest Bond5449c682009-04-25 10:30:44 -0400161{
Joe Perches659b4d92013-03-18 10:44:37 -0700162 out[0] = in[0];
163 out[1] = in[5];
164 out[2] = in[10];
165 out[3] = in[15];
166 out[4] = in[4];
167 out[5] = in[9];
168 out[6] = in[14];
169 out[7] = in[3];
170 out[8] = in[8];
171 out[9] = in[13];
172 out[10] = in[2];
173 out[11] = in[7];
174 out[12] = in[12];
175 out[13] = in[1];
176 out[14] = in[6];
177 out[15] = in[11];
Forest Bond5449c682009-04-25 10:30:44 -0400178}
179
Archana kumari8009ae12013-10-17 15:54:44 +0530180static void MixColumns(unsigned char *in, unsigned char *out)
Forest Bond5449c682009-04-25 10:30:44 -0400181{
Joe Perches659b4d92013-03-18 10:44:37 -0700182 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]];
Forest Bond5449c682009-04-25 10:30:44 -0400186}
187
Archana kumari8009ae12013-10-17 15:54:44 +0530188static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
Forest Bond5449c682009-04-25 10:30:44 -0400189{
Joe Perches659b4d92013-03-18 10:44:37 -0700190 int i;
191 int round;
192 unsigned char TmpdataA[16];
193 unsigned char TmpdataB[16];
194 unsigned char abyRoundKey[16];
Forest Bond5449c682009-04-25 10:30:44 -0400195
Joe Perches659b4d92013-03-18 10:44:37 -0700196 for (i = 0; i < 16; i++)
197 abyRoundKey[i] = key[i];
Forest Bond5449c682009-04-25 10:30:44 -0400198
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700199 for (round = 0; round < 11; round++) {
200 if (round == 0) {
Joe Perches659b4d92013-03-18 10:44:37 -0700201 xor_128(abyRoundKey, data, ciphertext);
202 AddRoundKey(abyRoundKey, round);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700203 } else if (round == 10) {
Joe Perches659b4d92013-03-18 10:44:37 -0700204 SubBytes(ciphertext, TmpdataA);
205 ShiftRows(TmpdataA, TmpdataB);
206 xor_128(TmpdataB, abyRoundKey, ciphertext);
Jelena Bjelja9c45c422014-03-14 16:10:12 +0100207 } else /* round 1 ~ 9 */{
Joe Perches659b4d92013-03-18 10:44:37 -0700208 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);
216 }
217 }
Forest Bond5449c682009-04-25 10:30:44 -0400218}
219
220/*
221 * Description: AES decryption
222 *
223 * Parameters:
224 * In:
225 * pbyRxKey - The key used to decrypt
226 * pbyFrame - Starting address of packet header
227 * wFrameSize - Total packet size including CRC
228 * Out:
229 * none
230 *
231 * Return Value: MIC compare result
232 *
233 */
Charles Clément7b6a0012010-08-01 17:15:50 +0200234bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize)
Forest Bond5449c682009-04-25 10:30:44 -0400235{
Joe Perches659b4d92013-03-18 10:44:37 -0700236 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];
Forest Bond5449c682009-04-25 10:30:44 -0400245
Joe Perches659b4d92013-03-18 10:44:37 -0700246 PS802_11Header pMACHeader = (PS802_11Header) pbyFrame;
247 unsigned char *pbyIV;
248 unsigned char *pbyPayload;
249 unsigned short wHLen = 22;
Tülin İzer600816c2013-05-15 23:41:28 +0300250 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 -0700251 bool bA4 = false;
252 unsigned char byTmp;
253 unsigned short wCnt;
254 int ii, jj, kk;
Forest Bond5449c682009-04-25 10:30:44 -0400255
Joe Perches659b4d92013-03-18 10:44:37 -0700256 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
257 if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
258 WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
259 bA4 = true;
Tülin İzer600816c2013-05-15 23:41:28 +0300260 pbyIV += 6; /* 6 is 802.11 address4 */
Joe Perches659b4d92013-03-18 10:44:37 -0700261 wHLen += 6;
262 wPayloadSize -= 6;
263 }
Tülin İzer600816c2013-05-15 23:41:28 +0300264 pbyPayload = pbyIV + 8; /* IV-length */
Forest Bond5449c682009-04-25 10:30:44 -0400265
Tülin İzer600816c2013-05-15 23:41:28 +0300266 abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */
Joe Perches659b4d92013-03-18 10:44:37 -0700267 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];
Forest Bond5449c682009-04-25 10:30:44 -0400274
Tülin İzer600816c2013-05-15 23:41:28 +0300275 /* MIC_IV */
Joe Perches659b4d92013-03-18 10:44:37 -0700276 MIC_IV[0] = 0x59;
277 memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
278 MIC_IV[14] = (unsigned char)(wPayloadSize >> 8);
279 MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff);
Forest Bond5449c682009-04-25 10:30:44 -0400280
Tülin İzer600816c2013-05-15 23:41:28 +0300281 /* MIC_HDR1 */
Joe Perches659b4d92013-03-18 10:44:37 -0700282 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);
287 byTmp &= 0x87;
288 MIC_HDR1[3] = byTmp | 0x40;
289 memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN);
290 memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN);
Forest Bond5449c682009-04-25 10:30:44 -0400291
Tülin İzer600816c2013-05-15 23:41:28 +0300292 /* MIC_HDR2 */
Joe Perches659b4d92013-03-18 10:44:37 -0700293 memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN);
294 byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff);
295 MIC_HDR2[6] = byTmp & 0x0f;
296 MIC_HDR2[7] = 0;
297 if (bA4) {
298 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN);
299 } else {
300 MIC_HDR2[8] = 0x00;
301 MIC_HDR2[9] = 0x00;
302 MIC_HDR2[10] = 0x00;
303 MIC_HDR2[11] = 0x00;
304 MIC_HDR2[12] = 0x00;
305 MIC_HDR2[13] = 0x00;
306 }
307 MIC_HDR2[14] = 0x00;
308 MIC_HDR2[15] = 0x00;
Forest Bond5449c682009-04-25 10:30:44 -0400309
Tülin İzer600816c2013-05-15 23:41:28 +0300310 /* CCMP */
Joe Perches659b4d92013-03-18 10:44:37 -0700311 AESv128(pbyRxKey, MIC_IV, abyMIC);
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100312 for (kk = 0; kk < 16; kk++)
Joe Perches659b4d92013-03-18 10:44:37 -0700313 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
Joe Perches659b4d92013-03-18 10:44:37 -0700314 AESv128(pbyRxKey, abyTmp, abyMIC);
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100315 for (kk = 0; kk < 16; kk++)
Joe Perches659b4d92013-03-18 10:44:37 -0700316 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
Joe Perches659b4d92013-03-18 10:44:37 -0700317 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond5449c682009-04-25 10:30:44 -0400318
Joe Perches659b4d92013-03-18 10:44:37 -0700319 wCnt = 1;
320 abyCTRPLD[0] = 0x01;
321 memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
Forest Bond5449c682009-04-25 10:30:44 -0400322
Joe Perches659b4d92013-03-18 10:44:37 -0700323 for (jj = wPayloadSize; jj > 16; jj = jj - 16) {
Joe Perches659b4d92013-03-18 10:44:37 -0700324 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
325 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
Forest Bond5449c682009-04-25 10:30:44 -0400326
Joe Perches659b4d92013-03-18 10:44:37 -0700327 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
Forest Bond5449c682009-04-25 10:30:44 -0400328
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100329 for (kk = 0; kk < 16; kk++)
Joe Perches659b4d92013-03-18 10:44:37 -0700330 abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100331 for (kk = 0; kk < 16; kk++)
Joe Perches659b4d92013-03-18 10:44:37 -0700332 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
Joe Perches659b4d92013-03-18 10:44:37 -0700333 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond5449c682009-04-25 10:30:44 -0400334
Joe Perches659b4d92013-03-18 10:44:37 -0700335 memcpy(pbyPayload, abyPlainText, 16);
336 wCnt++;
337 pbyPayload += 16;
Tülin İzer600816c2013-05-15 23:41:28 +0300338 } /* for wPayloadSize */
Forest Bond5449c682009-04-25 10:30:44 -0400339
Tülin İzer600816c2013-05-15 23:41:28 +0300340 /* last payload */
Joe Perches659b4d92013-03-18 10:44:37 -0700341 memcpy(&(abyLastCipher[0]), pbyPayload, jj);
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100342 for (ii = jj; ii < 16; ii++)
Joe Perches659b4d92013-03-18 10:44:37 -0700343 abyLastCipher[ii] = 0x00;
Forest Bond5449c682009-04-25 10:30:44 -0400344
Joe Perches659b4d92013-03-18 10:44:37 -0700345 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
346 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
Forest Bond5449c682009-04-25 10:30:44 -0400347
Joe Perches659b4d92013-03-18 10:44:37 -0700348 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100349 for (kk = 0; kk < 16; kk++)
Joe Perches659b4d92013-03-18 10:44:37 -0700350 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
Joe Perches659b4d92013-03-18 10:44:37 -0700351 memcpy(pbyPayload, abyPlainText, jj);
352 pbyPayload += jj;
Forest Bond5449c682009-04-25 10:30:44 -0400353
Tülin İzer600816c2013-05-15 23:41:28 +0300354 /* for MIC calculation */
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100355 for (ii = jj; ii < 16; ii++)
Joe Perches659b4d92013-03-18 10:44:37 -0700356 abyPlainText[ii] = 0x00;
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100357 for (kk = 0; kk < 16; kk++)
Joe Perches659b4d92013-03-18 10:44:37 -0700358 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
Joe Perches659b4d92013-03-18 10:44:37 -0700359 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond5449c682009-04-25 10:30:44 -0400360
Tülin İzer600816c2013-05-15 23:41:28 +0300361 /* =>above is the calculate MIC */
362 /* -------------------------------------------- */
Forest Bond5449c682009-04-25 10:30:44 -0400363
Joe Perches659b4d92013-03-18 10:44:37 -0700364 wCnt = 0;
365 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
366 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
367 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
Jelena Bjeljae82efb22014-03-14 16:47:06 +0100368 for (kk = 0; kk < 8; kk++)
Joe Perches659b4d92013-03-18 10:44:37 -0700369 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
Tülin İzer600816c2013-05-15 23:41:28 +0300370 /* =>above is the dec-MIC from packet */
371 /* -------------------------------------------- */
Forest Bond5449c682009-04-25 10:30:44 -0400372
Tapasweni Pathakfd7dcd32014-09-28 18:05:05 +0530373 return !memcmp(abyMIC, abyTmp, 8);
Forest Bond5449c682009-04-25 10:30:44 -0400374}