]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/rt2860/common/cmm_aes.c
Fix common misspellings
[mirror_ubuntu-artful-kernel.git] / drivers / staging / rt2860 / common / cmm_aes.c
CommitLineData
91980990
GKH
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
ca97b838
BZ
27 Module Name:
28 cmm_aes.c
91980990
GKH
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
ca97b838
BZ
35 Paul Wu 02-25-02 Initial
36*/
91980990 37
ca97b838 38#include "../rt_config.h"
91980990 39
62eb734b 40struct aes_context {
51126deb
BZ
41 u32 erk[64]; /* encryption round keys */
42 u32 drk[64]; /* decryption round keys */
96b3c83d 43 int nr; /* number of rounds */
62eb734b 44};
91980990 45
ca97b838
BZ
46/*****************************/
47/******** SBOX Table *********/
48/*****************************/
91980990 49
51126deb 50u8 SboxTable[256] = {
ca97b838
BZ
51 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
52 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
53 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
54 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
55 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
56 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
57 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
58 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
59 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
60 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
61 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
62 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
63 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
64 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
65 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
66 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
67 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
68 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
69 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
70 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
71 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
72 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
73 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
74 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
75 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
76 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
77 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
78 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
79 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
80 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
81 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
82 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
83};
91980990 84
51126deb 85void xor_32(u8 *a, u8 *b, u8 *out)
ca97b838 86{
51126deb 87 int i;
91980990 88
96b3c83d 89 for (i = 0; i < 4; i++) {
ca97b838 90 out[i] = a[i] ^ b[i];
91980990 91 }
91980990
GKH
92}
93
51126deb 94void xor_128(u8 *a, u8 *b, u8 *out)
91980990 95{
51126deb 96 int i;
91980990 97
96b3c83d 98 for (i = 0; i < 16; i++) {
ca97b838
BZ
99 out[i] = a[i] ^ b[i];
100 }
91980990
GKH
101}
102
51126deb 103u8 RTMPCkipSbox(u8 a)
91980990 104{
ca97b838 105 return SboxTable[(int)a];
91980990
GKH
106}
107
51126deb 108void next_key(u8 *key, int round)
91980990 109{
51126deb
BZ
110 u8 rcon;
111 u8 sbox_key[4];
112 u8 rcon_table[12] = {
ca97b838
BZ
113 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
114 0x1b, 0x36, 0x36, 0x36
115 };
91980990 116
ca97b838
BZ
117 sbox_key[0] = RTMPCkipSbox(key[13]);
118 sbox_key[1] = RTMPCkipSbox(key[14]);
119 sbox_key[2] = RTMPCkipSbox(key[15]);
120 sbox_key[3] = RTMPCkipSbox(key[12]);
91980990 121
ca97b838 122 rcon = rcon_table[round];
91980990 123
ca97b838
BZ
124 xor_32(&key[0], sbox_key, &key[0]);
125 key[0] = key[0] ^ rcon;
91980990 126
ca97b838
BZ
127 xor_32(&key[4], &key[0], &key[4]);
128 xor_32(&key[8], &key[4], &key[8]);
129 xor_32(&key[12], &key[8], &key[12]);
91980990
GKH
130}
131
51126deb 132void byte_sub(u8 *in, u8 *out)
91980990 133{
51126deb 134 int i;
91980990 135
96b3c83d 136 for (i = 0; i < 16; i++) {
ca97b838
BZ
137 out[i] = RTMPCkipSbox(in[i]);
138 }
139}
91980990 140
ca97b838
BZ
141/************************************/
142/* bitwise_xor() */
143/* A 128 bit, bitwise exclusive or */
144/************************************/
91980990 145
ca97b838
BZ
146void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
147{
148 int i;
96b3c83d 149 for (i = 0; i < 16; i++) {
ca97b838
BZ
150 out[i] = ina[i] ^ inb[i];
151 }
152}
91980990 153
51126deb 154void shift_row(u8 *in, u8 *out)
ca97b838 155{
96b3c83d
BZ
156 out[0] = in[0];
157 out[1] = in[5];
158 out[2] = in[10];
159 out[3] = in[15];
160 out[4] = in[4];
161 out[5] = in[9];
162 out[6] = in[14];
163 out[7] = in[3];
164 out[8] = in[8];
165 out[9] = in[13];
ca97b838
BZ
166 out[10] = in[2];
167 out[11] = in[7];
168 out[12] = in[12];
169 out[13] = in[1];
170 out[14] = in[6];
171 out[15] = in[11];
172}
91980990 173
51126deb 174void mix_column(u8 *in, u8 *out)
ca97b838 175{
51126deb
BZ
176 int i;
177 u8 add1b[4];
178 u8 add1bf7[4];
179 u8 rotl[4];
180 u8 swap_halfs[4];
181 u8 andf7[4];
182 u8 rotr[4];
183 u8 temp[4];
184 u8 tempb[4];
96b3c83d
BZ
185
186 for (i = 0; i < 4; i++) {
187 if ((in[i] & 0x80) == 0x80)
ca97b838
BZ
188 add1b[i] = 0x1b;
189 else
190 add1b[i] = 0x00;
191 }
91980990 192
96b3c83d 193 swap_halfs[0] = in[2]; /* Swap halfs */
ca97b838
BZ
194 swap_halfs[1] = in[3];
195 swap_halfs[2] = in[0];
196 swap_halfs[3] = in[1];
91980990 197
96b3c83d 198 rotl[0] = in[3]; /* Rotate left 8 bits */
ca97b838
BZ
199 rotl[1] = in[0];
200 rotl[2] = in[1];
201 rotl[3] = in[2];
91980990 202
ca97b838
BZ
203 andf7[0] = in[0] & 0x7f;
204 andf7[1] = in[1] & 0x7f;
205 andf7[2] = in[2] & 0x7f;
206 andf7[3] = in[3] & 0x7f;
91980990 207
96b3c83d 208 for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
ca97b838 209 andf7[i] = andf7[i] << 1;
96b3c83d 210 if ((andf7[i - 1] & 0x80) == 0x80) {
ca97b838
BZ
211 andf7[i] = (andf7[i] | 0x01);
212 }
213 }
214 andf7[0] = andf7[0] << 1;
215 andf7[0] = andf7[0] & 0xfe;
91980990 216
ca97b838 217 xor_32(add1b, andf7, add1bf7);
91980990 218
ca97b838 219 xor_32(in, add1bf7, rotr);
91980990 220
96b3c83d 221 temp[0] = rotr[0]; /* Rotate right 8 bits */
ca97b838
BZ
222 rotr[0] = rotr[1];
223 rotr[1] = rotr[2];
224 rotr[2] = rotr[3];
225 rotr[3] = temp[0];
91980990 226
ca97b838 227 xor_32(add1bf7, rotr, temp);
96b3c83d 228 xor_32(swap_halfs, rotl, tempb);
ca97b838
BZ
229 xor_32(temp, tempb, out);
230}
91980990 231
ca97b838
BZ
232/************************************************/
233/* construct_mic_header1() */
234/* Builds the first MIC header block from */
235/* header fields. */
236/************************************************/
91980990 237
96b3c83d
BZ
238void construct_mic_header1(unsigned char *mic_header1,
239 int header_length, unsigned char *mpdu)
91980990 240{
ca97b838
BZ
241 mic_header1[0] = (unsigned char)((header_length - 2) / 256);
242 mic_header1[1] = (unsigned char)((header_length - 2) % 256);
96b3c83d
BZ
243 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
244 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
245 mic_header1[4] = mpdu[4]; /* A1 */
ca97b838
BZ
246 mic_header1[5] = mpdu[5];
247 mic_header1[6] = mpdu[6];
248 mic_header1[7] = mpdu[7];
249 mic_header1[8] = mpdu[8];
250 mic_header1[9] = mpdu[9];
96b3c83d 251 mic_header1[10] = mpdu[10]; /* A2 */
ca97b838
BZ
252 mic_header1[11] = mpdu[11];
253 mic_header1[12] = mpdu[12];
254 mic_header1[13] = mpdu[13];
255 mic_header1[14] = mpdu[14];
256 mic_header1[15] = mpdu[15];
91980990
GKH
257}
258
ca97b838
BZ
259/************************************************/
260/* construct_mic_header2() */
261/* Builds the last MIC header block from */
262/* header fields. */
263/************************************************/
264
96b3c83d
BZ
265void construct_mic_header2(unsigned char *mic_header2,
266 unsigned char *mpdu, int a4_exists, int qc_exists)
91980990 267{
ca97b838 268 int i;
91980990 269
96b3c83d
BZ
270 for (i = 0; i < 16; i++)
271 mic_header2[i] = 0x00;
91980990 272
96b3c83d 273 mic_header2[0] = mpdu[16]; /* A3 */
ca97b838
BZ
274 mic_header2[1] = mpdu[17];
275 mic_header2[2] = mpdu[18];
276 mic_header2[3] = mpdu[19];
277 mic_header2[4] = mpdu[20];
278 mic_header2[5] = mpdu[21];
91980990 279
ec278fa2 280 /* In Sequence Control field, mute sequence numer bits (12-bit) */
96b3c83d
BZ
281 mic_header2[6] = mpdu[22] & 0x0f; /* SC */
282 mic_header2[7] = 0x00; /* mpdu[23]; */
91980990 283
64ff4044 284 if ((!qc_exists) && a4_exists) {
96b3c83d
BZ
285 for (i = 0; i < 6; i++)
286 mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
91980990 287
ca97b838 288 }
91980990 289
96b3c83d
BZ
290 if (qc_exists && (!a4_exists)) {
291 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
ca97b838
BZ
292 mic_header2[9] = mpdu[25] & 0x00;
293 }
91980990 294
96b3c83d
BZ
295 if (qc_exists && a4_exists) {
296 for (i = 0; i < 6; i++)
297 mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
91980990 298
ca97b838
BZ
299 mic_header2[14] = mpdu[30] & 0x0f;
300 mic_header2[15] = mpdu[31] & 0x00;
301 }
302}
91980990 303
ca97b838
BZ
304/************************************************/
305/* construct_mic_iv() */
306/* Builds the MIC IV from header fields and PN */
307/************************************************/
91980990 308
96b3c83d
BZ
309void construct_mic_iv(unsigned char *mic_iv,
310 int qc_exists,
311 int a4_exists,
312 unsigned char *mpdu,
313 unsigned int payload_length, unsigned char *pn_vector)
ca97b838
BZ
314{
315 int i;
316
317 mic_iv[0] = 0x59;
318 if (qc_exists && a4_exists)
96b3c83d 319 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
ca97b838 320 if (qc_exists && !a4_exists)
96b3c83d 321 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
ca97b838
BZ
322 if (!qc_exists)
323 mic_iv[1] = 0x00;
324 for (i = 2; i < 8; i++)
96b3c83d 325 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
ca97b838 326#ifdef CONSISTENT_PN_ORDER
96b3c83d
BZ
327 for (i = 8; i < 14; i++)
328 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
ca97b838 329#else
96b3c83d
BZ
330 for (i = 8; i < 14; i++)
331 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
ca97b838 332#endif
96b3c83d
BZ
333 mic_iv[14] = (unsigned char)(payload_length / 256);
334 mic_iv[15] = (unsigned char)(payload_length % 256);
91980990
GKH
335
336}
337
ca97b838
BZ
338/****************************************/
339/* aes128k128d() */
340/* Performs a 128 bit AES encrypt with */
341/* 128 bit data. */
342/****************************************/
96b3c83d
BZ
343void aes128k128d(unsigned char *key, unsigned char *data,
344 unsigned char *ciphertext)
91980990 345{
ca97b838
BZ
346 int round;
347 int i;
348 unsigned char intermediatea[16];
349 unsigned char intermediateb[16];
350 unsigned char round_key[16];
91980990 351
96b3c83d
BZ
352 for (i = 0; i < 16; i++)
353 round_key[i] = key[i];
91980990 354
96b3c83d
BZ
355 for (round = 0; round < 11; round++) {
356 if (round == 0) {
ca97b838
BZ
357 xor_128(round_key, data, ciphertext);
358 next_key(round_key, round);
96b3c83d 359 } else if (round == 10) {
ca97b838
BZ
360 byte_sub(ciphertext, intermediatea);
361 shift_row(intermediatea, intermediateb);
362 xor_128(intermediateb, round_key, ciphertext);
96b3c83d
BZ
363 } else { /* 1 - 9 */
364
ca97b838
BZ
365 byte_sub(ciphertext, intermediatea);
366 shift_row(intermediatea, intermediateb);
367 mix_column(&intermediateb[0], &intermediatea[0]);
368 mix_column(&intermediateb[4], &intermediatea[4]);
369 mix_column(&intermediateb[8], &intermediatea[8]);
370 mix_column(&intermediateb[12], &intermediatea[12]);
371 xor_128(intermediatea, round_key, ciphertext);
372 next_key(round_key, round);
373 }
374 }
91980990 375
ca97b838 376}
91980990 377
96b3c83d
BZ
378void construct_ctr_preload(unsigned char *ctr_preload,
379 int a4_exists,
380 int qc_exists,
381 unsigned char *mpdu, unsigned char *pn_vector, int c)
ca97b838 382{
91980990 383
ca97b838 384 int i = 0;
96b3c83d
BZ
385 for (i = 0; i < 16; i++)
386 ctr_preload[i] = 0x00;
ca97b838
BZ
387 i = 0;
388
96b3c83d
BZ
389 ctr_preload[0] = 0x01; /* flag */
390 if (qc_exists && a4_exists)
391 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
392 if (qc_exists && !a4_exists)
393 ctr_preload[1] = mpdu[24] & 0x0f;
ca97b838
BZ
394
395 for (i = 2; i < 8; i++)
96b3c83d 396 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
ca97b838 397#ifdef CONSISTENT_PN_ORDER
96b3c83d
BZ
398 for (i = 8; i < 14; i++)
399 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
ca97b838 400#else
96b3c83d
BZ
401 for (i = 8; i < 14; i++)
402 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
ca97b838 403#endif
ec278fa2 404 ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */
96b3c83d 405 ctr_preload[15] = (unsigned char)(c % 256);
91980990 406
91980990
GKH
407}
408
62eb734b 409BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd,
51126deb 410 u8 *pData,
62eb734b 411 unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey)
91980990 412{
51126deb
BZ
413 u8 KeyID;
414 u32 HeaderLen;
415 u8 PN[6];
416 u32 payload_len;
417 u32 num_blocks;
418 u32 payload_remainder;
419 u16 fc;
420 u8 fc0;
421 u8 fc1;
422 u32 frame_type;
423 u32 frame_subtype;
424 u32 from_ds;
425 u32 to_ds;
426 int a4_exists;
427 int qc_exists;
428 u8 aes_out[16];
96b3c83d 429 int payload_index;
51126deb
BZ
430 u32 i;
431 u8 ctr_preload[16];
432 u8 chain_buffer[16];
433 u8 padded_buffer[16];
434 u8 mic_iv[16];
435 u8 mic_header1[16];
436 u8 mic_header2[16];
437 u8 MIC[8];
438 u8 TrailMIC[8];
ca97b838
BZ
439
440 fc0 = *pData;
441 fc1 = *(pData + 1);
442
51126deb 443 fc = *((u16 *)pData);
ca97b838
BZ
444
445 frame_type = ((fc0 >> 2) & 0x03);
446 frame_subtype = ((fc0 >> 4) & 0x0f);
447
448 from_ds = (fc1 & 0x2) >> 1;
449 to_ds = (fc1 & 0x1);
450
451 a4_exists = (from_ds & to_ds);
96b3c83d
BZ
452 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
453 (frame_subtype == 0x09) || /* Likely to change. */
454 (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
455 );
ca97b838
BZ
456
457 HeaderLen = 24;
458 if (a4_exists)
459 HeaderLen += 6;
460
51126deb 461 KeyID = *((u8 *)(pData + HeaderLen + 3));
ca97b838
BZ
462 KeyID = KeyID >> 6;
463
96b3c83d
BZ
464 if (pWpaKey[KeyID].KeyLen == 0) {
465 DBGPRINT(RT_DEBUG_TRACE,
466 ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n",
467 KeyID));
ca97b838
BZ
468 return FALSE;
469 }
91980990 470
96b3c83d
BZ
471 PN[0] = *(pData + HeaderLen);
472 PN[1] = *(pData + HeaderLen + 1);
473 PN[2] = *(pData + HeaderLen + 4);
474 PN[3] = *(pData + HeaderLen + 5);
475 PN[4] = *(pData + HeaderLen + 6);
476 PN[5] = *(pData + HeaderLen + 7);
91980990 477
ec278fa2 478 payload_len = DataByteCnt - HeaderLen - 8 - 8; /* 8 bytes for CCMP header , 8 bytes for MIC */
ca97b838
BZ
479 payload_remainder = (payload_len) % 16;
480 num_blocks = (payload_len) / 16;
91980990 481
ec278fa2
BZ
482 /* Find start of payload */
483 payload_index = HeaderLen + 8; /*IV+EIV */
91980990 484
96b3c83d 485 for (i = 0; i < num_blocks; i++) {
ca97b838 486 construct_ctr_preload(ctr_preload,
96b3c83d 487 a4_exists, qc_exists, pData, PN, i + 1);
ca97b838
BZ
488
489 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
490
491 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
492 NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
493 payload_index += 16;
494 }
91980990 495
ec278fa2
BZ
496 /* */
497 /* If there is a short final block, then pad it */
498 /* encrypt it and copy the unpadded part back */
499 /* */
96b3c83d 500 if (payload_remainder > 0) {
ca97b838 501 construct_ctr_preload(ctr_preload,
96b3c83d
BZ
502 a4_exists,
503 qc_exists, pData, PN, num_blocks + 1);
91980990 504
ca97b838 505 NdisZeroMemory(padded_buffer, 16);
96b3c83d
BZ
506 NdisMoveMemory(padded_buffer, pData + payload_index,
507 payload_remainder);
91980990 508
ca97b838 509 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
91980990 510
ca97b838 511 bitwise_xor(aes_out, padded_buffer, chain_buffer);
96b3c83d
BZ
512 NdisMoveMemory(pData + payload_index - 8, chain_buffer,
513 payload_remainder);
ca97b838
BZ
514 payload_index += payload_remainder;
515 }
ec278fa2
BZ
516 /* */
517 /* Descrypt the MIC */
518 /* */
96b3c83d 519 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pData, PN, 0);
ca97b838
BZ
520 NdisZeroMemory(padded_buffer, 16);
521 NdisMoveMemory(padded_buffer, pData + payload_index, 8);
522
523 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
524
525 bitwise_xor(aes_out, padded_buffer, chain_buffer);
526
527 NdisMoveMemory(TrailMIC, chain_buffer, 8);
528
ec278fa2
BZ
529 /* */
530 /* Calculate MIC */
531 /* */
ca97b838 532
ec278fa2 533 /*Force the protected frame bit on */
ca97b838
BZ
534 *(pData + 1) = *(pData + 1) | 0x40;
535
ec278fa2
BZ
536 /* Find start of payload */
537 /* Because the CCMP header has been removed */
ca97b838
BZ
538 payload_index = HeaderLen;
539
96b3c83d
BZ
540 construct_mic_iv(mic_iv, qc_exists, a4_exists, pData, payload_len, PN);
541
542 construct_mic_header1(mic_header1, HeaderLen, pData);
543
544 construct_mic_header2(mic_header2, pData, a4_exists, qc_exists);
ca97b838
BZ
545
546 aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
547 bitwise_xor(aes_out, mic_header1, chain_buffer);
548 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
549 bitwise_xor(aes_out, mic_header2, chain_buffer);
550 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
551
ec278fa2 552 /* iterate through each 16 byte payload block */
96b3c83d 553 for (i = 0; i < num_blocks; i++) {
ca97b838
BZ
554 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
555 payload_index += 16;
556 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
557 }
91980990 558
ec278fa2 559 /* Add on the final payload block if it needs padding */
96b3c83d 560 if (payload_remainder > 0) {
ca97b838 561 NdisZeroMemory(padded_buffer, 16);
96b3c83d
BZ
562 NdisMoveMemory(padded_buffer, pData + payload_index,
563 payload_remainder);
91980990 564
ca97b838
BZ
565 bitwise_xor(aes_out, padded_buffer, chain_buffer);
566 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
567 }
ec278fa2
BZ
568 /* aes_out contains padded mic, discard most significant */
569 /* 8 bytes to generate 64 bit MIC */
96b3c83d
BZ
570 for (i = 0; i < 8; i++)
571 MIC[i] = aes_out[i];
91980990 572
96b3c83d 573 if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
ec278fa2 574 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); /*MIC error. */
ca97b838
BZ
575 return FALSE;
576 }
91980990 577
ca97b838
BZ
578 return TRUE;
579}
91980990
GKH
580
581/* ========================= AES En/Decryption ========================== */
ca97b838
BZ
582#ifndef uint8
583#define uint8 unsigned char
584#endif
585
586#ifndef uint32
587#define uint32 unsigned int
588#endif
91980990
GKH
589
590/* forward S-box */
96b3c83d
BZ
591static uint32 FSb[256] = {
592 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
593 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
594 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
595 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
596 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
597 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
598 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
599 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
600 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
601 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
602 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
603 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
604 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
605 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
606 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
607 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
608 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
609 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
610 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
611 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
612 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
613 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
614 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
615 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
616 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
617 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
618 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
619 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
620 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
621 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
622 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
623 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
91980990
GKH
624};
625
626/* forward table */
627#define FT \
628\
629 V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
630 V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
631 V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
632 V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
633 V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
634 V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
635 V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
636 V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
637 V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
638 V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
639 V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
640 V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
641 V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
642 V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
643 V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
644 V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
645 V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
646 V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
647 V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
648 V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
649 V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
650 V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
651 V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
652 V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
653 V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
654 V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
655 V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
656 V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
657 V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
658 V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
659 V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
660 V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
661 V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
662 V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
663 V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
664 V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
665 V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
666 V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
667 V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
668 V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
669 V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
670 V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
671 V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
672 V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
673 V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
674 V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
675 V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
676 V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
677 V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
678 V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
679 V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
680 V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
681 V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
682 V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
683 V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
684 V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
685 V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
686 V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
687 V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
688 V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
689 V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
690 V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
691 V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
692 V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
693
694#define V(a,b,c,d) 0x##a##b##c##d
695static uint32 FT0[256] = { FT };
96b3c83d 696
91980990
GKH
697#undef V
698
699#define V(a,b,c,d) 0x##d##a##b##c
700static uint32 FT1[256] = { FT };
96b3c83d 701
91980990
GKH
702#undef V
703
704#define V(a,b,c,d) 0x##c##d##a##b
705static uint32 FT2[256] = { FT };
96b3c83d 706
91980990
GKH
707#undef V
708
709#define V(a,b,c,d) 0x##b##c##d##a
710static uint32 FT3[256] = { FT };
96b3c83d 711
91980990
GKH
712#undef V
713
714#undef FT
715
716/* reverse S-box */
717
96b3c83d
BZ
718static uint32 RSb[256] = {
719 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
720 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
721 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
722 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
723 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
724 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
725 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
726 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
727 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
728 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
729 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
730 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
731 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
732 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
733 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
734 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
735 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
736 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
737 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
738 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
739 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
740 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
741 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
742 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
743 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
744 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
745 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
746 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
747 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
748 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
749 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
750 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
91980990
GKH
751};
752
753/* reverse table */
754
755#define RT \
756\
757 V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
758 V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
759 V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
760 V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
761 V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
762 V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
763 V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
764 V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
765 V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
766 V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
767 V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
768 V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
769 V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
770 V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
771 V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
772 V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
773 V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
774 V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
775 V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
776 V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
777 V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
778 V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
779 V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
780 V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
781 V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
782 V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
783 V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
784 V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
785 V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
786 V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
787 V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
788 V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
789 V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
790 V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
791 V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
792 V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
793 V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
794 V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
795 V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
796 V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
797 V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
798 V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
799 V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
800 V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
801 V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
802 V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
803 V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
804 V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
805 V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
806 V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
807 V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
808 V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
809 V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
810 V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
811 V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
812 V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
813 V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
814 V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
815 V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
816 V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
817 V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
818 V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
819 V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
820 V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
821
822#define V(a,b,c,d) 0x##a##b##c##d
823static uint32 RT0[256] = { RT };
96b3c83d 824
91980990
GKH
825#undef V
826
827#define V(a,b,c,d) 0x##d##a##b##c
828static uint32 RT1[256] = { RT };
96b3c83d 829
91980990
GKH
830#undef V
831
832#define V(a,b,c,d) 0x##c##d##a##b
833static uint32 RT2[256] = { RT };
96b3c83d 834
91980990
GKH
835#undef V
836
837#define V(a,b,c,d) 0x##b##c##d##a
838static uint32 RT3[256] = { RT };
96b3c83d 839
91980990
GKH
840#undef V
841
842#undef RT
843
844/* round constants */
845
96b3c83d
BZ
846static uint32 RCON[10] = {
847 0x01000000, 0x02000000, 0x04000000, 0x08000000,
848 0x10000000, 0x20000000, 0x40000000, 0x80000000,
849 0x1B000000, 0x36000000
91980990
GKH
850};
851
852/* key schedule tables */
853
854static int KT_init = 1;
855
856static uint32 KT0[256];
857static uint32 KT1[256];
858static uint32 KT2[256];
859static uint32 KT3[256];
860
25985edc 861/* platform-independent 32-bit integer manipulation macros */
91980990
GKH
862
863#define GET_UINT32(n,b,i) \
864{ \
865 (n) = ( (uint32) (b)[(i) ] << 24 ) \
866 | ( (uint32) (b)[(i) + 1] << 16 ) \
867 | ( (uint32) (b)[(i) + 2] << 8 ) \
868 | ( (uint32) (b)[(i) + 3] ); \
869}
870
871#define PUT_UINT32(n,b,i) \
872{ \
873 (b)[(i) ] = (uint8) ( (n) >> 24 ); \
874 (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
875 (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
876 (b)[(i) + 3] = (uint8) ( (n) ); \
877}
878
62eb734b 879int rt_aes_set_key(struct aes_context * ctx, uint8 * key, int nbits)
91980990 880{
96b3c83d
BZ
881 int i;
882 uint32 *RK, *SK;
883
884 switch (nbits) {
885 case 128:
886 ctx->nr = 10;
887 break;
888 case 192:
889 ctx->nr = 12;
890 break;
891 case 256:
892 ctx->nr = 14;
893 break;
894 default:
895 return (1);
91980990
GKH
896 }
897
ca97b838 898 RK = (uint32 *) ctx->erk;
91980990 899
96b3c83d
BZ
900 for (i = 0; i < (nbits >> 5); i++) {
901 GET_UINT32(RK[i], key, i * 4);
91980990
GKH
902 }
903
96b3c83d 904 /* setup encryption round keys */
91980990 905
96b3c83d 906 switch (nbits) {
91980990
GKH
907 case 128:
908
96b3c83d
BZ
909 for (i = 0; i < 10; i++, RK += 4) {
910 RK[4] = RK[0] ^ RCON[i] ^
911 (FSb[(uint8) (RK[3] >> 16)] << 24) ^
912 (FSb[(uint8) (RK[3] >> 8)] << 16) ^
913 (FSb[(uint8) (RK[3])] << 8) ^
914 (FSb[(uint8) (RK[3] >> 24)]);
915
916 RK[5] = RK[1] ^ RK[4];
917 RK[6] = RK[2] ^ RK[5];
918 RK[7] = RK[3] ^ RK[6];
91980990
GKH
919 }
920 break;
921
922 case 192:
923
96b3c83d
BZ
924 for (i = 0; i < 8; i++, RK += 6) {
925 RK[6] = RK[0] ^ RCON[i] ^
926 (FSb[(uint8) (RK[5] >> 16)] << 24) ^
927 (FSb[(uint8) (RK[5] >> 8)] << 16) ^
928 (FSb[(uint8) (RK[5])] << 8) ^
929 (FSb[(uint8) (RK[5] >> 24)]);
930
931 RK[7] = RK[1] ^ RK[6];
932 RK[8] = RK[2] ^ RK[7];
933 RK[9] = RK[3] ^ RK[8];
91980990
GKH
934 RK[10] = RK[4] ^ RK[9];
935 RK[11] = RK[5] ^ RK[10];
936 }
937 break;
938
939 case 256:
940
96b3c83d
BZ
941 for (i = 0; i < 7; i++, RK += 8) {
942 RK[8] = RK[0] ^ RCON[i] ^
943 (FSb[(uint8) (RK[7] >> 16)] << 24) ^
944 (FSb[(uint8) (RK[7] >> 8)] << 16) ^
945 (FSb[(uint8) (RK[7])] << 8) ^
946 (FSb[(uint8) (RK[7] >> 24)]);
91980990 947
96b3c83d 948 RK[9] = RK[1] ^ RK[8];
91980990
GKH
949 RK[10] = RK[2] ^ RK[9];
950 RK[11] = RK[3] ^ RK[10];
951
952 RK[12] = RK[4] ^
96b3c83d
BZ
953 (FSb[(uint8) (RK[11] >> 24)] << 24) ^
954 (FSb[(uint8) (RK[11] >> 16)] << 16) ^
955 (FSb[(uint8) (RK[11] >> 8)] << 8) ^
956 (FSb[(uint8) (RK[11])]);
91980990
GKH
957
958 RK[13] = RK[5] ^ RK[12];
959 RK[14] = RK[6] ^ RK[13];
960 RK[15] = RK[7] ^ RK[14];
961 }
962 break;
963 }
964
96b3c83d 965 /* setup decryption round keys */
91980990 966
96b3c83d
BZ
967 if (KT_init) {
968 for (i = 0; i < 256; i++) {
969 KT0[i] = RT0[FSb[i]];
970 KT1[i] = RT1[FSb[i]];
971 KT2[i] = RT2[FSb[i]];
972 KT3[i] = RT3[FSb[i]];
91980990
GKH
973 }
974
96b3c83d 975 KT_init = 0;
91980990
GKH
976 }
977
ca97b838 978 SK = (uint32 *) ctx->drk;
91980990 979
96b3c83d
BZ
980 *SK++ = *RK++;
981 *SK++ = *RK++;
982 *SK++ = *RK++;
983 *SK++ = *RK++;
91980990 984
96b3c83d 985 for (i = 1; i < ctx->nr; i++) {
91980990
GKH
986 RK -= 8;
987
96b3c83d
BZ
988 *SK++ = KT0[(uint8) (*RK >> 24)] ^
989 KT1[(uint8) (*RK >> 16)] ^
990 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
991 RK++;
992
993 *SK++ = KT0[(uint8) (*RK >> 24)] ^
994 KT1[(uint8) (*RK >> 16)] ^
995 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
996 RK++;
997
998 *SK++ = KT0[(uint8) (*RK >> 24)] ^
999 KT1[(uint8) (*RK >> 16)] ^
1000 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
1001 RK++;
1002
1003 *SK++ = KT0[(uint8) (*RK >> 24)] ^
1004 KT1[(uint8) (*RK >> 16)] ^
1005 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
1006 RK++;
91980990
GKH
1007 }
1008
1009 RK -= 8;
1010
96b3c83d
BZ
1011 *SK++ = *RK++;
1012 *SK++ = *RK++;
1013 *SK++ = *RK++;
1014 *SK++ = *RK++;
91980990 1015
96b3c83d 1016 return (0);
91980990
GKH
1017}
1018
1019/* AES 128-bit block encryption routine */
1020
62eb734b 1021void rt_aes_encrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
91980990 1022{
96b3c83d 1023 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
91980990 1024
ca97b838 1025 RK = (uint32 *) ctx->erk;
96b3c83d
BZ
1026 GET_UINT32(X0, input, 0);
1027 X0 ^= RK[0];
1028 GET_UINT32(X1, input, 4);
1029 X1 ^= RK[1];
1030 GET_UINT32(X2, input, 8);
1031 X2 ^= RK[2];
1032 GET_UINT32(X3, input, 12);
1033 X3 ^= RK[3];
91980990
GKH
1034
1035#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1036{ \
1037 RK += 4; \
1038 \
1039 X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \
1040 FT1[ (uint8) ( Y1 >> 16 ) ] ^ \
1041 FT2[ (uint8) ( Y2 >> 8 ) ] ^ \
1042 FT3[ (uint8) ( Y3 ) ]; \
1043 \
1044 X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \
1045 FT1[ (uint8) ( Y2 >> 16 ) ] ^ \
1046 FT2[ (uint8) ( Y3 >> 8 ) ] ^ \
1047 FT3[ (uint8) ( Y0 ) ]; \
1048 \
1049 X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \
1050 FT1[ (uint8) ( Y3 >> 16 ) ] ^ \
1051 FT2[ (uint8) ( Y0 >> 8 ) ] ^ \
1052 FT3[ (uint8) ( Y1 ) ]; \
1053 \
1054 X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \
1055 FT1[ (uint8) ( Y0 >> 16 ) ] ^ \
1056 FT2[ (uint8) ( Y1 >> 8 ) ] ^ \
1057 FT3[ (uint8) ( Y2 ) ]; \
1058}
1059
96b3c83d
BZ
1060 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */
1061 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */
1062 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */
1063 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */
1064 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */
1065 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */
1066 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */
1067 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */
1068 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */
1069
1070 if (ctx->nr > 10) {
1071 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */
1072 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */
91980990
GKH
1073 }
1074
96b3c83d
BZ
1075 if (ctx->nr > 12) {
1076 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */
1077 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */
91980990
GKH
1078 }
1079
96b3c83d 1080 /* last round */
91980990
GKH
1081
1082 RK += 4;
1083
96b3c83d
BZ
1084 X0 = RK[0] ^ (FSb[(uint8) (Y0 >> 24)] << 24) ^
1085 (FSb[(uint8) (Y1 >> 16)] << 16) ^
1086 (FSb[(uint8) (Y2 >> 8)] << 8) ^ (FSb[(uint8) (Y3)]);
1087
1088 X1 = RK[1] ^ (FSb[(uint8) (Y1 >> 24)] << 24) ^
1089 (FSb[(uint8) (Y2 >> 16)] << 16) ^
1090 (FSb[(uint8) (Y3 >> 8)] << 8) ^ (FSb[(uint8) (Y0)]);
1091
1092 X2 = RK[2] ^ (FSb[(uint8) (Y2 >> 24)] << 24) ^
1093 (FSb[(uint8) (Y3 >> 16)] << 16) ^
1094 (FSb[(uint8) (Y0 >> 8)] << 8) ^ (FSb[(uint8) (Y1)]);
1095
1096 X3 = RK[3] ^ (FSb[(uint8) (Y3 >> 24)] << 24) ^
1097 (FSb[(uint8) (Y0 >> 16)] << 16) ^
1098 (FSb[(uint8) (Y1 >> 8)] << 8) ^ (FSb[(uint8) (Y2)]);
1099
1100 PUT_UINT32(X0, output, 0);
1101 PUT_UINT32(X1, output, 4);
1102 PUT_UINT32(X2, output, 8);
1103 PUT_UINT32(X3, output, 12);
91980990
GKH
1104}
1105
1106/* AES 128-bit block decryption routine */
1107
62eb734b 1108void rt_aes_decrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
91980990 1109{
96b3c83d 1110 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
91980990 1111
ca97b838 1112 RK = (uint32 *) ctx->drk;
91980990 1113
96b3c83d
BZ
1114 GET_UINT32(X0, input, 0);
1115 X0 ^= RK[0];
1116 GET_UINT32(X1, input, 4);
1117 X1 ^= RK[1];
1118 GET_UINT32(X2, input, 8);
1119 X2 ^= RK[2];
1120 GET_UINT32(X3, input, 12);
1121 X3 ^= RK[3];
91980990
GKH
1122
1123#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1124{ \
1125 RK += 4; \
1126 \
1127 X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \
1128 RT1[ (uint8) ( Y3 >> 16 ) ] ^ \
1129 RT2[ (uint8) ( Y2 >> 8 ) ] ^ \
1130 RT3[ (uint8) ( Y1 ) ]; \
1131 \
1132 X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \
1133 RT1[ (uint8) ( Y0 >> 16 ) ] ^ \
1134 RT2[ (uint8) ( Y3 >> 8 ) ] ^ \
1135 RT3[ (uint8) ( Y2 ) ]; \
1136 \
1137 X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \
1138 RT1[ (uint8) ( Y1 >> 16 ) ] ^ \
1139 RT2[ (uint8) ( Y0 >> 8 ) ] ^ \
1140 RT3[ (uint8) ( Y3 ) ]; \
1141 \
1142 X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \
1143 RT1[ (uint8) ( Y2 >> 16 ) ] ^ \
1144 RT2[ (uint8) ( Y1 >> 8 ) ] ^ \
1145 RT3[ (uint8) ( Y0 ) ]; \
1146}
1147
96b3c83d
BZ
1148 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */
1149 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */
1150 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */
1151 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */
1152 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */
1153 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */
1154 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */
1155 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */
1156 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */
1157
1158 if (ctx->nr > 10) {
1159 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */
1160 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */
91980990
GKH
1161 }
1162
96b3c83d
BZ
1163 if (ctx->nr > 12) {
1164 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */
1165 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */
91980990
GKH
1166 }
1167
96b3c83d 1168 /* last round */
91980990
GKH
1169
1170 RK += 4;
1171
96b3c83d
BZ
1172 X0 = RK[0] ^ (RSb[(uint8) (Y0 >> 24)] << 24) ^
1173 (RSb[(uint8) (Y3 >> 16)] << 16) ^
1174 (RSb[(uint8) (Y2 >> 8)] << 8) ^ (RSb[(uint8) (Y1)]);
1175
1176 X1 = RK[1] ^ (RSb[(uint8) (Y1 >> 24)] << 24) ^
1177 (RSb[(uint8) (Y0 >> 16)] << 16) ^
1178 (RSb[(uint8) (Y3 >> 8)] << 8) ^ (RSb[(uint8) (Y2)]);
1179
1180 X2 = RK[2] ^ (RSb[(uint8) (Y2 >> 24)] << 24) ^
1181 (RSb[(uint8) (Y1 >> 16)] << 16) ^
1182 (RSb[(uint8) (Y0 >> 8)] << 8) ^ (RSb[(uint8) (Y3)]);
1183
1184 X3 = RK[3] ^ (RSb[(uint8) (Y3 >> 24)] << 24) ^
1185 (RSb[(uint8) (Y2 >> 16)] << 16) ^
1186 (RSb[(uint8) (Y1 >> 8)] << 8) ^ (RSb[(uint8) (Y0)]);
1187
1188 PUT_UINT32(X0, output, 0);
1189 PUT_UINT32(X1, output, 4);
1190 PUT_UINT32(X2, output, 8);
1191 PUT_UINT32(X3, output, 12);
91980990
GKH
1192}
1193
ca97b838
BZ
1194/*
1195 ==========================================================================
1196 Description:
1197 ENCRYPT AES GTK before sending in EAPOL frame.
1198 AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
1199 This function references to RFC 3394 for aes key wrap algorithm.
1200 Return:
1201 ==========================================================================
1202*/
51126deb
BZ
1203void AES_GTK_KEY_WRAP(u8 * key,
1204 u8 * plaintext,
1205 u32 p_len, u8 * ciphertext)
ca97b838 1206{
51126deb
BZ
1207 u8 A[8], BIN[16], BOUT[16];
1208 u8 R[512];
1209 int num_blocks = p_len / 8; /* unit:64bits */
1210 int i, j;
62eb734b 1211 struct aes_context aesctx;
51126deb 1212 u8 xor;
96b3c83d
BZ
1213
1214 rt_aes_set_key(&aesctx, key, 128);
1215
ec278fa2 1216 /* Init IA */
96b3c83d
BZ
1217 for (i = 0; i < 8; i++)
1218 A[i] = 0xa6;
1219
ec278fa2 1220 /*Input plaintext */
96b3c83d
BZ
1221 for (i = 0; i < num_blocks; i++) {
1222 for (j = 0; j < 8; j++)
1223 R[8 * (i + 1) + j] = plaintext[8 * i + j];
1224 }
1225
ec278fa2 1226 /* Key Mix */
96b3c83d
BZ
1227 for (j = 0; j < 6; j++) {
1228 for (i = 1; i <= num_blocks; i++) {
ec278fa2 1229 /*phase 1 */
96b3c83d
BZ
1230 NdisMoveMemory(BIN, A, 8);
1231 NdisMoveMemory(&BIN[8], &R[8 * i], 8);
1232 rt_aes_encrypt(&aesctx, BIN, BOUT);
1233
1234 NdisMoveMemory(A, &BOUT[0], 8);
1235 xor = num_blocks * j + i;
1236 A[7] = BOUT[7] ^ xor;
1237 NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
1238 }
1239 }
1240
ec278fa2 1241 /* Output ciphertext */
96b3c83d
BZ
1242 NdisMoveMemory(ciphertext, A, 8);
1243
1244 for (i = 1; i <= num_blocks; i++) {
1245 for (j = 0; j < 8; j++)
1246 ciphertext[8 * i + j] = R[8 * i + j];
1247 }
ca97b838
BZ
1248}
1249
91980990
GKH
1250/*
1251 ========================================================================
1252
1253 Routine Description:
ca97b838 1254 Misc function to decrypt AES body
91980990
GKH
1255
1256 Arguments:
1257
1258 Return Value:
1259
1260 Note:
ca97b838 1261 This function references to RFC 3394 for aes key unwrap algorithm.
91980990
GKH
1262
1263 ========================================================================
1264*/
51126deb
BZ
1265void AES_GTK_KEY_UNWRAP(u8 * key,
1266 u8 * plaintext,
1267 u32 c_len, u8 * ciphertext)
91980990 1268{
51126deb
BZ
1269 u8 A[8], BIN[16], BOUT[16];
1270 u8 xor;
1271 int i, j;
62eb734b 1272 struct aes_context aesctx;
51126deb
BZ
1273 u8 *R;
1274 int num_blocks = c_len / 8; /* unit:64bits */
91980990 1275
51126deb 1276 os_alloc_mem(NULL, (u8 **) & R, 512);
91980990 1277
96b3c83d
BZ
1278 if (R == NULL) {
1279 DBGPRINT(RT_DEBUG_ERROR,
06aea994 1280 ("AES_GTK_KEY_UNWRAP: no memory!\n"));
96b3c83d
BZ
1281 return;
1282 }
1283 /* End of if */
ec278fa2 1284 /* Initialize */
ca97b838 1285 NdisMoveMemory(A, ciphertext, 8);
ec278fa2 1286 /*Input plaintext */
96b3c83d
BZ
1287 for (i = 0; i < (c_len - 8); i++) {
1288 R[i] = ciphertext[i + 8];
91980990
GKH
1289 }
1290
ca97b838 1291 rt_aes_set_key(&aesctx, key, 128);
91980990 1292
96b3c83d
BZ
1293 for (j = 5; j >= 0; j--) {
1294 for (i = (num_blocks - 1); i > 0; i--) {
1295 xor = (num_blocks - 1) * j + i;
ca97b838
BZ
1296 NdisMoveMemory(BIN, A, 8);
1297 BIN[7] = A[7] ^ xor;
96b3c83d 1298 NdisMoveMemory(&BIN[8], &R[(i - 1) * 8], 8);
ca97b838
BZ
1299 rt_aes_decrypt(&aesctx, BIN, BOUT);
1300 NdisMoveMemory(A, &BOUT[0], 8);
96b3c83d 1301 NdisMoveMemory(&R[(i - 1) * 8], &BOUT[8], 8);
ca97b838
BZ
1302 }
1303 }
91980990 1304
ec278fa2 1305 /* OUTPUT */
96b3c83d 1306 for (i = 0; i < c_len; i++) {
ca97b838
BZ
1307 plaintext[i] = R[i];
1308 }
91980990 1309
ca97b838 1310 os_free_mem(NULL, R);
91980990 1311}