1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#include "../rt_config.h"
39#include "../rtmp_ckipmic.h"
40
41
42#define MIC_ACCUM(v) pContext->accum += (ULONGLONG)v * RTMPMicGetCoefficient(pContext)
43#define GB(p,i,s) ( ((ULONG) *((UCHAR*)(p)+i) ) << (s) )
44#define GETBIG32(p) GB(p,0,24)|GB(p,1,16)|GB(p,2,8)|GB(p,3,0)
45
46
47
48
49
50UCHAR SboxTable[256] =
51{
52 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
53 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
54 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
55 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
56 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
57 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
58 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
59 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
60 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
61 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
62 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
63 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
64 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
65 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
66 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
67 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
68 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
69 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
70 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
71 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
72 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
73 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
74 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
75 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
76 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
77 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
78 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
79 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
80 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
81 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
82 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
83 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
84};
85
86
87
88
89
90
91static const USHORT Sbox[256] =
92{
93 0xC6A5,0xF884,0xEE99,0xF68D,0xFF0D,0xD6BD,0xDEB1,0x9154,
94 0x6050,0x0203,0xCEA9,0x567D,0xE719,0xB562,0x4DE6,0xEC9A,
95 0x8F45,0x1F9D,0x8940,0xFA87,0xEF15,0xB2EB,0x8EC9,0xFB0B,
96 0x41EC,0xB367,0x5FFD,0x45EA,0x23BF,0x53F7,0xE496,0x9B5B,
97 0x75C2,0xE11C,0x3DAE,0x4C6A,0x6C5A,0x7E41,0xF502,0x834F,
98 0x685C,0x51F4,0xD134,0xF908,0xE293,0xAB73,0x6253,0x2A3F,
99 0x080C,0x9552,0x4665,0x9D5E,0x3028,0x37A1,0x0A0F,0x2FB5,
100 0x0E09,0x2436,0x1B9B,0xDF3D,0xCD26,0x4E69,0x7FCD,0xEA9F,
101 0x121B,0x1D9E,0x5874,0x342E,0x362D,0xDCB2,0xB4EE,0x5BFB,
102 0xA4F6,0x764D,0xB761,0x7DCE,0x527B,0xDD3E,0x5E71,0x1397,
103 0xA6F5,0xB968,0x0000,0xC12C,0x4060,0xE31F,0x79C8,0xB6ED,
104 0xD4BE,0x8D46,0x67D9,0x724B,0x94DE,0x98D4,0xB0E8,0x854A,
105 0xBB6B,0xC52A,0x4FE5,0xED16,0x86C5,0x9AD7,0x6655,0x1194,
106 0x8ACF,0xE910,0x0406,0xFE81,0xA0F0,0x7844,0x25BA,0x4BE3,
107 0xA2F3,0x5DFE,0x80C0,0x058A,0x3FAD,0x21BC,0x7048,0xF104,
108 0x63DF,0x77C1,0xAF75,0x4263,0x2030,0xE51A,0xFD0E,0xBF6D,
109 0x814C,0x1814,0x2635,0xC32F,0xBEE1,0x35A2,0x88CC,0x2E39,
110 0x9357,0x55F2,0xFC82,0x7A47,0xC8AC,0xBAE7,0x322B,0xE695,
111 0xC0A0,0x1998,0x9ED1,0xA37F,0x4466,0x547E,0x3BAB,0x0B83,
112 0x8CCA,0xC729,0x6BD3,0x283C,0xA779,0xBCE2,0x161D,0xAD76,
113 0xDB3B,0x6456,0x744E,0x141E,0x92DB,0x0C0A,0x486C,0xB8E4,
114 0x9F5D,0xBD6E,0x43EF,0xC4A6,0x39A8,0x31A4,0xD337,0xF28B,
115 0xD532,0x8B43,0x6E59,0xDAB7,0x018C,0xB164,0x9CD2,0x49E0,
116 0xD8B4,0xACFA,0xF307,0xCF25,0xCAAF,0xF48E,0x47E9,0x1018,
117 0x6FD5,0xF088,0x4A6F,0x5C72,0x3824,0x57F1,0x73C7,0x9751,
118 0xCB23,0xA17C,0xE89C,0x3E21,0x96DD,0x61DC,0x0D86,0x0F85,
119 0xE090,0x7C42,0x71C4,0xCCAA,0x90D8,0x0605,0xF701,0x1C12,
120 0xC2A3,0x6A5F,0xAEF9,0x69D0,0x1791,0x9958,0x3A27,0x27B9,
121 0xD938,0xEB13,0x2BB3,0x2233,0xD2BB,0xA970,0x0789,0x33A7,
122 0x2DB6,0x3C22,0x1592,0xC920,0x8749,0xAAFF,0x5078,0xA57A,
123 0x038F,0x59F8,0x0980,0x1A17,0x65DA,0xD731,0x84C6,0xD0B8,
124 0x82C3,0x29B0,0x5A77,0x1E11,0x7BCB,0xA8FC,0x6DD6,0x2C3A
125 };
126
127#define Lo8(v16) ((v16) & 0xFF)
128#define Hi8(v16) (((v16) >> 8) & 0xFF)
129#define u16Swap(i) ( (((i) >> 8) & 0xFF) | (((i) << 8) & 0xFF00) )
130#define _S_(i) (Sbox[Lo8(i)] ^ u16Swap(Sbox[Hi8(i)]))
131
132#define rotLeft_1(x) ((((x) << 1) | ((x) >> 15)) & 0xFFFF)
133VOID CKIP_key_permute
134 (
135 OUT UCHAR *PK,
136 IN UCHAR *CK,
137 IN UCHAR toDsFromDs,
138 IN UCHAR *piv
139 )
140{
141 int i;
142 USHORT H[2], tmp;
143 USHORT L[8], R[8];
144
145
146 memset(L, 0, sizeof(L));
147 for (i=0; i<16; i++) {
148 L[i>>1] |= ( ((USHORT)(CK[i])) << ( i & 1 ? 8 : 0) );
149 }
150
151 H[0] = (((USHORT)piv[0]) << 8) + piv[1];
152 H[1] = ( ((USHORT)toDsFromDs) << 8) | piv[2];
153
154 for (i=0; i<8; i++) {
155 H[0] ^= L[i];
156 tmp = _S_(H[0]);
157 H[0] = tmp ^ H[1];
158 H[1] = tmp;
159 R[i] = H[0];
160 }
161
162
163 tmp=L[0];
164 for (i=7; i>0; i--) {
165 R[i] = tmp = rotLeft_1(tmp) + R[i];
166 }
167
168
169 PK[0] = piv[0];
170 PK[1] = piv[1];
171 PK[2] = piv[2];
172
173
174 for (i=3; i<16; i++) {
175 PK[i] = (UCHAR) (R[i>>1] >> (i & 1 ? 8 : 0));
176 }
177}
178
179
180VOID RTMPCkipMicInit(
181 IN PMIC_CONTEXT pContext,
182 IN PUCHAR CK)
183{
184
185 NdisMoveMemory(pContext->CK, CK, sizeof(pContext->CK));
186 pContext->accum = 0;
187 pContext->position = 0;
188}
189
190
191VOID RTMPMicUpdate(
192 IN PMIC_CONTEXT pContext,
193 IN PUCHAR pOctets,
194 IN INT len)
195{
196 INT byte_position;
197 ULONG val;
198
199 byte_position = (pContext->position & 3);
200 while (len > 0) {
201
202 do {
203 if (len == 0) return;
204 pContext->part[byte_position++] = *pOctets++;
205 pContext->position++;
206 len--;
207 } while (byte_position < 4);
208
209 val = GETBIG32(&pContext->part[0]);
210 MIC_ACCUM(val);
211 byte_position = 0;
212 }
213}
214
215ULONG RTMPMicGetCoefficient(
216 IN PMIC_CONTEXT pContext)
217{
218 UCHAR aes_counter[16];
219 INT coeff_position;
220 UCHAR *p;
221
222 coeff_position = (pContext->position - 1) >> 2;
223 if ( (coeff_position & 3) == 0) {
224
225 u32 counter = (coeff_position >> 2);
226
227
228 memset(&aes_counter[0], 0, sizeof(aes_counter));
229 aes_counter[15] = (UINT8)(counter >> 0);
230 aes_counter[14] = (UINT8)(counter >> 8);
231 aes_counter[13] = (UINT8)(counter >> 16);
232 aes_counter[12] = (UINT8)(counter >> 24);
233
234 RTMPAesEncrypt(&pContext->CK[0], &aes_counter[0], pContext->coefficient);
235 }
236 p = &(pContext->coefficient[ (coeff_position & 3) << 2 ]);
237 return GETBIG32(p);
238}
239
240
241
242
243
244
245VOID xor_128(
246 IN PUCHAR a,
247 IN PUCHAR b,
248 OUT PUCHAR out)
249{
250 INT i;
251
252 for (i=0;i<16; i++)
253 {
254 out[i] = a[i] ^ b[i];
255 }
256}
257
258UCHAR RTMPCkipSbox(
259 IN UCHAR a)
260{
261 return SboxTable[(int)a];
262}
263
264VOID xor_32(
265 IN PUCHAR a,
266 IN PUCHAR b,
267 OUT PUCHAR out)
268{
269 INT i;
270
271 for (i=0;i<4; i++)
272 {
273 out[i] = a[i] ^ b[i];
274 }
275}
276
277VOID next_key(
278 IN PUCHAR key,
279 IN INT round)
280{
281 UCHAR rcon;
282 UCHAR sbox_key[4];
283 UCHAR rcon_table[12] =
284 {
285 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
286 0x1b, 0x36, 0x36, 0x36
287 };
288
289 sbox_key[0] = RTMPCkipSbox(key[13]);
290 sbox_key[1] = RTMPCkipSbox(key[14]);
291 sbox_key[2] = RTMPCkipSbox(key[15]);
292 sbox_key[3] = RTMPCkipSbox(key[12]);
293
294 rcon = rcon_table[round];
295
296 xor_32(&key[0], sbox_key, &key[0]);
297 key[0] = key[0] ^ rcon;
298
299 xor_32(&key[4], &key[0], &key[4]);
300 xor_32(&key[8], &key[4], &key[8]);
301 xor_32(&key[12], &key[8], &key[12]);
302}
303
304VOID byte_sub(
305 IN PUCHAR in,
306 OUT PUCHAR out)
307{
308 INT i;
309
310 for (i=0; i< 16; i++)
311 {
312 out[i] = RTMPCkipSbox(in[i]);
313 }
314}
315
316VOID shift_row(
317 IN PUCHAR in,
318 OUT PUCHAR out)
319{
320 out[0] = in[0];
321 out[1] = in[5];
322 out[2] = in[10];
323 out[3] = in[15];
324 out[4] = in[4];
325 out[5] = in[9];
326 out[6] = in[14];
327 out[7] = in[3];
328 out[8] = in[8];
329 out[9] = in[13];
330 out[10] = in[2];
331 out[11] = in[7];
332 out[12] = in[12];
333 out[13] = in[1];
334 out[14] = in[6];
335 out[15] = in[11];
336}
337
338VOID mix_column(
339 IN PUCHAR in,
340 OUT PUCHAR out)
341{
342 INT i;
343 UCHAR add1b[4];
344 UCHAR add1bf7[4];
345 UCHAR rotl[4];
346 UCHAR swap_halfs[4];
347 UCHAR andf7[4];
348 UCHAR rotr[4];
349 UCHAR temp[4];
350 UCHAR tempb[4];
351
352 for (i=0 ; i<4; i++)
353 {
354 if ((in[i] & 0x80)== 0x80)
355 add1b[i] = 0x1b;
356 else
357 add1b[i] = 0x00;
358 }
359
360 swap_halfs[0] = in[2];
361 swap_halfs[1] = in[3];
362 swap_halfs[2] = in[0];
363 swap_halfs[3] = in[1];
364
365 rotl[0] = in[3];
366 rotl[1] = in[0];
367 rotl[2] = in[1];
368 rotl[3] = in[2];
369
370 andf7[0] = in[0] & 0x7f;
371 andf7[1] = in[1] & 0x7f;
372 andf7[2] = in[2] & 0x7f;
373 andf7[3] = in[3] & 0x7f;
374
375 for (i = 3; i>0; i--)
376 {
377 andf7[i] = andf7[i] << 1;
378 if ((andf7[i-1] & 0x80) == 0x80)
379 {
380 andf7[i] = (andf7[i] | 0x01);
381 }
382 }
383 andf7[0] = andf7[0] << 1;
384 andf7[0] = andf7[0] & 0xfe;
385
386 xor_32(add1b, andf7, add1bf7);
387
388 xor_32(in, add1bf7, rotr);
389
390 temp[0] = rotr[0];
391 rotr[0] = rotr[1];
392 rotr[1] = rotr[2];
393 rotr[2] = rotr[3];
394 rotr[3] = temp[0];
395
396 xor_32(add1bf7, rotr, temp);
397 xor_32(swap_halfs, rotl,tempb);
398 xor_32(temp, tempb, out);
399}
400
401VOID RTMPAesEncrypt(
402 IN PUCHAR key,
403 IN PUCHAR data,
404 IN PUCHAR ciphertext)
405{
406 INT round;
407 INT i;
408 UCHAR intermediatea[16];
409 UCHAR intermediateb[16];
410 UCHAR round_key[16];
411
412 for(i=0; i<16; i++) round_key[i] = key[i];
413
414 for (round = 0; round < 11; round++)
415 {
416 if (round == 0)
417 {
418 xor_128(round_key, data, ciphertext);
419 next_key(round_key, round);
420 }
421 else if (round == 10)
422 {
423 byte_sub(ciphertext, intermediatea);
424 shift_row(intermediatea, intermediateb);
425 xor_128(intermediateb, round_key, ciphertext);
426 }
427 else
428 {
429 byte_sub(ciphertext, intermediatea);
430 shift_row(intermediatea, intermediateb);
431 mix_column(&intermediateb[0], &intermediatea[0]);
432 mix_column(&intermediateb[4], &intermediatea[4]);
433 mix_column(&intermediateb[8], &intermediatea[8]);
434 mix_column(&intermediateb[12], &intermediatea[12]);
435 xor_128(intermediatea, round_key, ciphertext);
436 next_key(round_key, round);
437 }
438 }
439
440}
441
442
443VOID RTMPMicFinal(
444 IN PMIC_CONTEXT pContext,
445 OUT UCHAR digest[4])
446{
447 INT byte_position;
448 ULONG val;
449 ULONGLONG sum, utmp;
450 LONGLONG stmp;
451
452
453 if ( (byte_position = (pContext->position & 3)) != 0) {
454
455 do {
456 pContext->part[byte_position++] = 0;
457 pContext->position++;
458 } while (byte_position < 4);
459 val = GETBIG32(&pContext->part[0]);
460 MIC_ACCUM(val);
461 }
462
463
464 sum = pContext->accum;
465 stmp = (sum & 0xffffffffL) - ((sum >> 32) * 15);
466 utmp = (stmp & 0xffffffffL) - ((stmp >> 32) * 15);
467 sum = utmp & 0xffffffffL;
468 if (utmp > 0x10000000fL)
469 sum -= 15;
470
471 val = (ULONG)sum;
472 digest[0] = (UCHAR)((val>>24) & 0xFF);
473 digest[1] = (UCHAR) ((val>>16) & 0xFF);
474 digest[2] = (UCHAR) ((val>>8) & 0xFF);
475 digest[3] = (UCHAR)((val>>0) & 0xFF);
476}
477
478VOID RTMPCkipInsertCMIC(
479 IN PRTMP_ADAPTER pAd,
480 OUT PUCHAR pMIC,
481 IN PUCHAR p80211hdr,
482 IN PNDIS_PACKET pPacket,
483 IN PCIPHER_KEY pKey,
484 IN PUCHAR mic_snap)
485{
486 PACKET_INFO PacketInfo;
487 PUCHAR pSrcBufVA;
488 ULONG SrcBufLen;
489 PUCHAR pDA, pSA, pProto;
490 UCHAR bigethlen[2];
491 UCHAR ckip_ck[16];
492 MIC_CONTEXT mic_ctx;
493 USHORT payloadlen;
494 UCHAR i;
495
496 if (pKey == NULL)
497 {
498 DBGPRINT_ERR(("RTMPCkipInsertCMIC, Before to form the CKIP key (CK), pKey can't be NULL\n"));
499 return;
500 }
501
502 switch (*(p80211hdr+1) & 3)
503 {
504 case 0:
505 pDA = p80211hdr+4;
506 pSA = p80211hdr+10;
507 break;
508 case 1:
509 pDA = p80211hdr+16;
510 pSA = p80211hdr+10;
511 break;
512 case 2:
513 pDA = p80211hdr+4;
514 pSA = p80211hdr+16;
515 break;
516 case 3:
517 pDA = p80211hdr+16;
518 pSA = p80211hdr+24;
519 break;
520 }
521
522 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
523
524 if (SrcBufLen < LENGTH_802_3)
525 return;
526
527 pProto = pSrcBufVA + 12;
528 payloadlen = PacketInfo.TotalPacketLength - LENGTH_802_3 + 18;
529
530 bigethlen[0] = (unsigned char)(payloadlen >> 8);
531 bigethlen[1] = (unsigned char)payloadlen;
532
533
534
535
536 if (pKey->KeyLen < 16)
537 {
538 for(i = 0; i < (16 / pKey->KeyLen); i++)
539 {
540 NdisMoveMemory(ckip_ck + i * pKey->KeyLen,
541 pKey->Key,
542 pKey->KeyLen);
543 }
544 NdisMoveMemory(ckip_ck + i * pKey->KeyLen,
545 pKey->Key,
546 16 - (i * pKey->KeyLen));
547 }
548 else
549 {
550 NdisMoveMemory(ckip_ck, pKey->Key, pKey->KeyLen);
551 }
552 RTMPCkipMicInit(&mic_ctx, ckip_ck);
553 RTMPMicUpdate(&mic_ctx, pDA, MAC_ADDR_LEN);
554 RTMPMicUpdate(&mic_ctx, pSA, MAC_ADDR_LEN);
555 RTMPMicUpdate(&mic_ctx, bigethlen, 2);
556 RTMPMicUpdate(&mic_ctx, mic_snap, 8);
557 RTMPMicUpdate(&mic_ctx, pAd->StaCfg.TxSEQ, 4);
558 RTMPMicUpdate(&mic_ctx, pProto, 2);
559
560 pSrcBufVA += LENGTH_802_3;
561 SrcBufLen -= LENGTH_802_3;
562
563
564 do
565 {
566 if (SrcBufLen > 0)
567 RTMPMicUpdate(&mic_ctx, pSrcBufVA, SrcBufLen);
568
569 NdisGetNextBuffer(PacketInfo.pFirstBuffer, &PacketInfo.pFirstBuffer);
570 if (PacketInfo.pFirstBuffer)
571 {
572 NDIS_QUERY_BUFFER(PacketInfo.pFirstBuffer, &pSrcBufVA, &SrcBufLen);
573 }
574 else
575 break;
576 } while (TRUE);
577
578 RTMPMicFinal(&mic_ctx, pMIC);
579}
580