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
27 Module Name:
28 wpa.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Jan Lee 03-07-22 Initial
36 Paul Lin 03-11-28 Modify for supplicant
37 */
38 #include "../rt_config.h"
39
40 #define WPARSNIE 0xdd
41 #define WPA2RSNIE 0x30
42
43 //extern UCHAR BIT8[];
44 UCHAR CipherWpaPskTkip[] = {
45 0xDD, 0x16, // RSN IE
46 0x00, 0x50, 0xf2, 0x01, // oui
47 0x01, 0x00, // Version
48 0x00, 0x50, 0xf2, 0x02, // Multicast
49 0x01, 0x00, // Number of unicast
50 0x00, 0x50, 0xf2, 0x02, // unicast
51 0x01, 0x00, // number of authentication method
52 0x00, 0x50, 0xf2, 0x02 // authentication
53 };
54 UCHAR CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
55
56 UCHAR CipherWpaPskAes[] = {
57 0xDD, 0x16, // RSN IE
58 0x00, 0x50, 0xf2, 0x01, // oui
59 0x01, 0x00, // Version
60 0x00, 0x50, 0xf2, 0x04, // Multicast
61 0x01, 0x00, // Number of unicast
62 0x00, 0x50, 0xf2, 0x04, // unicast
63 0x01, 0x00, // number of authentication method
64 0x00, 0x50, 0xf2, 0x02 // authentication
65 };
66 UCHAR CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
67
68 UCHAR CipherSuiteCiscoCCKM[] = {
69 0xDD, 0x16, // RSN IE
70 0x00, 0x50, 0xf2, 0x01, // oui
71 0x01, 0x00, // Version
72 0x00, 0x40, 0x96, 0x01, // Multicast
73 0x01, 0x00, // Number of uicast
74 0x00, 0x40, 0x96, 0x01, // unicast
75 0x01, 0x00, // number of authentication method
76 0x00, 0x40, 0x96, 0x00 // Authentication
77 };
78 UCHAR CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
79
80 UCHAR CipherSuiteCiscoCCKM24[] = {
81 0xDD, 0x18, // RSN IE
82 0x00, 0x50, 0xf2, 0x01, // oui
83 0x01, 0x00, // Version
84 0x00, 0x40, 0x96, 0x01, // Multicast
85 0x01, 0x00, // Number of uicast
86 0x00, 0x40, 0x96, 0x01, // unicast
87 0x01, 0x00, // number of authentication method
88 0x00, 0x40, 0x96, 0x00,
89 0x28, 0x00// Authentication
90 };
91
92 UCHAR CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
93
94 UCHAR CipherSuiteCCXTkip[] = {
95 0xDD, 0x16, // RSN IE
96 0x00, 0x50, 0xf2, 0x01, // oui
97 0x01, 0x00, // Version
98 0x00, 0x50, 0xf2, 0x02, // Multicast
99 0x01, 0x00, // Number of unicast
100 0x00, 0x50, 0xf2, 0x02, // unicast
101 0x01, 0x00, // number of authentication method
102 0x00, 0x50, 0xf2, 0x01 // authentication
103 };
104 UCHAR CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
105
106 UCHAR CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
107 UCHAR LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
108
109 UCHAR EAPOL_FRAME[] = {0x88, 0x8E};
110
111 BOOLEAN CheckRSNIE(
112 IN PRTMP_ADAPTER pAd,
113 IN PUCHAR pData,
114 IN UCHAR DataLen,
115 OUT UCHAR *Offset);
116
117 void inc_byte_array(UCHAR *counter, int len);
118
119 /*
120 ========================================================================
121
122 Routine Description:
123 Classify WPA EAP message type
124
125 Arguments:
126 EAPType Value of EAP message type
127 MsgType Internal Message definition for MLME state machine
128
129 Return Value:
130 TRUE Found appropriate message type
131 FALSE No appropriate message type
132
133 IRQL = DISPATCH_LEVEL
134
135 Note:
136 All these constants are defined in wpa.h
137 For supplicant, there is only EAPOL Key message avaliable
138
139 ========================================================================
140 */
WpaMsgTypeSubst(IN UCHAR EAPType,OUT INT * MsgType)141 BOOLEAN WpaMsgTypeSubst(
142 IN UCHAR EAPType,
143 OUT INT *MsgType)
144 {
145 switch (EAPType)
146 {
147 case EAPPacket:
148 *MsgType = MT2_EAPPacket;
149 break;
150 case EAPOLStart:
151 *MsgType = MT2_EAPOLStart;
152 break;
153 case EAPOLLogoff:
154 *MsgType = MT2_EAPOLLogoff;
155 break;
156 case EAPOLKey:
157 *MsgType = MT2_EAPOLKey;
158 break;
159 case EAPOLASFAlert:
160 *MsgType = MT2_EAPOLASFAlert;
161 break;
162 default:
163 return FALSE;
164 }
165 return TRUE;
166 }
167
168 /*
169 ==========================================================================
170 Description:
171 association state machine init, including state transition and timer init
172 Parameters:
173 S - pointer to the association state machine
174 ==========================================================================
175 */
WpaPskStateMachineInit(IN PRTMP_ADAPTER pAd,IN STATE_MACHINE * S,OUT STATE_MACHINE_FUNC Trans[])176 VOID WpaPskStateMachineInit(
177 IN PRTMP_ADAPTER pAd,
178 IN STATE_MACHINE *S,
179 OUT STATE_MACHINE_FUNC Trans[])
180 {
181 StateMachineInit(S, Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
182 StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
183 }
184
185 /*
186 ==========================================================================
187 Description:
188 This is state machine function.
189 When receiving EAPOL packets which is for 802.1x key management.
190 Use both in WPA, and WPAPSK case.
191 In this function, further dispatch to different functions according to the received packet. 3 categories are :
192 1. normal 4-way pairwisekey and 2-way groupkey handshake
193 2. MIC error (Countermeasures attack) report packet from STA.
194 3. Request for pairwise/group key update from STA
195 Return:
196 ==========================================================================
197 */
WpaEAPOLKeyAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)198 VOID WpaEAPOLKeyAction(
199 IN PRTMP_ADAPTER pAd,
200 IN MLME_QUEUE_ELEM *Elem)
201
202 {
203 INT MsgType = EAPOL_MSG_INVALID;
204 PKEY_DESCRIPTER pKeyDesc;
205 PHEADER_802_11 pHeader; //red
206 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
207 UCHAR EapolVr;
208 KEY_INFO peerKeyInfo;
209
210 DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
211
212 // Get 802.11 header first
213 pHeader = (PHEADER_802_11) Elem->Msg;
214
215 // Get EAPoL-Key Descriptor
216 pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
217
218 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
219 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
220
221 *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
222
223
224 // 1. Check EAPOL frame version and type
225 EapolVr = (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
226
227 if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
228 {
229 DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
230 return;
231 }
232
233 // First validate replay counter, only accept message with larger replay counter
234 // Let equal pass, some AP start with all zero replay counter
235 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
236
237 if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
238 (RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
239 {
240 DBGPRINT(RT_DEBUG_ERROR, (" ReplayCounter not match \n"));
241 return;
242 }
243
244 // Process WPA2PSK frame
245 if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
246 {
247 if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
248 (peerKeyInfo.EKD_DL == 0) &&
249 (peerKeyInfo.KeyAck == 1) &&
250 (peerKeyInfo.KeyMic == 0) &&
251 (peerKeyInfo.Secure == 0) &&
252 (peerKeyInfo.Error == 0) &&
253 (peerKeyInfo.Request == 0))
254 {
255 MsgType = EAPOL_PAIR_MSG_1;
256 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
257 } else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
258 (peerKeyInfo.EKD_DL == 1) &&
259 (peerKeyInfo.KeyAck == 1) &&
260 (peerKeyInfo.KeyMic == 1) &&
261 (peerKeyInfo.Secure == 1) &&
262 (peerKeyInfo.Error == 0) &&
263 (peerKeyInfo.Request == 0))
264 {
265 MsgType = EAPOL_PAIR_MSG_3;
266 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
267 } else if((peerKeyInfo.KeyType == GROUPKEY) &&
268 (peerKeyInfo.EKD_DL == 1) &&
269 (peerKeyInfo.KeyAck == 1) &&
270 (peerKeyInfo.KeyMic == 1) &&
271 (peerKeyInfo.Secure == 1) &&
272 (peerKeyInfo.Error == 0) &&
273 (peerKeyInfo.Request == 0))
274 {
275 MsgType = EAPOL_GROUP_MSG_1;
276 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
277 }
278
279 // We will assume link is up (assoc suceess and port not secured).
280 // All state has to be able to process message from previous state
281 switch(pAd->StaCfg.WpaState)
282 {
283 case SS_START:
284 if(MsgType == EAPOL_PAIR_MSG_1)
285 {
286 Wpa2PairMsg1Action(pAd, Elem);
287 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
288 }
289 break;
290
291 case SS_WAIT_MSG_3:
292 if(MsgType == EAPOL_PAIR_MSG_1)
293 {
294 Wpa2PairMsg1Action(pAd, Elem);
295 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
296 }
297 else if(MsgType == EAPOL_PAIR_MSG_3)
298 {
299 Wpa2PairMsg3Action(pAd, Elem);
300 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
301 }
302 break;
303
304 case SS_WAIT_GROUP: // When doing group key exchange
305 case SS_FINISH: // This happened when update group key
306 if(MsgType == EAPOL_PAIR_MSG_1)
307 {
308 // Reset port secured variable
309 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
310 Wpa2PairMsg1Action(pAd, Elem);
311 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
312 }
313 else if(MsgType == EAPOL_PAIR_MSG_3)
314 {
315 // Reset port secured variable
316 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
317 Wpa2PairMsg3Action(pAd, Elem);
318 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
319 }
320 else if(MsgType == EAPOL_GROUP_MSG_1)
321 {
322 WpaGroupMsg1Action(pAd, Elem);
323 pAd->StaCfg.WpaState = SS_FINISH;
324 }
325 break;
326
327 default:
328 break;
329 }
330 }
331 // Process WPAPSK Frame
332 // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
333 else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
334 {
335 if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
336 (peerKeyInfo.KeyIndex == 0) &&
337 (peerKeyInfo.KeyAck == 1) &&
338 (peerKeyInfo.KeyMic == 0) &&
339 (peerKeyInfo.Secure == 0) &&
340 (peerKeyInfo.Error == 0) &&
341 (peerKeyInfo.Request == 0))
342 {
343 MsgType = EAPOL_PAIR_MSG_1;
344 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
345 }
346 else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
347 (peerKeyInfo.KeyIndex == 0) &&
348 (peerKeyInfo.KeyAck == 1) &&
349 (peerKeyInfo.KeyMic == 1) &&
350 (peerKeyInfo.Secure == 0) &&
351 (peerKeyInfo.Error == 0) &&
352 (peerKeyInfo.Request == 0))
353 {
354 MsgType = EAPOL_PAIR_MSG_3;
355 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
356 }
357 else if((peerKeyInfo.KeyType == GROUPKEY) &&
358 (peerKeyInfo.KeyIndex != 0) &&
359 (peerKeyInfo.KeyAck == 1) &&
360 (peerKeyInfo.KeyMic == 1) &&
361 (peerKeyInfo.Secure == 1) &&
362 (peerKeyInfo.Error == 0) &&
363 (peerKeyInfo.Request == 0))
364 {
365 MsgType = EAPOL_GROUP_MSG_1;
366 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
367 }
368
369 // We will assume link is up (assoc suceess and port not secured).
370 // All state has to be able to process message from previous state
371 switch(pAd->StaCfg.WpaState)
372 {
373 case SS_START:
374 if(MsgType == EAPOL_PAIR_MSG_1)
375 {
376 WpaPairMsg1Action(pAd, Elem);
377 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
378 }
379 break;
380
381 case SS_WAIT_MSG_3:
382 if(MsgType == EAPOL_PAIR_MSG_1)
383 {
384 WpaPairMsg1Action(pAd, Elem);
385 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
386 }
387 else if(MsgType == EAPOL_PAIR_MSG_3)
388 {
389 WpaPairMsg3Action(pAd, Elem);
390 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
391 }
392 break;
393
394 case SS_WAIT_GROUP: // When doing group key exchange
395 case SS_FINISH: // This happened when update group key
396 if(MsgType == EAPOL_PAIR_MSG_1)
397 {
398 WpaPairMsg1Action(pAd, Elem);
399 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
400 // Reset port secured variable
401 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
402 }
403 else if(MsgType == EAPOL_PAIR_MSG_3)
404 {
405 WpaPairMsg3Action(pAd, Elem);
406 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
407 // Reset port secured variable
408 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
409 }
410 else if(MsgType == EAPOL_GROUP_MSG_1)
411 {
412 WpaGroupMsg1Action(pAd, Elem);
413 pAd->StaCfg.WpaState = SS_FINISH;
414 }
415 break;
416
417 default:
418 break;
419 }
420 }
421
422 DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
423 }
424
425 /*
426 ========================================================================
427
428 Routine Description:
429 Process Pairwise key 4-way handshaking
430
431 Arguments:
432 pAd Pointer to our adapter
433 Elem Message body
434
435 Return Value:
436 None
437
438 Note:
439
440 ========================================================================
441 */
WpaPairMsg1Action(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)442 VOID WpaPairMsg1Action(
443 IN PRTMP_ADAPTER pAd,
444 IN MLME_QUEUE_ELEM *Elem)
445 {
446 PHEADER_802_11 pHeader;
447 UCHAR *mpool, *PTK, *digest;
448 PUCHAR pOutBuffer = NULL;
449 UCHAR Header802_3[14];
450 ULONG FrameLen = 0;
451 PEAPOL_PACKET pMsg1;
452 EAPOL_PACKET Packet;
453 UCHAR Mic[16];
454
455 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
456
457 // allocate memory pool
458 os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
459
460 if (mpool == NULL)
461 return;
462
463 // PTK Len = 80.
464 PTK = (UCHAR *) ROUND_UP(mpool, 4);
465 // digest Len = 80.
466 digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
467
468 pHeader = (PHEADER_802_11) Elem->Msg;
469
470 // Process message 1 from authenticator
471 pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
472
473 // 1. Save Replay counter, it will use to verify message 3 and construct message 2
474 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
475
476 // 2. Save ANonce
477 NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
478
479 // Generate random SNonce
480 GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
481
482 // Calc PTK(ANonce, SNonce)
483 WpaCountPTK(pAd,
484 pAd->StaCfg.PMK,
485 pAd->StaCfg.ANonce,
486 pAd->CommonCfg.Bssid,
487 pAd->StaCfg.SNonce,
488 pAd->CurrentAddress,
489 PTK,
490 LEN_PTK);
491
492 // Save key to PTK entry
493 NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
494
495 // init 802.3 header and Fill Packet
496 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
497
498 // Zero Message 2 body
499 NdisZeroMemory(&Packet, sizeof(Packet));
500 Packet.ProVer = EAPOL_VER;
501 Packet.ProType = EAPOLKey;
502 //
503 // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
504 //
505 Packet.KeyDesc.Type = WPA1_KEY_DESC;
506 // 1. Key descriptor version and appropriate RSN IE
507 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
508 {
509 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
510 }
511 else // TKIP
512 {
513 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
514 }
515
516 // fill in Data Material and its length
517 Packet.KeyDesc.KeyData[0] = IE_WPA;
518 Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
519 Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
520 NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
521
522 // Update packet length after decide Key data payload
523 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
524
525 // Update Key length
526 Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
527 Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
528 // 2. Key Type PeerKey
529 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
530
531 // 3. KeyMic field presented
532 Packet.KeyDesc.KeyInfo.KeyMic = 1;
533
534 //Convert to little-endian format.
535 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
536
537
538 // 4. Fill SNonce
539 NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
540
541 // 5. Key Replay Count
542 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
543
544 // Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
545 // Out buffer for transmitting message 2
546 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
547 if(pOutBuffer == NULL)
548 {
549 os_free_mem(pAd, mpool);
550 return;
551 }
552 // Prepare EAPOL frame for MIC calculation
553 // Be careful, only EAPOL frame is counted for MIC calculation
554 MakeOutgoingFrame(pOutBuffer, &FrameLen,
555 Packet.Body_Len[1] + 4, &Packet,
556 END_OF_ARGS);
557
558 // 6. Prepare and Fill MIC value
559 NdisZeroMemory(Mic, sizeof(Mic));
560 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
561 { // AES
562
563 HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
564 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
565 }
566 else
567 { // TKIP
568 hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
569 }
570 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
571
572 //hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
573
574 MakeOutgoingFrame(pOutBuffer, &FrameLen,
575 LENGTH_802_3, &Header802_3,
576 Packet.Body_Len[1] + 4, &Packet,
577 END_OF_ARGS);
578
579
580 // 5. Copy frame to Tx ring and send Msg 2 to authenticator
581 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
582
583 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
584 os_free_mem(pAd, (PUCHAR)mpool);
585
586 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
587 }
588
Wpa2PairMsg1Action(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)589 VOID Wpa2PairMsg1Action(
590 IN PRTMP_ADAPTER pAd,
591 IN MLME_QUEUE_ELEM *Elem)
592 {
593 PHEADER_802_11 pHeader;
594 UCHAR *mpool, *PTK, *digest;
595 PUCHAR pOutBuffer = NULL;
596 UCHAR Header802_3[14];
597 ULONG FrameLen = 0;
598 PEAPOL_PACKET pMsg1;
599 EAPOL_PACKET Packet;
600 UCHAR Mic[16];
601
602 DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
603
604 // allocate memory pool
605 os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
606
607 if (mpool == NULL)
608 return;
609
610 // PTK Len = 80.
611 PTK = (UCHAR *) ROUND_UP(mpool, 4);
612 // digest Len = 80.
613 digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
614
615 pHeader = (PHEADER_802_11) Elem->Msg;
616
617 // Process message 1 from authenticator
618 pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
619
620 // 1. Save Replay counter, it will use to verify message 3 and construct message 2
621 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
622
623 // 2. Save ANonce
624 NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
625
626 // Generate random SNonce
627 GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
628
629 if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
630 {
631 // cached PMKID
632 }
633
634 // Calc PTK(ANonce, SNonce)
635 WpaCountPTK(pAd,
636 pAd->StaCfg.PMK,
637 pAd->StaCfg.ANonce,
638 pAd->CommonCfg.Bssid,
639 pAd->StaCfg.SNonce,
640 pAd->CurrentAddress,
641 PTK,
642 LEN_PTK);
643
644 // Save key to PTK entry
645 NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
646
647 // init 802.3 header and Fill Packet
648 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
649
650 // Zero message 2 body
651 NdisZeroMemory(&Packet, sizeof(Packet));
652 Packet.ProVer = EAPOL_VER;
653 Packet.ProType = EAPOLKey;
654 //
655 // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
656 //
657 Packet.KeyDesc.Type = WPA2_KEY_DESC;
658
659 // 1. Key descriptor version and appropriate RSN IE
660 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
661 {
662 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
663 }
664 else // TKIP
665 {
666 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
667 }
668
669 // fill in Data Material and its length
670 Packet.KeyDesc.KeyData[0] = IE_WPA2;
671 Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
672 Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
673 NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
674
675 // Update packet length after decide Key data payload
676 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
677
678 // 2. Key Type PeerKey
679 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
680
681 // 3. KeyMic field presented
682 Packet.KeyDesc.KeyInfo.KeyMic = 1;
683
684 // Update Key Length
685 Packet.KeyDesc.KeyLength[0] = 0;
686 Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
687
688 // 4. Fill SNonce
689 NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
690
691 // 5. Key Replay Count
692 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
693
694 // Convert to little-endian format.
695 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
696
697 // Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
698 // Out buffer for transmitting message 2
699 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
700 if(pOutBuffer == NULL)
701 {
702 os_free_mem(pAd, mpool);
703 return;
704 }
705
706 // Prepare EAPOL frame for MIC calculation
707 // Be careful, only EAPOL frame is counted for MIC calculation
708 MakeOutgoingFrame(pOutBuffer, &FrameLen,
709 Packet.Body_Len[1] + 4, &Packet,
710 END_OF_ARGS);
711
712 // 6. Prepare and Fill MIC value
713 NdisZeroMemory(Mic, sizeof(Mic));
714 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
715 {
716 // AES
717 HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
718 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
719 }
720 else
721 {
722 hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
723 }
724 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
725
726
727 // Make Transmitting frame
728 MakeOutgoingFrame(pOutBuffer, &FrameLen,
729 LENGTH_802_3, &Header802_3,
730 Packet.Body_Len[1] + 4, &Packet,
731 END_OF_ARGS);
732
733
734 // 5. Copy frame to Tx ring
735 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
736
737 MlmeFreeMemory(pAd, pOutBuffer);
738 os_free_mem(pAd, mpool);
739
740 DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
741
742 }
743
744 /*
745 ========================================================================
746
747 Routine Description:
748 Process Pairwise key 4-way handshaking
749
750 Arguments:
751 pAd Pointer to our adapter
752 Elem Message body
753
754 Return Value:
755 None
756
757 Note:
758
759 ========================================================================
760 */
WpaPairMsg3Action(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)761 VOID WpaPairMsg3Action(
762 IN PRTMP_ADAPTER pAd,
763 IN MLME_QUEUE_ELEM *Elem)
764
765 {
766 PHEADER_802_11 pHeader;
767 PUCHAR pOutBuffer = NULL;
768 UCHAR Header802_3[14];
769 ULONG FrameLen = 0;
770 EAPOL_PACKET Packet;
771 PEAPOL_PACKET pMsg3;
772 UCHAR Mic[16], OldMic[16];
773 MAC_TABLE_ENTRY *pEntry = NULL;
774 UCHAR skip_offset;
775 KEY_INFO peerKeyInfo;
776
777 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
778
779 // Record 802.11 header & the received EAPOL packet Msg3
780 pHeader = (PHEADER_802_11) Elem->Msg;
781 pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
782
783 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
784 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
785
786 *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
787
788
789 // 1. Verify cipher type match
790 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
791 {
792 return;
793 }
794 else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
795 {
796 return;
797 }
798
799 // Verify RSN IE
800 //if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
801 if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
802 {
803 DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
804 hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
805 hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
806 return;
807 }
808 else
809 DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
810
811
812 // 2. Check MIC value
813 // Save the MIC and replace with zero
814 NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
815 NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
816 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
817 {
818 // AES
819 UCHAR digest[80];
820
821 HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
822 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
823 }
824 else // TKIP
825 {
826 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
827 }
828
829 if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
830 {
831 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
832 return;
833 }
834 else
835 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
836
837 // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
838 if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
839 return;
840
841 // Update new replay counter
842 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
843
844 // 4. Double check ANonce
845 if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
846 return;
847
848 // init 802.3 header and Fill Packet
849 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
850
851 // Zero Message 4 body
852 NdisZeroMemory(&Packet, sizeof(Packet));
853 Packet.ProVer = EAPOL_VER;
854 Packet.ProType = EAPOLKey;
855 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
856
857 //
858 // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
859 //
860 Packet.KeyDesc.Type = WPA1_KEY_DESC;
861
862 // Key descriptor version and appropriate RSN IE
863 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
864
865 // Update Key Length
866 Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
867 Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
868
869 // Key Type PeerKey
870 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
871
872 // KeyMic field presented
873 Packet.KeyDesc.KeyInfo.KeyMic = 1;
874
875 // In Msg3, KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
876 // Station sends Msg4 KeyInfo.secure should be the same as that in Msg.3
877 Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
878
879 // Convert to little-endian format.
880 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
881
882 // Key Replay count
883 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
884
885 // Out buffer for transmitting message 4
886 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
887 if(pOutBuffer == NULL)
888 return;
889
890 // Prepare EAPOL frame for MIC calculation
891 // Be careful, only EAPOL frame is counted for MIC calculation
892 MakeOutgoingFrame(pOutBuffer, &FrameLen,
893 Packet.Body_Len[1] + 4, &Packet,
894 END_OF_ARGS);
895
896 // Prepare and Fill MIC value
897 NdisZeroMemory(Mic, sizeof(Mic));
898 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
899 {
900 // AES
901 UCHAR digest[80];
902
903 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
904 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
905 }
906 else
907 {
908 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
909 }
910 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
911
912 // Update PTK
913 // Prepare pair-wise key information into shared key table
914 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
915 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
916 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
917 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
918 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
919
920 // Decide its ChiperAlg
921 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
922 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
923 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
924 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
925 else
926 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
927
928 // Update these related information to MAC_TABLE_ENTRY
929 pEntry = &pAd->MacTab.Content[BSSID_WCID];
930 NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
931 NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
932 NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
933 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
934
935 // Update pairwise key information to ASIC Shared Key Table
936 AsicAddSharedKeyEntry(pAd,
937 BSS0,
938 0,
939 pAd->SharedKey[BSS0][0].CipherAlg,
940 pAd->SharedKey[BSS0][0].Key,
941 pAd->SharedKey[BSS0][0].TxMic,
942 pAd->SharedKey[BSS0][0].RxMic);
943
944 // Update ASIC WCID attribute table and IVEIV table
945 RTMPAddWcidAttributeEntry(pAd,
946 BSS0,
947 0,
948 pAd->SharedKey[BSS0][0].CipherAlg,
949 pEntry);
950
951 // Make transmitting frame
952 MakeOutgoingFrame(pOutBuffer, &FrameLen,
953 LENGTH_802_3, &Header802_3,
954 Packet.Body_Len[1] + 4, &Packet,
955 END_OF_ARGS);
956
957
958 // Copy frame to Tx ring and Send Message 4 to authenticator
959 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
960
961 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
962
963 DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
964 }
965
Wpa2PairMsg3Action(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)966 VOID Wpa2PairMsg3Action(
967 IN PRTMP_ADAPTER pAd,
968 IN MLME_QUEUE_ELEM *Elem)
969
970 {
971 PHEADER_802_11 pHeader;
972 PUCHAR pOutBuffer = NULL;
973 UCHAR Header802_3[14];
974 ULONG FrameLen = 0;
975 EAPOL_PACKET Packet;
976 PEAPOL_PACKET pMsg3;
977 UCHAR Mic[16], OldMic[16];
978 UCHAR *mpool, *KEYDATA, *digest;
979 UCHAR Key[32];
980 MAC_TABLE_ENTRY *pEntry = NULL;
981 KEY_INFO peerKeyInfo;
982
983 // allocate memory
984 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
985
986 if(mpool == NULL)
987 return;
988
989 // KEYDATA Len = 512.
990 KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
991 // digest Len = 80.
992 digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
993
994 DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
995
996 pHeader = (PHEADER_802_11) Elem->Msg;
997
998 // Process message 3 frame.
999 pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1000
1001 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
1002 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1003
1004 *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
1005
1006 // 1. Verify cipher type match
1007 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
1008 {
1009 os_free_mem(pAd, (PUCHAR)mpool);
1010 return;
1011 }
1012 else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
1013 {
1014 os_free_mem(pAd, (PUCHAR)mpool);
1015 return;
1016 }
1017
1018 // 2. Check MIC value
1019 // Save the MIC and replace with zero
1020 NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1021 NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1022 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1023 {
1024 // AES
1025 HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1026 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1027 }
1028 else
1029 {
1030 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
1031 }
1032
1033 if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1034 {
1035 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
1036 os_free_mem(pAd, (PUCHAR)mpool);
1037 return;
1038 }
1039 else
1040 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
1041
1042 // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
1043 if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
1044 {
1045 os_free_mem(pAd, (PUCHAR)mpool);
1046 return;
1047 }
1048
1049 // Update new replay counter
1050 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1051
1052 // 4. Double check ANonce
1053 if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
1054 {
1055 os_free_mem(pAd, (PUCHAR)mpool);
1056 return;
1057 }
1058
1059 // Obtain GTK
1060 // 5. Decrypt GTK from Key Data
1061 DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
1062 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1063 {
1064 // Decrypt AES GTK
1065 AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
1066 }
1067 else // TKIP
1068 {
1069 INT i;
1070 // Decrypt TKIP GTK
1071 // Construct 32 bytes RC4 Key
1072 NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
1073 NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
1074 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1075 //discard first 256 bytes
1076 for(i = 0; i < 256; i++)
1077 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1078 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1079 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
1080 }
1081
1082 if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
1083 {
1084 os_free_mem(pAd, (PUCHAR)mpool);
1085 return;
1086 }
1087
1088 // Update GTK to ASIC
1089 // Update group key information to ASIC Shared Key Table
1090 AsicAddSharedKeyEntry(pAd,
1091 BSS0,
1092 pAd->StaCfg.DefaultKeyId,
1093 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1094 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
1095 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
1096 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
1097
1098 // Update ASIC WCID attribute table and IVEIV table
1099 RTMPAddWcidAttributeEntry(pAd,
1100 BSS0,
1101 pAd->StaCfg.DefaultKeyId,
1102 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1103 NULL);
1104
1105 // init 802.3 header and Fill Packet
1106 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1107
1108 // Zero message 4 body
1109 NdisZeroMemory(&Packet, sizeof(Packet));
1110 Packet.ProVer = EAPOL_VER;
1111 Packet.ProType = EAPOLKey;
1112 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
1113
1114 //
1115 // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
1116 //
1117 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1118
1119 // Key descriptor version and appropriate RSN IE
1120 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
1121
1122 // Update Key Length
1123 Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
1124 Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
1125
1126 // Key Type PeerKey
1127 Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
1128
1129 // KeyMic field presented
1130 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1131 Packet.KeyDesc.KeyInfo.Secure = 1;
1132
1133 // Convert to little-endian format.
1134 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
1135
1136 // Key Replay count
1137 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1138
1139 // Out buffer for transmitting message 4
1140 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
1141 if(pOutBuffer == NULL)
1142 {
1143 os_free_mem(pAd, (PUCHAR)mpool);
1144 return;
1145 }
1146
1147 // Prepare EAPOL frame for MIC calculation
1148 // Be careful, only EAPOL frame is counted for MIC calculation
1149 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1150 Packet.Body_Len[1] + 4, &Packet,
1151 END_OF_ARGS);
1152
1153 // Prepare and Fill MIC value
1154 NdisZeroMemory(Mic, sizeof(Mic));
1155 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1156 {
1157 // AES
1158 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1159 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1160 }
1161 else
1162 {
1163 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1164 }
1165 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1166
1167 // Update PTK
1168 // Prepare pair-wise key information into shared key table
1169 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1170 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1171 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
1172 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
1173 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
1174
1175 // Decide its ChiperAlg
1176 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1177 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1178 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1179 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1180 else
1181 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
1182
1183 // Update these related information to MAC_TABLE_ENTRY
1184 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1185 NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
1186 NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
1187 NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
1188 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1189
1190 // Update pairwise key information to ASIC Shared Key Table
1191 AsicAddSharedKeyEntry(pAd,
1192 BSS0,
1193 0,
1194 pAd->SharedKey[BSS0][0].CipherAlg,
1195 pAd->SharedKey[BSS0][0].Key,
1196 pAd->SharedKey[BSS0][0].TxMic,
1197 pAd->SharedKey[BSS0][0].RxMic);
1198
1199 // Update ASIC WCID attribute table and IVEIV table
1200 RTMPAddWcidAttributeEntry(pAd,
1201 BSS0,
1202 0,
1203 pAd->SharedKey[BSS0][0].CipherAlg,
1204 pEntry);
1205
1206 // Make Transmitting frame
1207 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1208 LENGTH_802_3, &Header802_3,
1209 Packet.Body_Len[1] + 4, &Packet,
1210 END_OF_ARGS);
1211
1212
1213 // Copy frame to Tx ring and Send Message 4 to authenticator
1214 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
1215
1216 // set 802.1x port control
1217 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1218 STA_PORT_SECURED(pAd);
1219
1220 // Indicate Connected for GUI
1221 pAd->IndicateMediaState = NdisMediaStateConnected;
1222
1223 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
1224 os_free_mem(pAd, (PUCHAR)mpool);
1225
1226
1227 // send wireless event - for set key done WPA2
1228 if (pAd->CommonCfg.bWirelessEvent)
1229 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
1230
1231 DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
1232
1233 }
1234
1235 /*
1236 ========================================================================
1237
1238 Routine Description:
1239 Process Group key 2-way handshaking
1240
1241 Arguments:
1242 pAd Pointer to our adapter
1243 Elem Message body
1244
1245 Return Value:
1246 None
1247
1248 Note:
1249
1250 ========================================================================
1251 */
WpaGroupMsg1Action(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)1252 VOID WpaGroupMsg1Action(
1253 IN PRTMP_ADAPTER pAd,
1254 IN MLME_QUEUE_ELEM *Elem)
1255
1256 {
1257 PUCHAR pOutBuffer = NULL;
1258 UCHAR Header802_3[14];
1259 ULONG FrameLen = 0;
1260 EAPOL_PACKET Packet;
1261 PEAPOL_PACKET pGroup;
1262 UCHAR *mpool, *digest, *KEYDATA;
1263 UCHAR Mic[16], OldMic[16];
1264 UCHAR GTK[32], Key[32];
1265 KEY_INFO peerKeyInfo;
1266
1267 // allocate memory
1268 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
1269
1270 if(mpool == NULL)
1271 return;
1272
1273 // digest Len = 80.
1274 digest = (UCHAR *) ROUND_UP(mpool, 4);
1275 // KEYDATA Len = 512.
1276 KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
1277
1278 DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
1279
1280 // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
1281 pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1282
1283 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
1284 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1285
1286 *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
1287
1288 // 0. Check cipher type match
1289 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
1290 {
1291 os_free_mem(pAd, (PUCHAR)mpool);
1292 return;
1293 }
1294 else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
1295 {
1296 os_free_mem(pAd, (PUCHAR)mpool);
1297 return;
1298 }
1299
1300 // 1. Verify Replay counter
1301 // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
1302 if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
1303 {
1304 os_free_mem(pAd, (PUCHAR)mpool);
1305 return;
1306 }
1307
1308 // Update new replay counter
1309 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1310
1311 // 2. Verify MIC is valid
1312 // Save the MIC and replace with zero
1313 NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1314 NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1315
1316 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1317 { // AES
1318 HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1319 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1320 }
1321 else
1322 { // TKIP
1323 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
1324 }
1325
1326 if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1327 {
1328 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
1329 MlmeFreeMemory(pAd, (PUCHAR)mpool);
1330 return;
1331 }
1332 else
1333 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
1334
1335
1336 // 3. Decrypt GTK from Key Data
1337 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1338 {
1339 // Decrypt AES GTK
1340 AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
1341 }
1342 else // TKIP
1343 {
1344 INT i;
1345
1346 // Decrypt TKIP GTK
1347 // Construct 32 bytes RC4 Key
1348 NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
1349 NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
1350 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1351 //discard first 256 bytes
1352 for(i = 0; i < 256; i++)
1353 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1354 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1355 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
1356 }
1357
1358 // Process decrypted key data material
1359 // Parse keyData to handle KDE format for WPA2PSK
1360 if (peerKeyInfo.EKD_DL)
1361 {
1362 if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
1363 {
1364 os_free_mem(pAd, (PUCHAR)mpool);
1365 return;
1366 }
1367 }
1368 else // WPAPSK
1369 {
1370 // set key material, TxMic and RxMic for WPAPSK
1371 NdisMoveMemory(GTK, KEYDATA, 32);
1372 NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
1373 pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
1374
1375 // Prepare pair-wise key information into shared key table
1376 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
1377 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
1378 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
1379 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, >K[16], LEN_TKIP_RXMICK);
1380 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, >K[24], LEN_TKIP_TXMICK);
1381
1382 // Update Shared Key CipherAlg
1383 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
1384 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1385 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
1386 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1387 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
1388 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
1389 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
1390 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
1391 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
1392
1393 //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
1394 }
1395
1396 // Update group key information to ASIC Shared Key Table
1397 AsicAddSharedKeyEntry(pAd,
1398 BSS0,
1399 pAd->StaCfg.DefaultKeyId,
1400 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1401 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
1402 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
1403 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
1404
1405 // Update ASIC WCID attribute table and IVEIV table
1406 RTMPAddWcidAttributeEntry(pAd,
1407 BSS0,
1408 pAd->StaCfg.DefaultKeyId,
1409 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1410 NULL);
1411
1412 // set 802.1x port control
1413 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1414 STA_PORT_SECURED(pAd);
1415
1416 // Indicate Connected for GUI
1417 pAd->IndicateMediaState = NdisMediaStateConnected;
1418
1419 // init header and Fill Packet
1420 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1421
1422 // Zero Group message 1 body
1423 NdisZeroMemory(&Packet, sizeof(Packet));
1424 Packet.ProVer = EAPOL_VER;
1425 Packet.ProType = EAPOLKey;
1426 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
1427
1428 //
1429 // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
1430 //
1431 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1432 {
1433 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1434 }
1435 else
1436 {
1437 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1438 }
1439
1440 // Key descriptor version and appropriate RSN IE
1441 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
1442
1443 // Update Key Length
1444 Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
1445 Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
1446
1447 // Key Index as G-Msg 1
1448 if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
1449 Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
1450
1451 // Key Type Group key
1452 Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
1453
1454 // KeyMic field presented
1455 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1456
1457 // Secure bit
1458 Packet.KeyDesc.KeyInfo.Secure = 1;
1459
1460 // Convert to little-endian format.
1461 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
1462
1463 // Key Replay count
1464 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1465
1466 // Out buffer for transmitting group message 2
1467 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
1468 if(pOutBuffer == NULL)
1469 {
1470 MlmeFreeMemory(pAd, (PUCHAR)mpool);
1471 return;
1472 }
1473
1474 // Prepare EAPOL frame for MIC calculation
1475 // Be careful, only EAPOL frame is counted for MIC calculation
1476 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1477 Packet.Body_Len[1] + 4, &Packet,
1478 END_OF_ARGS);
1479
1480 // Prepare and Fill MIC value
1481 NdisZeroMemory(Mic, sizeof(Mic));
1482 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1483 {
1484 // AES
1485 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1486 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1487 }
1488 else
1489 {
1490 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1491 }
1492 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1493
1494
1495 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1496 LENGTH_802_3, &Header802_3,
1497 Packet.Body_Len[1] + 4, &Packet,
1498 END_OF_ARGS);
1499
1500
1501 // 5. Copy frame to Tx ring and prepare for encryption
1502 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
1503
1504 // 6 Free allocated memory
1505 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
1506 os_free_mem(pAd, (PUCHAR)mpool);
1507
1508 // send wireless event - for set key done WPA2
1509 if (pAd->CommonCfg.bWirelessEvent)
1510 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1511
1512 DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
1513 }
1514
1515 /*
1516 ========================================================================
1517
1518 Routine Description:
1519 Init WPA MAC header
1520
1521 Arguments:
1522 pAd Pointer to our adapter
1523
1524 Return Value:
1525 None
1526
1527 Note:
1528
1529 ========================================================================
1530 */
WpaMacHeaderInit(IN PRTMP_ADAPTER pAd,IN OUT PHEADER_802_11 pHdr80211,IN UCHAR wep,IN PUCHAR pAddr1)1531 VOID WpaMacHeaderInit(
1532 IN PRTMP_ADAPTER pAd,
1533 IN OUT PHEADER_802_11 pHdr80211,
1534 IN UCHAR wep,
1535 IN PUCHAR pAddr1)
1536 {
1537 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
1538 pHdr80211->FC.Type = BTYPE_DATA;
1539 pHdr80211->FC.ToDs = 1;
1540 if (wep == 1)
1541 pHdr80211->FC.Wep = 1;
1542
1543 // Addr1: BSSID, Addr2: SA, Addr3: DA
1544 COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
1545 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
1546 COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
1547 pHdr80211->Sequence = pAd->Sequence;
1548 }
1549
1550 /*
1551 ========================================================================
1552
1553 Routine Description:
1554 Copy frame from waiting queue into relative ring buffer and set
1555 appropriate ASIC register to kick hardware encryption before really
1556 sent out to air.
1557
1558 Arguments:
1559 pAd Pointer to our adapter
1560 PNDIS_PACKET Pointer to outgoing Ndis frame
1561 NumberOfFrag Number of fragment required
1562
1563 Return Value:
1564 None
1565
1566 Note:
1567
1568 ========================================================================
1569 */
RTMPToWirelessSta(IN PRTMP_ADAPTER pAd,IN PUCHAR pHeader802_3,IN UINT HdrLen,IN PUCHAR pData,IN UINT DataLen,IN BOOLEAN is4wayFrame)1570 VOID RTMPToWirelessSta(
1571 IN PRTMP_ADAPTER pAd,
1572 IN PUCHAR pHeader802_3,
1573 IN UINT HdrLen,
1574 IN PUCHAR pData,
1575 IN UINT DataLen,
1576 IN BOOLEAN is4wayFrame)
1577
1578 {
1579 NDIS_STATUS Status;
1580 PNDIS_PACKET pPacket;
1581 UCHAR Index;
1582
1583 do
1584 {
1585 // 1. build a NDIS packet and call RTMPSendPacket();
1586 // be careful about how/when to release this internal allocated NDIS PACKET buffer
1587 Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
1588 if (Status != NDIS_STATUS_SUCCESS)
1589 break;
1590
1591 if (is4wayFrame)
1592 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
1593 else
1594 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
1595
1596 // 2. send out the packet
1597 Status = STASendPacket(pAd, pPacket);
1598 if(Status == NDIS_STATUS_SUCCESS)
1599 {
1600 // Dequeue one frame from TxSwQueue0..3 queue and process it
1601 // There are three place calling dequeue for TX ring.
1602 // 1. Here, right after queueing the frame.
1603 // 2. At the end of TxRingTxDone service routine.
1604 // 3. Upon NDIS call RTMPSendPackets
1605 if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1606 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
1607 {
1608 for(Index = 0; Index < 5; Index ++)
1609 if(pAd->TxSwQueue[Index].Number > 0)
1610 RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
1611 }
1612 }
1613 } while(FALSE);
1614
1615 }
1616
1617 /*
1618 ========================================================================
1619
1620 Routine Description:
1621 Check Sanity RSN IE form AP
1622
1623 Arguments:
1624
1625 Return Value:
1626
1627
1628 ========================================================================
1629 */
CheckRSNIE(IN PRTMP_ADAPTER pAd,IN PUCHAR pData,IN UCHAR DataLen,OUT UCHAR * Offset)1630 BOOLEAN CheckRSNIE(
1631 IN PRTMP_ADAPTER pAd,
1632 IN PUCHAR pData,
1633 IN UCHAR DataLen,
1634 OUT UCHAR *Offset)
1635 {
1636 PUCHAR pVIE;
1637 UCHAR len;
1638 PEID_STRUCT pEid;
1639 BOOLEAN result = FALSE;
1640
1641 pVIE = pData;
1642 len = DataLen;
1643 *Offset = 0;
1644
1645 while (len > sizeof(RSNIE2))
1646 {
1647 pEid = (PEID_STRUCT) pVIE;
1648 // WPA RSN IE
1649 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
1650 {
1651 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
1652 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1653 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1654 {
1655 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1656 result = TRUE;
1657 }
1658
1659 *Offset += (pEid->Len + 2);
1660 }
1661 // WPA2 RSN IE
1662 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
1663 {
1664 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
1665 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1666 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1667 {
1668 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1669 result = TRUE;
1670 }
1671
1672 *Offset += (pEid->Len + 2);
1673 }
1674 else
1675 {
1676 break;
1677 }
1678
1679 pVIE += (pEid->Len + 2);
1680 len -= (pEid->Len + 2);
1681 }
1682
1683 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
1684
1685 return result;
1686
1687 }
1688
1689
1690 /*
1691 ========================================================================
1692
1693 Routine Description:
1694 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
1695 GTK is encaptulated in KDE format at p.83 802.11i D10
1696
1697 Arguments:
1698
1699 Return Value:
1700
1701 Note:
1702 802.11i D10
1703
1704 ========================================================================
1705 */
ParseKeyData(IN PRTMP_ADAPTER pAd,IN PUCHAR pKeyData,IN UCHAR KeyDataLen,IN UCHAR bPairewise)1706 BOOLEAN ParseKeyData(
1707 IN PRTMP_ADAPTER pAd,
1708 IN PUCHAR pKeyData,
1709 IN UCHAR KeyDataLen,
1710 IN UCHAR bPairewise)
1711 {
1712 PKDE_ENCAP pKDE = NULL;
1713 PUCHAR pMyKeyData = pKeyData;
1714 UCHAR KeyDataLength = KeyDataLen;
1715 UCHAR GTKLEN;
1716 UCHAR skip_offset;
1717
1718 // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
1719 if (bPairewise)
1720 {
1721 // Check RSN IE whether it is WPA2/WPA2PSK
1722 if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
1723 {
1724 DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
1725 hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
1726 return FALSE;
1727 }
1728 else
1729 {
1730 // skip RSN IE
1731 pMyKeyData += skip_offset;
1732 KeyDataLength -= skip_offset;
1733
1734 //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
1735 }
1736 }
1737
1738 DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
1739
1740 // Parse EKD format
1741 if (KeyDataLength >= 8)
1742 {
1743 pKDE = (PKDE_ENCAP) pMyKeyData;
1744 }
1745 else
1746 {
1747 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
1748 return FALSE;
1749 }
1750
1751
1752 // Sanity check - shared key index should not be 0
1753 if (pKDE->GTKEncap.Kid == 0)
1754 {
1755 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
1756 return FALSE;
1757 }
1758
1759 // Sanity check - KED length
1760 if (KeyDataLength < (pKDE->Len + 2))
1761 {
1762 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
1763 return FALSE;
1764 }
1765
1766 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1767 GTKLEN = pKDE->Len -6;
1768
1769 if (GTKLEN < MIN_LEN_OF_GTK)
1770 {
1771 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
1772 return FALSE;
1773 }
1774 else
1775 DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
1776
1777 // Update GTK
1778 // set key material, TxMic and RxMic for WPAPSK
1779 NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
1780 pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
1781
1782 // Update shared key table
1783 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
1784 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
1785 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
1786 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
1787 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
1788
1789 // Update Shared Key CipherAlg
1790 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
1791 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1792 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
1793 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1794 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
1795 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
1796 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
1797 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
1798 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
1799
1800 return TRUE;
1801
1802 }
1803
1804 /*
1805 ========================================================================
1806
1807 Routine Description:
1808 Cisco CCKM PRF function
1809
1810 Arguments:
1811 key Cisco Base Transient Key (BTK)
1812 key_len The key length of the BTK
1813 data Ruquest Number(RN) + BSSID
1814 data_len The length of the data
1815 output Store for PTK(Pairwise transient keys)
1816 len The length of the output
1817 Return Value:
1818 None
1819
1820 Note:
1821 802.1i Annex F.9
1822
1823 ========================================================================
1824 */
CCKMPRF(IN UCHAR * key,IN INT key_len,IN UCHAR * data,IN INT data_len,OUT UCHAR * output,IN INT len)1825 VOID CCKMPRF(
1826 IN UCHAR *key,
1827 IN INT key_len,
1828 IN UCHAR *data,
1829 IN INT data_len,
1830 OUT UCHAR *output,
1831 IN INT len)
1832 {
1833 INT i;
1834 UCHAR input[1024];
1835 INT currentindex = 0;
1836 INT total_len;
1837
1838 NdisMoveMemory(input, data, data_len);
1839 total_len = data_len;
1840 input[total_len] = 0;
1841 total_len++;
1842 for (i = 0; i < (len + 19) / 20; i++)
1843 {
1844 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
1845 currentindex += 20;
1846 input[total_len - 1]++;
1847 }
1848 }
1849
1850 /*
1851 ========================================================================
1852
1853 Routine Description:
1854 Process MIC error indication and record MIC error timer.
1855
1856 Arguments:
1857 pAd Pointer to our adapter
1858 pWpaKey Pointer to the WPA key structure
1859
1860 Return Value:
1861 None
1862
1863 IRQL = DISPATCH_LEVEL
1864
1865 Note:
1866
1867 ========================================================================
1868 */
RTMPReportMicError(IN PRTMP_ADAPTER pAd,IN PCIPHER_KEY pWpaKey)1869 VOID RTMPReportMicError(
1870 IN PRTMP_ADAPTER pAd,
1871 IN PCIPHER_KEY pWpaKey)
1872 {
1873 ULONG Now;
1874 UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
1875
1876 // Record Last MIC error time and count
1877 Now = jiffies;
1878 if (pAd->StaCfg.MicErrCnt == 0)
1879 {
1880 pAd->StaCfg.MicErrCnt++;
1881 pAd->StaCfg.LastMicErrorTime = Now;
1882 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1883 }
1884 else if (pAd->StaCfg.MicErrCnt == 1)
1885 {
1886 if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
1887 {
1888 // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
1889 pAd->StaCfg.LastMicErrorTime = Now;
1890 }
1891 else
1892 {
1893
1894 if (pAd->CommonCfg.bWirelessEvent)
1895 RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1896
1897 pAd->StaCfg.LastMicErrorTime = Now;
1898 // Violate MIC error counts, MIC countermeasures kicks in
1899 pAd->StaCfg.MicErrCnt++;
1900 // We shall block all reception
1901 // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
1902 //
1903 // No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
1904 // if pAd->StaCfg.MicErrCnt greater than 2.
1905 //
1906 // RTMPRingCleanUp(pAd, QID_AC_BK);
1907 // RTMPRingCleanUp(pAd, QID_AC_BE);
1908 // RTMPRingCleanUp(pAd, QID_AC_VI);
1909 // RTMPRingCleanUp(pAd, QID_AC_VO);
1910 // RTMPRingCleanUp(pAd, QID_HCCA);
1911 }
1912 }
1913 else
1914 {
1915 // MIC error count >= 2
1916 // This should not happen
1917 ;
1918 }
1919 MlmeEnqueue(pAd,
1920 MLME_CNTL_STATE_MACHINE,
1921 OID_802_11_MIC_FAILURE_REPORT_FRAME,
1922 1,
1923 &unicastKey);
1924
1925 if (pAd->StaCfg.MicErrCnt == 2)
1926 {
1927 RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
1928 }
1929 }
1930
1931
1932 #ifdef WPA_SUPPLICANT_SUPPORT
1933 #define LENGTH_EAP_H 4
1934 // If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
WpaCheckEapCode(IN PRTMP_ADAPTER pAd,IN PUCHAR pFrame,IN USHORT FrameLen,IN USHORT OffSet)1935 INT WpaCheckEapCode(
1936 IN PRTMP_ADAPTER pAd,
1937 IN PUCHAR pFrame,
1938 IN USHORT FrameLen,
1939 IN USHORT OffSet)
1940 {
1941
1942 PUCHAR pData;
1943 INT result = 0;
1944
1945 if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
1946 return result;
1947
1948 pData = pFrame + OffSet; // skip offset bytes
1949
1950 if(*(pData+1) == EAPPacket) // 802.1x header - Packet Type
1951 {
1952 result = *(pData+4); // EAP header - Code
1953 }
1954
1955 return result;
1956 }
1957
WpaSendMicFailureToWpaSupplicant(IN PRTMP_ADAPTER pAd,IN BOOLEAN bUnicast)1958 VOID WpaSendMicFailureToWpaSupplicant(
1959 IN PRTMP_ADAPTER pAd,
1960 IN BOOLEAN bUnicast)
1961 {
1962 union iwreq_data wrqu;
1963 char custom[IW_CUSTOM_MAX] = {0};
1964
1965 sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
1966 if (bUnicast)
1967 sprintf(custom, "%s unicast", custom);
1968 wrqu.data.length = strlen(custom);
1969 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1970
1971 return;
1972 }
1973 #endif // WPA_SUPPLICANT_SUPPORT //
1974
WpaMicFailureReportFrame(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)1975 VOID WpaMicFailureReportFrame(
1976 IN PRTMP_ADAPTER pAd,
1977 IN MLME_QUEUE_ELEM *Elem)
1978 {
1979 PUCHAR pOutBuffer = NULL;
1980 UCHAR Header802_3[14];
1981 ULONG FrameLen = 0;
1982 EAPOL_PACKET Packet;
1983 UCHAR Mic[16];
1984 BOOLEAN bUnicast;
1985
1986 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
1987
1988 bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
1989 pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
1990
1991 // init 802.3 header and Fill Packet
1992 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1993
1994 NdisZeroMemory(&Packet, sizeof(Packet));
1995 Packet.ProVer = EAPOL_VER;
1996 Packet.ProType = EAPOLKey;
1997
1998 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1999
2000 // Request field presented
2001 Packet.KeyDesc.KeyInfo.Request = 1;
2002
2003 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
2004 {
2005 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
2006 }
2007 else // TKIP
2008 {
2009 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
2010 }
2011
2012 Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
2013
2014 // KeyMic field presented
2015 Packet.KeyDesc.KeyInfo.KeyMic = 1;
2016
2017 // Error field presented
2018 Packet.KeyDesc.KeyInfo.Error = 1;
2019
2020 // Update packet length after decide Key data payload
2021 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
2022
2023 // Key Replay Count
2024 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
2025 inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
2026
2027 // Convert to little-endian format.
2028 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
2029
2030
2031 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
2032 if(pOutBuffer == NULL)
2033 {
2034 return;
2035 }
2036
2037 // Prepare EAPOL frame for MIC calculation
2038 // Be careful, only EAPOL frame is counted for MIC calculation
2039 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2040 Packet.Body_Len[1] + 4, &Packet,
2041 END_OF_ARGS);
2042
2043 // Prepare and Fill MIC value
2044 NdisZeroMemory(Mic, sizeof(Mic));
2045 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
2046 { // AES
2047 UCHAR digest[20] = {0};
2048 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
2049 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
2050 }
2051 else
2052 { // TKIP
2053 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
2054 }
2055 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
2056
2057 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2058 LENGTH_802_3, &Header802_3,
2059 Packet.Body_Len[1] + 4, &Packet,
2060 END_OF_ARGS);
2061
2062 // opy frame to Tx ring and send MIC failure report frame to authenticator
2063 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
2064
2065 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
2066
2067 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
2068 }
2069
2070 /** from wpa_supplicant
2071 * inc_byte_array - Increment arbitrary length byte array by one
2072 * @counter: Pointer to byte array
2073 * @len: Length of the counter in bytes
2074 *
2075 * This function increments the last byte of the counter by one and continues
2076 * rolling over to more significant bytes if the byte was incremented from
2077 * 0xff to 0x00.
2078 */
inc_byte_array(UCHAR * counter,int len)2079 void inc_byte_array(UCHAR *counter, int len)
2080 {
2081 int pos = len - 1;
2082 while (pos >= 0) {
2083 counter[pos]++;
2084 if (counter[pos] != 0)
2085 break;
2086 pos--;
2087 }
2088 }
2089
WpaDisassocApAndBlockAssoc(IN PVOID SystemSpecific1,IN PVOID FunctionContext,IN PVOID SystemSpecific2,IN PVOID SystemSpecific3)2090 VOID WpaDisassocApAndBlockAssoc(
2091 IN PVOID SystemSpecific1,
2092 IN PVOID FunctionContext,
2093 IN PVOID SystemSpecific2,
2094 IN PVOID SystemSpecific3)
2095 {
2096 RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
2097 MLME_DISASSOC_REQ_STRUCT DisassocReq;
2098
2099 // disassoc from current AP first
2100 DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
2101 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
2102 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
2103
2104 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
2105 pAd->StaCfg.bBlockAssoc = TRUE;
2106 }
2107
2108