blob: f7a3b8f8da708e55aeb290670bba8f49144e6794 [file] [log] [blame]
Forest Bond92b96792009-06-13 07:38:31 -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 *
Forest Bond92b96792009-06-13 07:38:31 -040019 * File: aes_ccmp.c
20 *
21 * Purpose: AES_CCMP decryption
22 *
23 * Author: Warren Hsu
24 *
25 * Date: Feb 15, 2005
26 *
27 * Functions:
28 * AESbGenCCMP - Parsing RX-packet
29 *
Forest Bond92b96792009-06-13 07:38:31 -040030 * Revision History:
Forest Bond92b96792009-06-13 07:38:31 -040031 */
32
Forest Bond92b96792009-06-13 07:38:31 -040033#include "device.h"
Forest Bond92b96792009-06-13 07:38:31 -040034#include "80211hdr.h"
Forest Bond92b96792009-06-13 07:38:31 -040035
36/*--------------------- Static Definitions -------------------------*/
37
38/*--------------------- Static Classes ----------------------------*/
39
40/*--------------------- Static Variables --------------------------*/
41
42/*
43 * SBOX Table
44 */
45
Andres More8ff23772010-05-09 22:20:09 -030046BYTE sbox_table[256] = {
47 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
48 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
49 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
50 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
51 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
52 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
53 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
54 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
55 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
56 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
57 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
58 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
59 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
60 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
61 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
62 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
Forest Bond92b96792009-06-13 07:38:31 -040063};
64
65BYTE dot2_table[256] = {
Andres More8ff23772010-05-09 22:20:09 -030066 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
67 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
68 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
69 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
70 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
71 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
72 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
73 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
74 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
75 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
76 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
77 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
78 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
79 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
80 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
81 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
Forest Bond92b96792009-06-13 07:38:31 -040082};
83
84BYTE dot3_table[256] = {
Andres More8ff23772010-05-09 22:20:09 -030085 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
86 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
87 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
88 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
89 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
90 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
91 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
92 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
93 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
94 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
95 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
96 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
97 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
98 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
99 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
100 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
Forest Bond92b96792009-06-13 07:38:31 -0400101};
102
103/*--------------------- Static Functions --------------------------*/
104
105/*--------------------- Export Variables --------------------------*/
106
107/*--------------------- Export Functions --------------------------*/
108
Otavio Salvadord5006482010-05-21 19:08:14 -0300109static void xor_128(BYTE *a, BYTE *b, BYTE *out)
Forest Bond92b96792009-06-13 07:38:31 -0400110{
Andres More8ff23772010-05-09 22:20:09 -0300111 PDWORD dwPtrA = (PDWORD) a;
112 PDWORD dwPtrB = (PDWORD) b;
113 PDWORD dwPtrOut = (PDWORD) out;
Forest Bond92b96792009-06-13 07:38:31 -0400114
Andres More8ff23772010-05-09 22:20:09 -0300115 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
116 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
117 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
118 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
Forest Bond92b96792009-06-13 07:38:31 -0400119}
120
121
Otavio Salvadord5006482010-05-21 19:08:14 -0300122static void xor_32(BYTE *a, BYTE *b, BYTE *out)
Forest Bond92b96792009-06-13 07:38:31 -0400123{
Andres More8ff23772010-05-09 22:20:09 -0300124 PDWORD dwPtrA = (PDWORD) a;
125 PDWORD dwPtrB = (PDWORD) b;
126 PDWORD dwPtrOut = (PDWORD) out;
Forest Bond92b96792009-06-13 07:38:31 -0400127
Andres More8ff23772010-05-09 22:20:09 -0300128 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
Forest Bond92b96792009-06-13 07:38:31 -0400129}
130
131void AddRoundKey(BYTE *key, int round)
132{
Andres More8ff23772010-05-09 22:20:09 -0300133 BYTE sbox_key[4];
134 BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
Forest Bond92b96792009-06-13 07:38:31 -0400135
Andres More8ff23772010-05-09 22:20:09 -0300136 sbox_key[0] = sbox_table[key[13]];
137 sbox_key[1] = sbox_table[key[14]];
138 sbox_key[2] = sbox_table[key[15]];
139 sbox_key[3] = sbox_table[key[12]];
Forest Bond92b96792009-06-13 07:38:31 -0400140
Andres More8ff23772010-05-09 22:20:09 -0300141 key[0] = key[0] ^ rcon_table[round];
142 xor_32(&key[0], sbox_key, &key[0]);
Forest Bond92b96792009-06-13 07:38:31 -0400143
Andres More8ff23772010-05-09 22:20:09 -0300144 xor_32(&key[4], &key[0], &key[4]);
145 xor_32(&key[8], &key[4], &key[8]);
146 xor_32(&key[12], &key[8], &key[12]);
Forest Bond92b96792009-06-13 07:38:31 -0400147}
148
149void SubBytes(BYTE *in, BYTE *out)
150{
Andres More8ff23772010-05-09 22:20:09 -0300151 int i;
Forest Bond92b96792009-06-13 07:38:31 -0400152
Andres More8ff23772010-05-09 22:20:09 -0300153 for (i = 0; i < 16; i++)
154 out[i] = sbox_table[in[i]];
Forest Bond92b96792009-06-13 07:38:31 -0400155}
156
157void ShiftRows(BYTE *in, BYTE *out)
158{
Andres More8ff23772010-05-09 22:20:09 -0300159 out[0] = in[0];
160 out[1] = in[5];
161 out[2] = in[10];
162 out[3] = in[15];
163 out[4] = in[4];
164 out[5] = in[9];
165 out[6] = in[14];
166 out[7] = in[3];
167 out[8] = in[8];
168 out[9] = in[13];
169 out[10] = in[2];
170 out[11] = in[7];
171 out[12] = in[12];
172 out[13] = in[1];
173 out[14] = in[6];
174 out[15] = in[11];
Forest Bond92b96792009-06-13 07:38:31 -0400175}
176
177void MixColumns(BYTE *in, BYTE *out)
178{
179
Andres More8ff23772010-05-09 22:20:09 -0300180 out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
181 out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
182 out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
183 out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
Forest Bond92b96792009-06-13 07:38:31 -0400184}
185
Forest Bond92b96792009-06-13 07:38:31 -0400186void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext)
187{
Andres More8ff23772010-05-09 22:20:09 -0300188 int i;
189 int round;
190 BYTE TmpdataA[16];
191 BYTE TmpdataB[16];
192 BYTE abyRoundKey[16];
Forest Bond92b96792009-06-13 07:38:31 -0400193
Andres More8ff23772010-05-09 22:20:09 -0300194 for (i = 0; i < 16; i++)
195 abyRoundKey[i] = key[i];
Forest Bond92b96792009-06-13 07:38:31 -0400196
Andres More8ff23772010-05-09 22:20:09 -0300197 for (round = 0; round < 11; round++) {
198 if (round == 0) {
199 xor_128(abyRoundKey, data, ciphertext);
200 AddRoundKey(abyRoundKey, round);
201 } else if (round == 10) {
202 SubBytes(ciphertext, TmpdataA);
203 ShiftRows(TmpdataA, TmpdataB);
204 xor_128(TmpdataB, abyRoundKey, ciphertext);
205 } else { /* round 1 ~ 9 */
206 SubBytes(ciphertext, TmpdataA);
207 ShiftRows(TmpdataA, TmpdataB);
208 MixColumns(&TmpdataB[0], &TmpdataA[0]);
209 MixColumns(&TmpdataB[4], &TmpdataA[4]);
210 MixColumns(&TmpdataB[8], &TmpdataA[8]);
211 MixColumns(&TmpdataB[12], &TmpdataA[12]);
212 xor_128(TmpdataA, abyRoundKey, ciphertext);
213 AddRoundKey(abyRoundKey, round);
214 }
215 }
Forest Bond92b96792009-06-13 07:38:31 -0400216
217}
218
219/*
220 * Description: AES decryption
221 *
222 * Parameters:
223 * In:
224 * pbyRxKey - The key used to decrypt
225 * pbyFrame - Starting address of packet header
226 * wFrameSize - Total packet size including CRC
227 * Out:
228 * none
229 *
230 * Return Value: MIC compare result
231 *
232 */
Andres More8ff23772010-05-09 22:20:09 -0300233
Forest Bond92b96792009-06-13 07:38:31 -0400234BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize)
235{
Andres More8ff23772010-05-09 22:20:09 -0300236 BYTE abyNonce[13];
237 BYTE MIC_IV[16];
238 BYTE MIC_HDR1[16];
239 BYTE MIC_HDR2[16];
240 BYTE abyMIC[16];
241 BYTE abyCTRPLD[16];
242 BYTE abyTmp[16];
243 BYTE abyPlainText[16];
244 BYTE abyLastCipher[16];
Forest Bond92b96792009-06-13 07:38:31 -0400245
Andres More8ff23772010-05-09 22:20:09 -0300246 PS802_11Header pMACHeader = (PS802_11Header) pbyFrame;
247 PBYTE pbyIV;
248 PBYTE pbyPayload;
249 WORD wHLen = 22;
250 /* 8 is IV, 8 is MIC, 4 is CRC */
251 WORD wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;
252 BOOL bA4 = FALSE;
253 BYTE byTmp;
254 WORD wCnt;
255 int ii, jj, kk;
Forest Bond92b96792009-06-13 07:38:31 -0400256
Andres More8ff23772010-05-09 22:20:09 -0300257 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
258 if (WLAN_GET_FC_TODS(*(PWORD) pbyFrame) &&
259 WLAN_GET_FC_FROMDS(*(PWORD) pbyFrame)) {
260 bA4 = TRUE;
261 pbyIV += 6; /* 6 is 802.11 address4 */
262 wHLen += 6;
263 wPayloadSize -= 6;
264 }
265 pbyPayload = pbyIV + 8; /* IV-length */
Forest Bond92b96792009-06-13 07:38:31 -0400266
Andres More8ff23772010-05-09 22:20:09 -0300267 abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */
268 memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN);
269 abyNonce[7] = pbyIV[7];
270 abyNonce[8] = pbyIV[6];
271 abyNonce[9] = pbyIV[5];
272 abyNonce[10] = pbyIV[4];
273 abyNonce[11] = pbyIV[1];
274 abyNonce[12] = pbyIV[0];
Forest Bond92b96792009-06-13 07:38:31 -0400275
Andres More8ff23772010-05-09 22:20:09 -0300276 /* MIC_IV */
277 MIC_IV[0] = 0x59;
278 memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
279 MIC_IV[14] = (BYTE)(wPayloadSize >> 8);
280 MIC_IV[15] = (BYTE)(wPayloadSize & 0xff);
Forest Bond92b96792009-06-13 07:38:31 -0400281
Andres More8ff23772010-05-09 22:20:09 -0300282 /* MIC_HDR1 */
283 MIC_HDR1[0] = (BYTE)(wHLen >> 8);
284 MIC_HDR1[1] = (BYTE)(wHLen & 0xff);
285 byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff);
286 MIC_HDR1[2] = byTmp & 0x8f;
287 byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8);
288 byTmp &= 0x87;
289 MIC_HDR1[3] = byTmp | 0x40;
290 memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN);
291 memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400292
Andres More8ff23772010-05-09 22:20:09 -0300293 /* MIC_HDR2 */
294 memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN);
295 byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff);
296 MIC_HDR2[6] = byTmp & 0x0f;
297 MIC_HDR2[7] = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400298
Andres More8ff23772010-05-09 22:20:09 -0300299 if (bA4) {
Andres More9a0e7562010-04-13 21:54:48 -0300300 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN);
Andres More8ff23772010-05-09 22:20:09 -0300301 } 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 Bond92b96792009-06-13 07:38:31 -0400311
Andres More8ff23772010-05-09 22:20:09 -0300312 /* CCMP */
313 AESv128(pbyRxKey, MIC_IV, abyMIC);
314 for (kk = 0; kk < 16; kk++)
315 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
Forest Bond92b96792009-06-13 07:38:31 -0400316
Andres More8ff23772010-05-09 22:20:09 -0300317 AESv128(pbyRxKey, abyTmp, abyMIC);
318 for (kk = 0; kk < 16; kk++)
319 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
Forest Bond92b96792009-06-13 07:38:31 -0400320
Andres More8ff23772010-05-09 22:20:09 -0300321 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400322
Andres More8ff23772010-05-09 22:20:09 -0300323 wCnt = 1;
324 abyCTRPLD[0] = 0x01;
325 memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
Forest Bond92b96792009-06-13 07:38:31 -0400326
Andres More8ff23772010-05-09 22:20:09 -0300327 for (jj = wPayloadSize; jj > 16; jj = jj-16) {
Forest Bond92b96792009-06-13 07:38:31 -0400328
Andres More8ff23772010-05-09 22:20:09 -0300329 abyCTRPLD[14] = (BYTE) (wCnt >> 8);
330 abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
Forest Bond92b96792009-06-13 07:38:31 -0400331
Andres More8ff23772010-05-09 22:20:09 -0300332 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
Forest Bond92b96792009-06-13 07:38:31 -0400333
Andres More8ff23772010-05-09 22:20:09 -0300334 for (kk = 0; kk < 16; kk++)
335 abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
Forest Bond92b96792009-06-13 07:38:31 -0400336
Andres More8ff23772010-05-09 22:20:09 -0300337 for (kk = 0; kk < 16; kk++)
338 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
Forest Bond92b96792009-06-13 07:38:31 -0400339
Andres More8ff23772010-05-09 22:20:09 -0300340 AESv128(pbyRxKey, abyTmp, abyMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400341
Andres More8ff23772010-05-09 22:20:09 -0300342 memcpy(pbyPayload, abyPlainText, 16);
343 wCnt++;
344 pbyPayload += 16;
345 } /* for wPayloadSize */
Forest Bond92b96792009-06-13 07:38:31 -0400346
Andres More8ff23772010-05-09 22:20:09 -0300347 /* last payload */
348 memcpy(&(abyLastCipher[0]), pbyPayload, jj);
349 for (ii = jj; ii < 16; ii++)
350 abyLastCipher[ii] = 0x00;
Forest Bond92b96792009-06-13 07:38:31 -0400351
Andres More8ff23772010-05-09 22:20:09 -0300352 abyCTRPLD[14] = (BYTE) (wCnt >> 8);
353 abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
Forest Bond92b96792009-06-13 07:38:31 -0400354
Andres More8ff23772010-05-09 22:20:09 -0300355 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
356 for (kk = 0; kk < 16; kk++)
357 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
Forest Bond92b96792009-06-13 07:38:31 -0400358
Andres More8ff23772010-05-09 22:20:09 -0300359 memcpy(pbyPayload, abyPlainText, jj);
360 pbyPayload += jj;
361
362 /* for MIC calculation */
363 for (ii = jj; ii < 16; ii++)
364 abyPlainText[ii] = 0x00;
365 for (kk = 0; kk < 16; kk++)
366 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
367
368 AESv128(pbyRxKey, abyTmp, abyMIC);
369
370 /* => above is the calculated MIC */
371
372 wCnt = 0;
373 abyCTRPLD[14] = (BYTE) (wCnt >> 8);
374 abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
375 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
376
377 for (kk = 0; kk < 8; kk++)
378 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
379
380 /* => above is the packet dec-MIC */
381
382 if (!memcmp(abyMIC, abyTmp, 8))
383 return TRUE;
384 else
385 return FALSE;
Forest Bond92b96792009-06-13 07:38:31 -0400386}