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 /* WPA OUI */
40 u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 };
41 u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 };
42 u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 };
43 u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 };
44 u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 };
45 u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 };
46 u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 };
47 u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 };
48 
49 /* WPA2 OUI */
50 u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
51 u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
52 u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
53 u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 };
54 u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 };
55 u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
56 
57 static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
58 				  u8 GroupKeyWepStatus,
59 				  u8 keyDescVer,
60 				  u8 MsgType,
61 				  u8 DefaultKeyIdx,
62 				  u8 * GTK,
63 				  u8 * RSNIE,
64 				  u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);
65 
66 static void CalculateMIC(u8 KeyDescVer,
67 			 u8 * PTK, struct rt_eapol_packet * pMsg);
68 
69 static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
70 
71 static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
72 				   struct rt_mlme_queue_elem *Elem);
73 
74 static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
75 				 struct rt_mlme_queue_elem *Elem);
76 
77 static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
78 				struct rt_mlme_queue_elem *Elem);
79 
80 static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
81 
82 /*
83     ==========================================================================
84     Description:
85         association state machine init, including state transition and timer init
86     Parameters:
87         S - pointer to the association state machine
88     ==========================================================================
89  */
WpaStateMachineInit(struct rt_rtmp_adapter * pAd,struct rt_state_machine * S,OUT STATE_MACHINE_FUNC Trans[])90 void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
91 			 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
92 {
93 	StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE,
94 			 MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK,
95 			 WPA_MACHINE_BASE);
96 
97 	StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket,
98 			      (STATE_MACHINE_FUNC) WpaEAPPacketAction);
99 	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart,
100 			      (STATE_MACHINE_FUNC) WpaEAPOLStartAction);
101 	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff,
102 			      (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction);
103 	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey,
104 			      (STATE_MACHINE_FUNC) WpaEAPOLKeyAction);
105 	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert,
106 			      (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction);
107 }
108 
109 /*
110     ==========================================================================
111     Description:
112         this is state machine function.
113         When receiving EAP packets which is  for 802.1x authentication use.
114         Not use in PSK case
115     Return:
116     ==========================================================================
117 */
WpaEAPPacketAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)118 void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
119 {
120 }
121 
WpaEAPOLASFAlertAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)122 void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
123 {
124 }
125 
WpaEAPOLLogoffAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)126 void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
127 {
128 }
129 
130 /*
131     ==========================================================================
132     Description:
133        Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
134     Return:
135     ==========================================================================
136 */
WpaEAPOLStartAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)137 void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
138 {
139 	struct rt_mac_table_entry *pEntry;
140 	struct rt_header_802_11 * pHeader;
141 
142 	DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
143 
144 	pHeader = (struct rt_header_802_11 *) Elem->Msg;
145 
146 	/*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */
147 	if (Elem->MsgLen == 6)
148 		pEntry = MacTableLookup(pAd, Elem->Msg);
149 	else {
150 		pEntry = MacTableLookup(pAd, pHeader->Addr2);
151 	}
152 
153 	if (pEntry) {
154 		DBGPRINT(RT_DEBUG_TRACE,
155 			 (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n",
156 			  pEntry->PortSecured, pEntry->WpaState,
157 			  pEntry->AuthMode, pEntry->PMKID_CacheIdx));
158 
159 		if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
160 		    && (pEntry->WpaState < AS_PTKSTART)
161 		    && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
162 			|| (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
163 			|| ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
164 			    && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) {
165 			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
166 			pEntry->WpaState = AS_INITPSK;
167 			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
168 			NdisZeroMemory(pEntry->R_Counter,
169 				       sizeof(pEntry->R_Counter));
170 			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
171 
172 			WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
173 		}
174 	}
175 }
176 
177 /*
178     ==========================================================================
179     Description:
180         This is state machine function.
181         When receiving EAPOL packets which is  for 802.1x key management.
182         Use both in WPA, and WPAPSK case.
183         In this function, further dispatch to different functions according to the received packet.  3 categories are :
184           1.  normal 4-way pairwisekey and 2-way groupkey handshake
185           2.  MIC error (Countermeasures attack)  report packet from STA.
186           3.  Request for pairwise/group key update from STA
187     Return:
188     ==========================================================================
189 */
WpaEAPOLKeyAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)190 void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
191 {
192 	struct rt_mac_table_entry *pEntry;
193 	struct rt_header_802_11 * pHeader;
194 	struct rt_eapol_packet * pEapol_packet;
195 	struct rt_key_info peerKeyInfo;
196 
197 	DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
198 
199 	pHeader = (struct rt_header_802_11 *) Elem->Msg;
200 	pEapol_packet =
201 	    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
202 
203 	NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
204 	NdisMoveMemory((u8 *)& peerKeyInfo,
205 		       (u8 *)& pEapol_packet->KeyDesc.KeyInfo,
206 		       sizeof(struct rt_key_info));
207 
208 	hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
209 		 (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
210 
211 	*((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));
212 
213 	do {
214 		pEntry = MacTableLookup(pAd, pHeader->Addr2);
215 
216 		if (!pEntry
217 		    || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
218 			break;
219 
220 		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
221 			break;
222 
223 		DBGPRINT(RT_DEBUG_TRACE,
224 			("Receive EAPoL-Key frame from STA %pMF\n",
225 				pEntry->Addr));
226 
227 		if (((pEapol_packet->ProVer != EAPOL_VER)
228 		     && (pEapol_packet->ProVer != EAPOL_VER2))
229 		    || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC)
230 			&& (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) {
231 			DBGPRINT(RT_DEBUG_ERROR,
232 				 ("Key descripter does not match with WPA rule\n"));
233 			break;
234 		}
235 		/* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */
236 		/* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */
237 		if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
238 		    && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) {
239 			DBGPRINT(RT_DEBUG_ERROR,
240 				 ("Key descripter version not match(TKIP) \n"));
241 			break;
242 		}
243 		/* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */
244 		/* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */
245 		else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
246 			 && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) {
247 			DBGPRINT(RT_DEBUG_ERROR,
248 				 ("Key descripter version not match(AES) \n"));
249 			break;
250 		}
251 		/* Check if this STA is in class 3 state and the WPA state is started */
252 		if ((pEntry->Sst == SST_ASSOC)
253 		    && (pEntry->WpaState >= AS_INITPSK)) {
254 			/* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */
255 			/* or not. */
256 			/* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */
257 			/* Key frame from the Authenticator must not have the Ack bit set. */
258 			if (peerKeyInfo.KeyAck == 1) {
259 				/* The frame is snet by Authenticator. */
260 				/* So the Supplicant side shall handle this. */
261 
262 				if ((peerKeyInfo.Secure == 0)
263 				    && (peerKeyInfo.Request == 0)
264 				    && (peerKeyInfo.Error == 0)
265 				    && (peerKeyInfo.KeyType == PAIRWISEKEY)) {
266 					/* Process 1. the message 1 of 4-way HS in WPA or WPA2 */
267 					/*                        EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
268 					/*                 2. the message 3 of 4-way HS in WPA */
269 					/*                        EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
270 					if (peerKeyInfo.KeyMic == 0)
271 						PeerPairMsg1Action(pAd, pEntry,
272 								   Elem);
273 					else
274 						PeerPairMsg3Action(pAd, pEntry,
275 								   Elem);
276 				} else if ((peerKeyInfo.Secure == 1)
277 					   && (peerKeyInfo.KeyMic == 1)
278 					   && (peerKeyInfo.Request == 0)
279 					   && (peerKeyInfo.Error == 0)) {
280 					/* Process 1. the message 3 of 4-way HS in WPA2 */
281 					/*                        EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
282 					/*                 2. the message 1 of group KS in WPA or WPA2 */
283 					/*                        EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */
284 					if (peerKeyInfo.KeyType == PAIRWISEKEY)
285 						PeerPairMsg3Action(pAd, pEntry,
286 								   Elem);
287 					else
288 						PeerGroupMsg1Action(pAd, pEntry,
289 								    Elem);
290 				}
291 			} else {
292 				/* The frame is snet by Supplicant. */
293 				/* So the Authenticator side shall handle this. */
294 				if ((peerKeyInfo.Request == 0) &&
295 				    (peerKeyInfo.Error == 0) &&
296 				    (peerKeyInfo.KeyMic == 1)) {
297 					if (peerKeyInfo.Secure == 0
298 					    && peerKeyInfo.KeyType ==
299 					    PAIRWISEKEY) {
300 						/* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */
301 						/* Process 1. message 2 of 4-way HS in WPA or WPA2 */
302 						/*                 2. message 4 of 4-way HS in WPA */
303 						if (CONV_ARRARY_TO_u16
304 						    (pEapol_packet->KeyDesc.
305 						     KeyDataLen) == 0) {
306 							PeerPairMsg4Action(pAd,
307 									   pEntry,
308 									   Elem);
309 						} else {
310 							PeerPairMsg2Action(pAd,
311 									   pEntry,
312 									   Elem);
313 						}
314 					} else if (peerKeyInfo.Secure == 1
315 						   && peerKeyInfo.KeyType ==
316 						   PAIRWISEKEY) {
317 						/* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */
318 						/* Process message 4 of 4-way HS in WPA2 */
319 						PeerPairMsg4Action(pAd, pEntry,
320 								   Elem);
321 					} else if (peerKeyInfo.Secure == 1
322 						   && peerKeyInfo.KeyType ==
323 						   GROUPKEY) {
324 						/* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */
325 						/* Process message 2 of Group key HS in WPA or WPA2 */
326 						PeerGroupMsg2Action(pAd, pEntry,
327 								    &Elem->
328 								    Msg
329 								    [LENGTH_802_11],
330 								    (Elem->
331 								     MsgLen -
332 								     LENGTH_802_11));
333 					}
334 				}
335 			}
336 		}
337 	} while (FALSE);
338 }
339 
340 /*
341 	========================================================================
342 
343 	Routine	Description:
344 		Copy frame from waiting queue into relative ring buffer and set
345 	appropriate ASIC register to kick hardware encryption before really
346 	sent out to air.
347 
348 	Arguments:
349 		pAd		Pointer	to our adapter
350 		void *	Pointer to outgoing Ndis frame
351 		NumberOfFrag	Number of fragment required
352 
353 	Return Value:
354 		None
355 
356 	Note:
357 
358 	========================================================================
359 */
RTMPToWirelessSta(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,u8 * pHeader802_3,u32 HdrLen,u8 * pData,u32 DataLen,IN BOOLEAN bClearFrame)360 void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
361 		       struct rt_mac_table_entry *pEntry,
362 		       u8 *pHeader802_3,
363 		       u32 HdrLen,
364 		       u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
365 {
366 	void *pPacket;
367 	int Status;
368 
369 	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
370 		return;
371 
372 	do {
373 		/* build a NDIS packet */
374 		Status =
375 		    RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
376 					   pData, DataLen);
377 		if (Status != NDIS_STATUS_SUCCESS)
378 			break;
379 
380 		if (bClearFrame)
381 			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
382 		else
383 			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
384 		{
385 			RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
386 
387 			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);	/* set a default value */
388 			if (pEntry->apidx != 0)
389 				RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket,
390 								  pEntry->
391 								  apidx);
392 
393 			RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
394 			RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
395 		}
396 
397 		{
398 			/* send out the packet */
399 			Status = STASendPacket(pAd, pPacket);
400 			if (Status == NDIS_STATUS_SUCCESS) {
401 				u8 Index;
402 
403 				/* Dequeue one frame from TxSwQueue0..3 queue and process it */
404 				/* There are three place calling dequeue for TX ring. */
405 				/* 1. Here, right after queueing the frame. */
406 				/* 2. At the end of TxRingTxDone service routine. */
407 				/* 3. Upon NDIS call RTMPSendPackets */
408 				if ((!RTMP_TEST_FLAG
409 				     (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
410 				    &&
411 				    (!RTMP_TEST_FLAG
412 				     (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
413 					for (Index = 0; Index < 5; Index++)
414 						if (pAd->TxSwQueue[Index].
415 						    Number > 0)
416 							RTMPDeQueuePacket(pAd,
417 									  FALSE,
418 									  Index,
419 									  MAX_TX_PROCESS);
420 				}
421 			}
422 		}
423 
424 	} while (FALSE);
425 }
426 
427 /*
428     ==========================================================================
429     Description:
430         This is a function to initialize 4-way handshake
431 
432     Return:
433 
434     ==========================================================================
435 */
WPAStart4WayHS(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,unsigned long TimeInterval)436 void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
437 		    struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
438 {
439 	u8 Header802_3[14];
440 	struct rt_eapol_packet EAPOLPKT;
441 	u8 *pBssid = NULL;
442 	u8 group_cipher = Ndis802_11WEPDisabled;
443 
444 	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
445 
446 	if (RTMP_TEST_FLAG
447 	    (pAd,
448 	     fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
449 	{
450 		DBGPRINT(RT_DEBUG_ERROR,
451 			 ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
452 		return;
453 	}
454 
455 	if (pBssid == NULL) {
456 		DBGPRINT(RT_DEBUG_ERROR,
457 			 ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
458 		return;
459 	}
460 	/* Check the status */
461 	if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) {
462 		DBGPRINT(RT_DEBUG_ERROR,
463 			 ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
464 		return;
465 	}
466 
467 	/* Increment replay counter by 1 */
468 	ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
469 
470 	/* Randomly generate ANonce */
471 	GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);
472 
473 	/* Construct EAPoL message - Pairwise Msg 1 */
474 	/* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
475 	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
476 	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0,	/* Default key index */
477 			  pEntry->ANonce, NULL,	/* TxRSC */
478 			  NULL,	/* GTK */
479 			  NULL,	/* RSNIE */
480 			  0,	/* RSNIE length */
481 			  &EAPOLPKT);
482 
483 	/* Make outgoing frame */
484 	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
485 	RTMPToWirelessSta(pAd, pEntry, Header802_3,
486 			  LENGTH_802_3, (u8 *)& EAPOLPKT,
487 			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
488 			  (pEntry->PortSecured ==
489 			   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
490 
491 	/* Trigger Retry Timer */
492 	RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
493 
494 	/* Update State */
495 	pEntry->WpaState = AS_PTKSTART;
496 
497 	DBGPRINT(RT_DEBUG_TRACE,
498 		 ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
499 
500 }
501 
502 /*
503 	========================================================================
504 
505 	Routine Description:
506 		Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
507 
508 	Arguments:
509 		pAd			Pointer	to our adapter
510 		Elem		Message body
511 
512 	Return Value:
513 		None
514 
515 	Note:
516 
517 	========================================================================
518 */
PeerPairMsg1Action(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,struct rt_mlme_queue_elem * Elem)519 void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
520 			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
521 {
522 	u8 PTK[80];
523 	u8 Header802_3[14];
524 	struct rt_eapol_packet * pMsg1;
525 	u32 MsgLen;
526 	struct rt_eapol_packet EAPOLPKT;
527 	u8 *pCurrentAddr = NULL;
528 	u8 *pmk_ptr = NULL;
529 	u8 group_cipher = Ndis802_11WEPDisabled;
530 	u8 *rsnie_ptr = NULL;
531 	u8 rsnie_len = 0;
532 
533 	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
534 
535 	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
536 		return;
537 
538 	if (Elem->MsgLen <
539 	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
540 	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
541 		return;
542 
543 	{
544 		pCurrentAddr = pAd->CurrentAddress;
545 		pmk_ptr = pAd->StaCfg.PMK;
546 		group_cipher = pAd->StaCfg.GroupCipher;
547 		rsnie_ptr = pAd->StaCfg.RSN_IE;
548 		rsnie_len = pAd->StaCfg.RSNIE_Len;
549 	}
550 
551 	/* Store the received frame */
552 	pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
553 	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
554 
555 	/* Sanity Check peer Pairwise message 1 - Replay Counter */
556 	if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
557 	    == FALSE)
558 		return;
559 
560 	/* Store Replay counter, it will use to verify message 3 and construct message 2 */
561 	NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter,
562 		       LEN_KEY_DESC_REPLAY);
563 
564 	/* Store ANonce */
565 	NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
566 		       LEN_KEY_DESC_NONCE);
567 
568 	/* Generate random SNonce */
569 	GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);
570 
571 	{
572 		/* Calculate PTK(ANonce, SNonce) */
573 		WpaDerivePTK(pAd,
574 			     pmk_ptr,
575 			     pEntry->ANonce,
576 			     pEntry->Addr,
577 			     pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);
578 
579 		/* Save key to PTK entry */
580 		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
581 	}
582 
583 	/* Update WpaState */
584 	pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
585 
586 	/* Construct EAPoL message - Pairwise Msg 2 */
587 	/*  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */
588 	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
589 	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0,	/* DefaultKeyIdx */
590 			  pEntry->SNonce, NULL,	/* TxRsc */
591 			  NULL,	/* GTK */
592 			  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
593 
594 	/* Make outgoing frame */
595 	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
596 
597 	RTMPToWirelessSta(pAd, pEntry,
598 			  Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
599 			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
600 
601 	DBGPRINT(RT_DEBUG_TRACE,
602 		 ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
603 }
604 
605 /*
606     ==========================================================================
607     Description:
608         When receiving the second packet of 4-way pairwisekey handshake.
609     Return:
610     ==========================================================================
611 */
PeerPairMsg2Action(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,struct rt_mlme_queue_elem * Elem)612 void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
613 			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
614 {
615 	u8 PTK[80];
616 	BOOLEAN Cancelled;
617 	struct rt_header_802_11 * pHeader;
618 	struct rt_eapol_packet EAPOLPKT;
619 	struct rt_eapol_packet * pMsg2;
620 	u32 MsgLen;
621 	u8 Header802_3[LENGTH_802_3];
622 	u8 TxTsc[6];
623 	u8 *pBssid = NULL;
624 	u8 *pmk_ptr = NULL;
625 	u8 *gtk_ptr = NULL;
626 	u8 default_key = 0;
627 	u8 group_cipher = Ndis802_11WEPDisabled;
628 	u8 *rsnie_ptr = NULL;
629 	u8 rsnie_len = 0;
630 
631 	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
632 
633 	if ((!pEntry) || (!pEntry->ValidAsCLI))
634 		return;
635 
636 	if (Elem->MsgLen <
637 	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
638 	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
639 		return;
640 
641 	/* check Entry in valid State */
642 	if (pEntry->WpaState < AS_PTKSTART)
643 		return;
644 
645 	/* pointer to 802.11 header */
646 	pHeader = (struct rt_header_802_11 *) Elem->Msg;
647 
648 	/* skip 802.11_header(24-byte) and LLC_header(8) */
649 	pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
650 	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
651 
652 	/* Store SNonce */
653 	NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
654 		       LEN_KEY_DESC_NONCE);
655 
656 	{
657 		/* Derive PTK */
658 		WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce,	/* ANONCE */
659 			     (u8 *) pBssid, pEntry->SNonce,	/* SNONCE */
660 			     pEntry->Addr, PTK, LEN_PTK);
661 
662 		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
663 	}
664 
665 	/* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
666 	if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
667 	    == FALSE)
668 		return;
669 
670 	do {
671 		/* delete retry timer */
672 		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
673 
674 		/* Change state */
675 		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
676 
677 		/* Increment replay counter by 1 */
678 		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
679 
680 		/* Construct EAPoL message - Pairwise Msg 3 */
681 		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
682 		ConstructEapolMsg(pEntry,
683 				  group_cipher,
684 				  EAPOL_PAIR_MSG_3,
685 				  default_key,
686 				  pEntry->ANonce,
687 				  TxTsc,
688 				  (u8 *) gtk_ptr,
689 				  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
690 
691 		/* Make outgoing frame */
692 		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
693 		RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
694 				  (u8 *)& EAPOLPKT,
695 				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
696 				  (pEntry->PortSecured ==
697 				   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
698 
699 		pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
700 		RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
701 
702 		/* Update State */
703 		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
704 	} while (FALSE);
705 
706 	DBGPRINT(RT_DEBUG_TRACE,
707 		 ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
708 }
709 
710 /*
711 	========================================================================
712 
713 	Routine Description:
714 		Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
715 
716 	Arguments:
717 		pAd	Pointer	to our adapter
718 		Elem		Message body
719 
720 	Return Value:
721 		None
722 
723 	Note:
724 
725 	========================================================================
726 */
PeerPairMsg3Action(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,struct rt_mlme_queue_elem * Elem)727 void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
728 			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
729 {
730 	struct rt_header_802_11 * pHeader;
731 	u8 Header802_3[14];
732 	struct rt_eapol_packet EAPOLPKT;
733 	struct rt_eapol_packet * pMsg3;
734 	u32 MsgLen;
735 	u8 *pCurrentAddr = NULL;
736 	u8 group_cipher = Ndis802_11WEPDisabled;
737 
738 	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
739 
740 	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
741 		return;
742 
743 	if (Elem->MsgLen <
744 	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
745 	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
746 		return;
747 
748 	{
749 		pCurrentAddr = pAd->CurrentAddress;
750 		group_cipher = pAd->StaCfg.GroupCipher;
751 
752 	}
753 
754 	/* Record 802.11 header & the received EAPOL packet Msg3 */
755 	pHeader = (struct rt_header_802_11 *) Elem->Msg;
756 	pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
757 	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
758 
759 	/* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
760 	if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
761 	    == FALSE)
762 		return;
763 
764 	/* Save Replay counter, it will use construct message 4 */
765 	NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
766 		       LEN_KEY_DESC_REPLAY);
767 
768 	/* Double check ANonce */
769 	if (!NdisEqualMemory
770 	    (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
771 		return;
772 	}
773 	/* Construct EAPoL message - Pairwise Msg 4 */
774 	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
775 	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0,	/* group key index not used in message 4 */
776 			  NULL,	/* Nonce not used in message 4 */
777 			  NULL,	/* TxRSC not used in message 4 */
778 			  NULL,	/* GTK not used in message 4 */
779 			  NULL,	/* RSN IE not used in message 4 */
780 			  0, &EAPOLPKT);
781 
782 	/* Update WpaState */
783 	pEntry->WpaState = AS_PTKINITDONE;
784 
785 	/* Update pairwise key */
786 	{
787 		struct rt_cipher_key *pSharedKey;
788 
789 		pSharedKey = &pAd->SharedKey[BSS0][0];
790 
791 		NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
792 
793 		/* Prepare pair-wise key information into shared key table */
794 		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
795 		pSharedKey->KeyLen = LEN_TKIP_EK;
796 		NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32],
797 			       LEN_TKIP_EK);
798 		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
799 			       LEN_TKIP_RXMICK);
800 		NdisMoveMemory(pSharedKey->TxMic,
801 			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
802 			       LEN_TKIP_TXMICK);
803 
804 		/* Decide its ChiperAlg */
805 		if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
806 			pSharedKey->CipherAlg = CIPHER_TKIP;
807 		else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
808 			pSharedKey->CipherAlg = CIPHER_AES;
809 		else
810 			pSharedKey->CipherAlg = CIPHER_NONE;
811 
812 		/* Update these related information to struct rt_mac_table_entry */
813 		pEntry = &pAd->MacTab.Content[BSSID_WCID];
814 		NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
815 			       LEN_TKIP_EK);
816 		NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
817 			       LEN_TKIP_RXMICK);
818 		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
819 			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
820 			       LEN_TKIP_TXMICK);
821 		pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
822 
823 		/* Update pairwise key information to ASIC Shared Key Table */
824 		AsicAddSharedKeyEntry(pAd,
825 				      BSS0,
826 				      0,
827 				      pSharedKey->CipherAlg,
828 				      pSharedKey->Key,
829 				      pSharedKey->TxMic, pSharedKey->RxMic);
830 
831 		/* Update ASIC WCID attribute table and IVEIV table */
832 		RTMPAddWcidAttributeEntry(pAd,
833 					  BSS0,
834 					  0, pSharedKey->CipherAlg, pEntry);
835 
836 	}
837 
838 	/* open 802.1x port control and privacy filter */
839 	if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
840 	    pEntry->AuthMode == Ndis802_11AuthModeWPA2) {
841 		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
842 		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
843 
844 		STA_PORT_SECURED(pAd);
845 		/* Indicate Connected for GUI */
846 		pAd->IndicateMediaState = NdisMediaStateConnected;
847 		DBGPRINT(RT_DEBUG_TRACE,
848 			 ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
849 			  GetAuthMode(pEntry->AuthMode),
850 			  GetEncryptType(pEntry->WepStatus),
851 			  GetEncryptType(group_cipher)));
852 	} else {
853 	}
854 
855 	/* Init 802.3 header and send out */
856 	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
857 	RTMPToWirelessSta(pAd, pEntry,
858 			  Header802_3, sizeof(Header802_3),
859 			  (u8 *)& EAPOLPKT,
860 			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
861 
862 	DBGPRINT(RT_DEBUG_TRACE,
863 		 ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
864 }
865 
866 /*
867     ==========================================================================
868     Description:
869         When receiving the last packet of 4-way pairwisekey handshake.
870         Initialize 2-way groupkey handshake following.
871     Return:
872     ==========================================================================
873 */
PeerPairMsg4Action(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,struct rt_mlme_queue_elem * Elem)874 void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
875 			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
876 {
877 	struct rt_eapol_packet * pMsg4;
878 	struct rt_header_802_11 * pHeader;
879 	u32 MsgLen;
880 	BOOLEAN Cancelled;
881 	u8 group_cipher = Ndis802_11WEPDisabled;
882 
883 	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
884 
885 	do {
886 		if ((!pEntry) || (!pEntry->ValidAsCLI))
887 			break;
888 
889 		if (Elem->MsgLen <
890 		    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
891 		     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
892 			break;
893 
894 		if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
895 			break;
896 
897 		/* pointer to 802.11 header */
898 		pHeader = (struct rt_header_802_11 *) Elem->Msg;
899 
900 		/* skip 802.11_header(24-byte) and LLC_header(8) */
901 		pMsg4 =
902 		    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
903 		MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
904 
905 		/* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
906 		if (PeerWpaMessageSanity
907 		    (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
908 			break;
909 
910 		/* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
911 		NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));
912 
913 		/* reset IVEIV in Asic */
914 		AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
915 
916 		pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
917 		NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
918 			       LEN_TKIP_EK);
919 		NdisMoveMemory(pEntry->PairwiseKey.RxMic,
920 			       &pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
921 			       LEN_TKIP_RXMICK);
922 		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
923 			       &pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
924 			       LEN_TKIP_TXMICK);
925 
926 		/* Set pairwise key to Asic */
927 		{
928 			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
929 			if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
930 				pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
931 			else if (pEntry->WepStatus ==
932 				 Ndis802_11Encryption3Enabled)
933 				pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
934 
935 			/* Add Pair-wise key to Asic */
936 			AsicAddPairwiseKeyEntry(pAd,
937 						pEntry->Addr,
938 						(u8)pEntry->Aid,
939 						&pEntry->PairwiseKey);
940 
941 			/* update WCID attribute table and IVEIV table for this entry */
942 			RTMPAddWcidAttributeEntry(pAd,
943 						  pEntry->apidx,
944 						  0,
945 						  pEntry->PairwiseKey.CipherAlg,
946 						  pEntry);
947 		}
948 
949 		/* 4. upgrade state */
950 		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
951 		pEntry->WpaState = AS_PTKINITDONE;
952 		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
953 
954 		if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
955 		    pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
956 			pEntry->GTKState = REKEY_ESTABLISHED;
957 			RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
958 
959 			/* send wireless event - for set key done WPA2 */
960 			if (pAd->CommonCfg.bWirelessEvent)
961 				RTMPSendWirelessEvent(pAd,
962 						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
963 						      pEntry->Addr,
964 						      pEntry->apidx, 0);
965 
966 			DBGPRINT(RT_DEBUG_OFF,
967 				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
968 				  pEntry->AuthMode,
969 				  GetAuthMode(pEntry->AuthMode),
970 				  pEntry->WepStatus,
971 				  GetEncryptType(pEntry->WepStatus),
972 				  group_cipher, GetEncryptType(group_cipher)));
973 		} else {
974 			/* 5. init Group 2-way handshake if necessary. */
975 			WPAStart2WayGroupHS(pAd, pEntry);
976 
977 			pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
978 			RTMPModTimer(&pEntry->RetryTimer,
979 				     PEER_MSG3_RETRY_EXEC_INTV);
980 		}
981 	} while (FALSE);
982 
983 }
984 
985 /*
986     ==========================================================================
987     Description:
988         This is a function to send the first packet of 2-way groupkey handshake
989     Return:
990 
991     ==========================================================================
992 */
WPAStart2WayGroupHS(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry)993 void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
994 {
995 	u8 Header802_3[14];
996 	u8 TxTsc[6];
997 	struct rt_eapol_packet EAPOLPKT;
998 	u8 group_cipher = Ndis802_11WEPDisabled;
999 	u8 default_key = 0;
1000 	u8 *gnonce_ptr = NULL;
1001 	u8 *gtk_ptr = NULL;
1002 	u8 *pBssid = NULL;
1003 
1004 	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
1005 
1006 	if ((!pEntry) || (!pEntry->ValidAsCLI))
1007 		return;
1008 
1009 	do {
1010 		/* Increment replay counter by 1 */
1011 		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
1012 
1013 		/* Construct EAPoL message - Group Msg 1 */
1014 		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
1015 		ConstructEapolMsg(pEntry,
1016 				  group_cipher,
1017 				  EAPOL_GROUP_MSG_1,
1018 				  default_key,
1019 				  (u8 *) gnonce_ptr,
1020 				  TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);
1021 
1022 		/* Make outgoing frame */
1023 		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
1024 		RTMPToWirelessSta(pAd, pEntry,
1025 				  Header802_3, LENGTH_802_3,
1026 				  (u8 *)& EAPOLPKT,
1027 				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
1028 				  FALSE);
1029 
1030 	} while (FALSE);
1031 
1032 	DBGPRINT(RT_DEBUG_TRACE,
1033 		 ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
1034 
1035 	return;
1036 }
1037 
1038 /*
1039 	========================================================================
1040 
1041 	Routine Description:
1042 		Process Group key 2-way handshaking
1043 
1044 	Arguments:
1045 		pAd	Pointer	to our adapter
1046 		Elem		Message body
1047 
1048 	Return Value:
1049 		None
1050 
1051 	Note:
1052 
1053 	========================================================================
1054 */
PeerGroupMsg1Action(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,struct rt_mlme_queue_elem * Elem)1055 void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
1056 			 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
1057 {
1058 	u8 Header802_3[14];
1059 	struct rt_eapol_packet EAPOLPKT;
1060 	struct rt_eapol_packet * pGroup;
1061 	u32 MsgLen;
1062 	BOOLEAN Cancelled;
1063 	u8 default_key = 0;
1064 	u8 group_cipher = Ndis802_11WEPDisabled;
1065 	u8 *pCurrentAddr = NULL;
1066 
1067 	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
1068 
1069 	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
1070 		return;
1071 
1072 	{
1073 		pCurrentAddr = pAd->CurrentAddress;
1074 		group_cipher = pAd->StaCfg.GroupCipher;
1075 		default_key = pAd->StaCfg.DefaultKeyId;
1076 	}
1077 
1078 	/* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */
1079 	pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1080 	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
1081 
1082 	/* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
1083 	if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
1084 	    == FALSE)
1085 		return;
1086 
1087 	/* delete retry timer */
1088 	RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1089 
1090 	/* Save Replay counter, it will use to construct message 2 */
1091 	NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
1092 		       LEN_KEY_DESC_REPLAY);
1093 
1094 	/* Construct EAPoL message - Group Msg 2 */
1095 	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
1096 	ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL,	/* Nonce not used */
1097 			  NULL,	/* TxRSC not used */
1098 			  NULL,	/* GTK not used */
1099 			  NULL,	/* RSN IE not used */
1100 			  0, &EAPOLPKT);
1101 
1102 	/* open 802.1x port control and privacy filter */
1103 	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1104 	pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1105 
1106 	STA_PORT_SECURED(pAd);
1107 	/* Indicate Connected for GUI */
1108 	pAd->IndicateMediaState = NdisMediaStateConnected;
1109 
1110 	DBGPRINT(RT_DEBUG_TRACE,
1111 		 ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
1112 		  GetAuthMode(pEntry->AuthMode),
1113 		  GetEncryptType(pEntry->WepStatus),
1114 		  GetEncryptType(group_cipher)));
1115 
1116 	/* init header and Fill Packet and send Msg 2 to authenticator */
1117 	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
1118 	RTMPToWirelessSta(pAd, pEntry,
1119 			  Header802_3, sizeof(Header802_3),
1120 			  (u8 *)& EAPOLPKT,
1121 			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);
1122 
1123 	DBGPRINT(RT_DEBUG_TRACE,
1124 		 ("<=== PeerGroupMsg1Action: sned group message 2\n"));
1125 }
1126 
1127 /*
1128     ==========================================================================
1129     Description:
1130         When receiving the last packet of 2-way groupkey handshake.
1131     Return:
1132     ==========================================================================
1133 */
PeerGroupMsg2Action(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,void * Msg,u32 MsgLen)1134 void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
1135 			 struct rt_mac_table_entry *pEntry,
1136 			 void * Msg, u32 MsgLen)
1137 {
1138 	u32 Len;
1139 	u8 *pData;
1140 	BOOLEAN Cancelled;
1141 	struct rt_eapol_packet * pMsg2;
1142 	u8 group_cipher = Ndis802_11WEPDisabled;
1143 
1144 	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
1145 
1146 	do {
1147 		if ((!pEntry) || (!pEntry->ValidAsCLI))
1148 			break;
1149 
1150 		if (MsgLen <
1151 		    (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
1152 		     MAX_LEN_OF_RSNIE - 2))
1153 			break;
1154 
1155 		if (pEntry->WpaState != AS_PTKINITDONE)
1156 			break;
1157 
1158 		pData = (u8 *)Msg;
1159 		pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
1160 		Len = MsgLen - LENGTH_802_1_H;
1161 
1162 		/* Sanity Check peer group message 2 - Replay Counter, MIC */
1163 		if (PeerWpaMessageSanity
1164 		    (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
1165 			break;
1166 
1167 		/* 3.  upgrade state */
1168 
1169 		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1170 		pEntry->GTKState = REKEY_ESTABLISHED;
1171 
1172 		if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
1173 		    || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) {
1174 			/* send wireless event - for set key done WPA2 */
1175 			if (pAd->CommonCfg.bWirelessEvent)
1176 				RTMPSendWirelessEvent(pAd,
1177 						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
1178 						      pEntry->Addr,
1179 						      pEntry->apidx, 0);
1180 
1181 			DBGPRINT(RT_DEBUG_OFF,
1182 				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1183 				  pEntry->AuthMode,
1184 				  GetAuthMode(pEntry->AuthMode),
1185 				  pEntry->WepStatus,
1186 				  GetEncryptType(pEntry->WepStatus),
1187 				  group_cipher, GetEncryptType(group_cipher)));
1188 		} else {
1189 			/* send wireless event - for set key done WPA */
1190 			if (pAd->CommonCfg.bWirelessEvent)
1191 				RTMPSendWirelessEvent(pAd,
1192 						      IW_SET_KEY_DONE_WPA1_EVENT_FLAG,
1193 						      pEntry->Addr,
1194 						      pEntry->apidx, 0);
1195 
1196 			DBGPRINT(RT_DEBUG_OFF,
1197 				 ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1198 				  pEntry->AuthMode,
1199 				  GetAuthMode(pEntry->AuthMode),
1200 				  pEntry->WepStatus,
1201 				  GetEncryptType(pEntry->WepStatus),
1202 				  group_cipher, GetEncryptType(group_cipher)));
1203 		}
1204 	} while (FALSE);
1205 }
1206 
1207 /*
1208 	========================================================================
1209 
1210 	Routine Description:
1211 		Classify WPA EAP message type
1212 
1213 	Arguments:
1214 		EAPType		Value of EAP message type
1215 		MsgType		Internal Message definition for MLME state machine
1216 
1217 	Return Value:
1218 		TRUE		Found appropriate message type
1219 		FALSE		No appropriate message type
1220 
1221 	IRQL = DISPATCH_LEVEL
1222 
1223 	Note:
1224 		All these constants are defined in wpa.h
1225 		For supplicant, there is only EAPOL Key message available
1226 
1227 	========================================================================
1228 */
WpaMsgTypeSubst(u8 EAPType,int * MsgType)1229 BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
1230 {
1231 	switch (EAPType) {
1232 	case EAPPacket:
1233 		*MsgType = MT2_EAPPacket;
1234 		break;
1235 	case EAPOLStart:
1236 		*MsgType = MT2_EAPOLStart;
1237 		break;
1238 	case EAPOLLogoff:
1239 		*MsgType = MT2_EAPOLLogoff;
1240 		break;
1241 	case EAPOLKey:
1242 		*MsgType = MT2_EAPOLKey;
1243 		break;
1244 	case EAPOLASFAlert:
1245 		*MsgType = MT2_EAPOLASFAlert;
1246 		break;
1247 	default:
1248 		return FALSE;
1249 	}
1250 	return TRUE;
1251 }
1252 
1253 /*
1254 	========================================================================
1255 
1256 	Routine Description:
1257 		The pseudo-random function(PRF) that hashes various inputs to
1258 		derive a pseudo-random value. To add liveness to the pseudo-random
1259 		value, a nonce should be one of the inputs.
1260 
1261 		It is used to generate PTK, GTK or some specific random value.
1262 
1263 	Arguments:
1264 		u8	*key,		-	the key material for HMAC_SHA1 use
1265 		int		key_len		-	the length of key
1266 		u8	*prefix		-	a prefix label
1267 		int		prefix_len	-	the length of the label
1268 		u8	*data		-	a specific data with variable length
1269 		int		data_len	-	the length of a specific data
1270 		int		len			-	the output length
1271 
1272 	Return Value:
1273 		u8	*output		-	the calculated result
1274 
1275 	Note:
1276 		802.11i-2004	Annex H.3
1277 
1278 	========================================================================
1279 */
PRF(u8 * key,int key_len,u8 * prefix,int prefix_len,u8 * data,int data_len,u8 * output,int len)1280 void PRF(u8 * key,
1281 	 int key_len,
1282 	 u8 * prefix,
1283 	 int prefix_len,
1284 	 u8 * data, int data_len, u8 * output, int len)
1285 {
1286 	int i;
1287 	u8 *input;
1288 	int currentindex = 0;
1289 	int total_len;
1290 
1291 	/* Allocate memory for input */
1292 	os_alloc_mem(NULL, (u8 **) & input, 1024);
1293 
1294 	if (input == NULL) {
1295 		DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
1296 		return;
1297 	}
1298 	/* Generate concatenation input */
1299 	NdisMoveMemory(input, prefix, prefix_len);
1300 
1301 	/* Concatenate a single octet containing 0 */
1302 	input[prefix_len] = 0;
1303 
1304 	/* Concatenate specific data */
1305 	NdisMoveMemory(&input[prefix_len + 1], data, data_len);
1306 	total_len = prefix_len + 1 + data_len;
1307 
1308 	/* Concatenate a single octet containing 0 */
1309 	/* This octet shall be update later */
1310 	input[total_len] = 0;
1311 	total_len++;
1312 
1313 	/* Iterate to calculate the result by hmac-sha-1 */
1314 	/* Then concatenate to last result */
1315 	for (i = 0; i < (len + 19) / 20; i++) {
1316 		HMAC_SHA1(key, key_len, input, total_len, &output[currentindex],
1317 			  SHA1_DIGEST_SIZE);
1318 		currentindex += 20;
1319 
1320 		/* update the last octet */
1321 		input[total_len - 1]++;
1322 	}
1323 	os_free_mem(NULL, input);
1324 }
1325 
1326 /*
1327 * F(P, S, c, i) = U1 xor U2 xor ... Uc
1328 * U1 = PRF(P, S || Int(i))
1329 * U2 = PRF(P, U1)
1330 * Uc = PRF(P, Uc-1)
1331 */
1332 
F(char * password,unsigned char * ssid,int ssidlength,int iterations,int count,unsigned char * output)1333 static void F(char *password, unsigned char *ssid, int ssidlength,
1334 	      int iterations, int count, unsigned char *output)
1335 {
1336 	unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
1337 	int i, j;
1338 
1339 	/* U1 = PRF(P, S || int(i)) */
1340 	memcpy(digest, ssid, ssidlength);
1341 	digest[ssidlength] = (unsigned char)((count >> 24) & 0xff);
1342 	digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff);
1343 	digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff);
1344 	digest[ssidlength + 3] = (unsigned char)(count & 0xff);
1345 	HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE);	/* for WPA update */
1346 
1347 	/* output = U1 */
1348 	memcpy(output, digest1, SHA1_DIGEST_SIZE);
1349 
1350 	for (i = 1; i < iterations; i++) {
1351 		/* Un = PRF(P, Un-1) */
1352 		HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE);	/* for WPA update */
1353 		memcpy(digest1, digest, SHA1_DIGEST_SIZE);
1354 
1355 		/* output = output xor Un */
1356 		for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1357 			output[j] ^= digest[j];
1358 		}
1359 	}
1360 }
1361 
1362 /*
1363 * password - ascii string up to 63 characters in length
1364 * ssid - octet string up to 32 octets
1365 * ssidlength - length of ssid in octets
1366 * output must be 40 octets in length and outputs 256 bits of key
1367 */
PasswordHash(char * password,u8 * ssid,int ssidlength,u8 * output)1368 int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
1369 {
1370 	if ((strlen(password) > 63) || (ssidlength > 32))
1371 		return 0;
1372 
1373 	F(password, ssid, ssidlength, 4096, 1, output);
1374 	F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
1375 	return 1;
1376 }
1377 
1378 /*
1379 	========================================================================
1380 
1381 	Routine Description:
1382 		It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
1383 		It shall be called by 4-way handshake processing.
1384 
1385 	Arguments:
1386 		pAd	-	pointer to our pAdapter context
1387 		PMK		-	pointer to PMK
1388 		ANonce	-	pointer to ANonce
1389 		AA		-	pointer to Authenticator Address
1390 		SNonce	-	pointer to SNonce
1391 		SA		-	pointer to Supplicant Address
1392 		len		-	indicate the length of PTK (octet)
1393 
1394 	Return Value:
1395 		Output		pointer to the PTK
1396 
1397 	Note:
1398 		Refer to IEEE 802.11i-2004 8.5.1.2
1399 
1400 	========================================================================
1401 */
WpaDerivePTK(struct rt_rtmp_adapter * pAd,u8 * PMK,u8 * ANonce,u8 * AA,u8 * SNonce,u8 * SA,u8 * output,u32 len)1402 void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
1403 		  u8 * PMK,
1404 		  u8 * ANonce,
1405 		  u8 * AA,
1406 		  u8 * SNonce,
1407 		  u8 * SA, u8 * output, u32 len)
1408 {
1409 	u8 concatenation[76];
1410 	u32 CurrPos = 0;
1411 	u8 temp[32];
1412 	u8 Prefix[] =
1413 	    { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
1414 		'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
1415 	};
1416 
1417 	/* initiate the concatenation input */
1418 	NdisZeroMemory(temp, sizeof(temp));
1419 	NdisZeroMemory(concatenation, 76);
1420 
1421 	/* Get smaller address */
1422 	if (RTMPCompareMemory(SA, AA, 6) == 1)
1423 		NdisMoveMemory(concatenation, AA, 6);
1424 	else
1425 		NdisMoveMemory(concatenation, SA, 6);
1426 	CurrPos += 6;
1427 
1428 	/* Get larger address */
1429 	if (RTMPCompareMemory(SA, AA, 6) == 1)
1430 		NdisMoveMemory(&concatenation[CurrPos], SA, 6);
1431 	else
1432 		NdisMoveMemory(&concatenation[CurrPos], AA, 6);
1433 
1434 	/* store the larger mac address for backward compatible of */
1435 	/* ralink proprietary STA-key issue */
1436 	NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
1437 	CurrPos += 6;
1438 
1439 	/* Get smaller Nonce */
1440 	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
1441 		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
1442 	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
1443 		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
1444 	else
1445 		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
1446 	CurrPos += 32;
1447 
1448 	/* Get larger Nonce */
1449 	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
1450 		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
1451 	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
1452 		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
1453 	else
1454 		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
1455 	CurrPos += 32;
1456 
1457 	hex_dump("concatenation=", concatenation, 76);
1458 
1459 	/* Use PRF to generate PTK */
1460 	PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
1461 
1462 }
1463 
1464 /*
1465 	========================================================================
1466 
1467 	Routine Description:
1468 		Generate random number by software.
1469 
1470 	Arguments:
1471 		pAd		-	pointer to our pAdapter context
1472 		macAddr	-	pointer to local MAC address
1473 
1474 	Return Value:
1475 
1476 	Note:
1477 		802.1ii-2004  Annex H.5
1478 
1479 	========================================================================
1480 */
GenRandom(struct rt_rtmp_adapter * pAd,u8 * macAddr,u8 * random)1481 void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
1482 {
1483 	int i, curr;
1484 	u8 local[80], KeyCounter[32];
1485 	u8 result[80];
1486 	unsigned long CurrentTime;
1487 	u8 prefix[] =
1488 	    { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };
1489 
1490 	/* Zero the related information */
1491 	NdisZeroMemory(result, 80);
1492 	NdisZeroMemory(local, 80);
1493 	NdisZeroMemory(KeyCounter, 32);
1494 
1495 	for (i = 0; i < 32; i++) {
1496 		/* copy the local MAC address */
1497 		COPY_MAC_ADDR(local, macAddr);
1498 		curr = MAC_ADDR_LEN;
1499 
1500 		/* concatenate the current time */
1501 		NdisGetSystemUpTime(&CurrentTime);
1502 		NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
1503 		curr += sizeof(CurrentTime);
1504 
1505 		/* concatenate the last result */
1506 		NdisMoveMemory(&local[curr], result, 32);
1507 		curr += 32;
1508 
1509 		/* concatenate a variable */
1510 		NdisMoveMemory(&local[curr], &i, 2);
1511 		curr += 2;
1512 
1513 		/* calculate the result */
1514 		PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
1515 	}
1516 
1517 	NdisMoveMemory(random, result, 32);
1518 }
1519 
1520 /*
1521 	========================================================================
1522 
1523 	Routine Description:
1524 		Build cipher suite in RSN-IE.
1525 		It only shall be called by RTMPMakeRSNIE.
1526 
1527 	Arguments:
1528 		pAd			-	pointer to our pAdapter context
1529 	ElementID	-	indicate the WPA1 or WPA2
1530 	WepStatus	-	indicate the encryption type
1531 		bMixCipher	-	a boolean to indicate the pairwise cipher and group
1532 						cipher are the same or not
1533 
1534 	Return Value:
1535 
1536 	Note:
1537 
1538 	========================================================================
1539 */
RTMPMakeRsnIeCipher(struct rt_rtmp_adapter * pAd,u8 ElementID,u32 WepStatus,IN BOOLEAN bMixCipher,u8 FlexibleCipher,u8 * pRsnIe,u8 * rsn_len)1540 static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
1541 				u8 ElementID,
1542 				u32 WepStatus,
1543 				IN BOOLEAN bMixCipher,
1544 				u8 FlexibleCipher,
1545 				u8 *pRsnIe, u8 * rsn_len)
1546 {
1547 	u8 PairwiseCnt;
1548 
1549 	*rsn_len = 0;
1550 
1551 	/* decide WPA2 or WPA1 */
1552 	if (ElementID == Wpa2Ie) {
1553 		struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;
1554 
1555 		/* Assign the verson as 1 */
1556 		pRsnie_cipher->version = 1;
1557 
1558 		switch (WepStatus) {
1559 			/* TKIP mode */
1560 		case Ndis802_11Encryption2Enabled:
1561 			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
1562 			pRsnie_cipher->ucount = 1;
1563 			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1564 				       OUI_WPA2_TKIP, 4);
1565 			*rsn_len = sizeof(struct rt_rsnie2);
1566 			break;
1567 
1568 			/* AES mode */
1569 		case Ndis802_11Encryption3Enabled:
1570 			if (bMixCipher)
1571 				NdisMoveMemory(pRsnie_cipher->mcast,
1572 					       OUI_WPA2_TKIP, 4);
1573 			else
1574 				NdisMoveMemory(pRsnie_cipher->mcast,
1575 					       OUI_WPA2_CCMP, 4);
1576 			pRsnie_cipher->ucount = 1;
1577 			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1578 				       OUI_WPA2_CCMP, 4);
1579 			*rsn_len = sizeof(struct rt_rsnie2);
1580 			break;
1581 
1582 			/* TKIP-AES mix mode */
1583 		case Ndis802_11Encryption4Enabled:
1584 			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
1585 
1586 			PairwiseCnt = 1;
1587 			/* Insert WPA2 TKIP as the first pairwise cipher */
1588 			if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
1589 				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1590 					       OUI_WPA2_TKIP, 4);
1591 				/* Insert WPA2 AES as the secondary pairwise cipher */
1592 				if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) {
1593 					NdisMoveMemory(pRsnie_cipher->ucast[0].
1594 						       oui + 4, OUI_WPA2_CCMP,
1595 						       4);
1596 					PairwiseCnt = 2;
1597 				}
1598 			} else {
1599 				/* Insert WPA2 AES as the first pairwise cipher */
1600 				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1601 					       OUI_WPA2_CCMP, 4);
1602 			}
1603 
1604 			pRsnie_cipher->ucount = PairwiseCnt;
1605 			*rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
1606 			break;
1607 		}
1608 
1609 		if ((pAd->OpMode == OPMODE_STA) &&
1610 		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
1611 		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
1612 			u32 GroupCipher = pAd->StaCfg.GroupCipher;
1613 			switch (GroupCipher) {
1614 			case Ndis802_11GroupWEP40Enabled:
1615 				NdisMoveMemory(pRsnie_cipher->mcast,
1616 					       OUI_WPA2_WEP40, 4);
1617 				break;
1618 			case Ndis802_11GroupWEP104Enabled:
1619 				NdisMoveMemory(pRsnie_cipher->mcast,
1620 					       OUI_WPA2_WEP104, 4);
1621 				break;
1622 			}
1623 		}
1624 		/* swap for big-endian platform */
1625 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1626 		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1627 	} else {
1628 		struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;
1629 
1630 		/* Assign OUI and version */
1631 		NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
1632 		pRsnie_cipher->version = 1;
1633 
1634 		switch (WepStatus) {
1635 			/* TKIP mode */
1636 		case Ndis802_11Encryption2Enabled:
1637 			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
1638 			pRsnie_cipher->ucount = 1;
1639 			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1640 				       OUI_WPA_TKIP, 4);
1641 			*rsn_len = sizeof(struct rt_rsnie);
1642 			break;
1643 
1644 			/* AES mode */
1645 		case Ndis802_11Encryption3Enabled:
1646 			if (bMixCipher)
1647 				NdisMoveMemory(pRsnie_cipher->mcast,
1648 					       OUI_WPA_TKIP, 4);
1649 			else
1650 				NdisMoveMemory(pRsnie_cipher->mcast,
1651 					       OUI_WPA_CCMP, 4);
1652 			pRsnie_cipher->ucount = 1;
1653 			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1654 				       OUI_WPA_CCMP, 4);
1655 			*rsn_len = sizeof(struct rt_rsnie);
1656 			break;
1657 
1658 			/* TKIP-AES mix mode */
1659 		case Ndis802_11Encryption4Enabled:
1660 			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
1661 
1662 			PairwiseCnt = 1;
1663 			/* Insert WPA TKIP as the first pairwise cipher */
1664 			if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
1665 				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1666 					       OUI_WPA_TKIP, 4);
1667 				/* Insert WPA AES as the secondary pairwise cipher */
1668 				if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) {
1669 					NdisMoveMemory(pRsnie_cipher->ucast[0].
1670 						       oui + 4, OUI_WPA_CCMP,
1671 						       4);
1672 					PairwiseCnt = 2;
1673 				}
1674 			} else {
1675 				/* Insert WPA AES as the first pairwise cipher */
1676 				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1677 					       OUI_WPA_CCMP, 4);
1678 			}
1679 
1680 			pRsnie_cipher->ucount = PairwiseCnt;
1681 			*rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
1682 			break;
1683 		}
1684 
1685 		if ((pAd->OpMode == OPMODE_STA) &&
1686 		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
1687 		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
1688 			u32 GroupCipher = pAd->StaCfg.GroupCipher;
1689 			switch (GroupCipher) {
1690 			case Ndis802_11GroupWEP40Enabled:
1691 				NdisMoveMemory(pRsnie_cipher->mcast,
1692 					       OUI_WPA_WEP40, 4);
1693 				break;
1694 			case Ndis802_11GroupWEP104Enabled:
1695 				NdisMoveMemory(pRsnie_cipher->mcast,
1696 					       OUI_WPA_WEP104, 4);
1697 				break;
1698 			}
1699 		}
1700 		/* swap for big-endian platform */
1701 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1702 		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1703 	}
1704 }
1705 
1706 /*
1707 	========================================================================
1708 
1709 	Routine Description:
1710 		Build AKM suite in RSN-IE.
1711 		It only shall be called by RTMPMakeRSNIE.
1712 
1713 	Arguments:
1714 		pAd			-	pointer to our pAdapter context
1715 	ElementID	-	indicate the WPA1 or WPA2
1716 	AuthMode	-	indicate the authentication mode
1717 		apidx		-	indicate the interface index
1718 
1719 	Return Value:
1720 
1721 	Note:
1722 
1723 	========================================================================
1724 */
RTMPMakeRsnIeAKM(struct rt_rtmp_adapter * pAd,u8 ElementID,u32 AuthMode,u8 apidx,u8 * pRsnIe,u8 * rsn_len)1725 static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
1726 			     u8 ElementID,
1727 			     u32 AuthMode,
1728 			     u8 apidx,
1729 			     u8 *pRsnIe, u8 * rsn_len)
1730 {
1731 	struct rt_rsnie_auth *pRsnie_auth;
1732 	u8 AkmCnt = 1;	/* default as 1 */
1733 
1734 	pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));
1735 
1736 	/* decide WPA2 or WPA1 */
1737 	if (ElementID == Wpa2Ie) {
1738 
1739 		switch (AuthMode) {
1740 		case Ndis802_11AuthModeWPA2:
1741 		case Ndis802_11AuthModeWPA1WPA2:
1742 			NdisMoveMemory(pRsnie_auth->auth[0].oui,
1743 				       OUI_WPA2_8021X_AKM, 4);
1744 			break;
1745 
1746 		case Ndis802_11AuthModeWPA2PSK:
1747 		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1748 			NdisMoveMemory(pRsnie_auth->auth[0].oui,
1749 				       OUI_WPA2_PSK_AKM, 4);
1750 			break;
1751 		default:
1752 			AkmCnt = 0;
1753 			break;
1754 
1755 		}
1756 	} else {
1757 		switch (AuthMode) {
1758 		case Ndis802_11AuthModeWPA:
1759 		case Ndis802_11AuthModeWPA1WPA2:
1760 			NdisMoveMemory(pRsnie_auth->auth[0].oui,
1761 				       OUI_WPA_8021X_AKM, 4);
1762 			break;
1763 
1764 		case Ndis802_11AuthModeWPAPSK:
1765 		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1766 			NdisMoveMemory(pRsnie_auth->auth[0].oui,
1767 				       OUI_WPA_PSK_AKM, 4);
1768 			break;
1769 
1770 		case Ndis802_11AuthModeWPANone:
1771 			NdisMoveMemory(pRsnie_auth->auth[0].oui,
1772 				       OUI_WPA_NONE_AKM, 4);
1773 			break;
1774 		default:
1775 			AkmCnt = 0;
1776 			break;
1777 		}
1778 	}
1779 
1780 	pRsnie_auth->acount = AkmCnt;
1781 	pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
1782 
1783 	/* update current RSNIE length */
1784 	(*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));
1785 
1786 }
1787 
1788 /*
1789 	========================================================================
1790 
1791 	Routine Description:
1792 		Build capability in RSN-IE.
1793 		It only shall be called by RTMPMakeRSNIE.
1794 
1795 	Arguments:
1796 		pAd			-	pointer to our pAdapter context
1797 	ElementID	-	indicate the WPA1 or WPA2
1798 		apidx		-	indicate the interface index
1799 
1800 	Return Value:
1801 
1802 	Note:
1803 
1804 	========================================================================
1805 */
RTMPMakeRsnIeCap(struct rt_rtmp_adapter * pAd,u8 ElementID,u8 apidx,u8 * pRsnIe,u8 * rsn_len)1806 static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
1807 			     u8 ElementID,
1808 			     u8 apidx,
1809 			     u8 *pRsnIe, u8 * rsn_len)
1810 {
1811 	RSN_CAPABILITIES *pRSN_Cap;
1812 
1813 	/* it could be ignored in WPA1 mode */
1814 	if (ElementID == WpaIe)
1815 		return;
1816 
1817 	pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));
1818 
1819 	pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
1820 
1821 	(*rsn_len) += sizeof(RSN_CAPABILITIES);	/* update current RSNIE length */
1822 
1823 }
1824 
1825 /*
1826 	========================================================================
1827 
1828 	Routine Description:
1829 		Build RSN IE context. It is not included element-ID and length.
1830 
1831 	Arguments:
1832 		pAd			-	pointer to our pAdapter context
1833 	AuthMode	-	indicate the authentication mode
1834 	WepStatus	-	indicate the encryption type
1835 		apidx		-	indicate the interface index
1836 
1837 	Return Value:
1838 
1839 	Note:
1840 
1841 	========================================================================
1842 */
RTMPMakeRSNIE(struct rt_rtmp_adapter * pAd,u32 AuthMode,u32 WepStatus,u8 apidx)1843 void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
1844 		   u32 AuthMode, u32 WepStatus, u8 apidx)
1845 {
1846 	u8 *pRsnIe = NULL;	/* primary RSNIE */
1847 	u8 *rsnielen_cur_p = 0;	/* the length of the primary RSNIE */
1848 	u8 *rsnielen_ex_cur_p = 0;	/* the length of the secondary RSNIE */
1849 	u8 PrimaryRsnie;
1850 	BOOLEAN bMixCipher = FALSE;	/* indicate the pairwise and group cipher are different */
1851 	u8 p_offset;
1852 	WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;	/* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */
1853 
1854 	rsnielen_cur_p = NULL;
1855 	rsnielen_ex_cur_p = NULL;
1856 
1857 	{
1858 		{
1859 			if (pAd->StaCfg.WpaSupplicantUP !=
1860 			    WPA_SUPPLICANT_DISABLE) {
1861 				if (AuthMode < Ndis802_11AuthModeWPA)
1862 					return;
1863 			} else {
1864 				/* Support WPAPSK or WPA2PSK in STA-Infra mode */
1865 				/* Support WPANone in STA-Adhoc mode */
1866 				if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
1867 				    (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1868 				    (AuthMode != Ndis802_11AuthModeWPANone)
1869 				    )
1870 					return;
1871 			}
1872 
1873 			DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));
1874 
1875 			/* Zero RSNIE context */
1876 			pAd->StaCfg.RSNIE_Len = 0;
1877 			NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
1878 
1879 			/* Pointer to RSNIE */
1880 			rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
1881 			pRsnIe = pAd->StaCfg.RSN_IE;
1882 
1883 			bMixCipher = pAd->StaCfg.bMixCipher;
1884 		}
1885 	}
1886 
1887 	/* indicate primary RSNIE as WPA or WPA2 */
1888 	if ((AuthMode == Ndis802_11AuthModeWPA) ||
1889 	    (AuthMode == Ndis802_11AuthModeWPAPSK) ||
1890 	    (AuthMode == Ndis802_11AuthModeWPANone) ||
1891 	    (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
1892 	    (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
1893 		PrimaryRsnie = WpaIe;
1894 	else
1895 		PrimaryRsnie = Wpa2Ie;
1896 
1897 	{
1898 		/* Build the primary RSNIE */
1899 		/* 1. insert cipher suite */
1900 		RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
1901 				    FlexibleCipher, pRsnIe, &p_offset);
1902 
1903 		/* 2. insert AKM */
1904 		RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
1905 				 &p_offset);
1906 
1907 		/* 3. insert capability */
1908 		RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
1909 	}
1910 
1911 	/* 4. update the RSNIE length */
1912 	*rsnielen_cur_p = p_offset;
1913 
1914 	hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
1915 
1916 }
1917 
1918 /*
1919     ==========================================================================
1920     Description:
1921 		Check whether the received frame is EAP frame.
1922 
1923 	Arguments:
1924 		pAd				-	pointer to our pAdapter context
1925 		pEntry			-	pointer to active entry
1926 		pData			-	the received frame
1927 		DataByteCount	-	the received frame's length
1928 		FromWhichBSSID	-	indicate the interface index
1929 
1930     Return:
1931          TRUE			-	This frame is EAP frame
1932          FALSE			-	otherwise
1933     ==========================================================================
1934 */
RTMPCheckWPAframe(struct rt_rtmp_adapter * pAd,struct rt_mac_table_entry * pEntry,u8 * pData,unsigned long DataByteCount,u8 FromWhichBSSID)1935 BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
1936 			  struct rt_mac_table_entry *pEntry,
1937 			  u8 *pData,
1938 			  unsigned long DataByteCount, u8 FromWhichBSSID)
1939 {
1940 	unsigned long Body_len;
1941 	BOOLEAN Cancelled;
1942 
1943 	if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
1944 		return FALSE;
1945 
1946 	/* Skip LLC header */
1947 	if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
1948 	    /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */
1949 	    NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) {
1950 		pData += 6;
1951 	}
1952 	/* Skip 2-bytes EAPoL type */
1953 	if (NdisEqualMemory(EAPOL, pData, 2)) {
1954 		pData += 2;
1955 	} else
1956 		return FALSE;
1957 
1958 	switch (*(pData + 1)) {
1959 	case EAPPacket:
1960 		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1961 		DBGPRINT(RT_DEBUG_TRACE,
1962 			 ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
1963 			  Body_len));
1964 		break;
1965 	case EAPOLStart:
1966 		DBGPRINT(RT_DEBUG_TRACE,
1967 			 ("Receive EAPOL-Start frame, TYPE = 1 \n"));
1968 		if (pEntry->EnqueueEapolStartTimerRunning !=
1969 		    EAPOL_START_DISABLE) {
1970 			DBGPRINT(RT_DEBUG_TRACE,
1971 				 ("Cancel the EnqueueEapolStartTimerRunning \n"));
1972 			RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer,
1973 					&Cancelled);
1974 			pEntry->EnqueueEapolStartTimerRunning =
1975 			    EAPOL_START_DISABLE;
1976 		}
1977 		break;
1978 	case EAPOLLogoff:
1979 		DBGPRINT(RT_DEBUG_TRACE,
1980 			 ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
1981 		break;
1982 	case EAPOLKey:
1983 		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1984 		DBGPRINT(RT_DEBUG_TRACE,
1985 			 ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
1986 			  Body_len));
1987 		break;
1988 	case EAPOLASFAlert:
1989 		DBGPRINT(RT_DEBUG_TRACE,
1990 			 ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
1991 		break;
1992 	default:
1993 		return FALSE;
1994 
1995 	}
1996 	return TRUE;
1997 }
1998 
1999 /*
2000     ==========================================================================
2001     Description:
2002 		Report the EAP message type
2003 
2004 	Arguments:
2005 		msg		-	EAPOL_PAIR_MSG_1
2006 					EAPOL_PAIR_MSG_2
2007 					EAPOL_PAIR_MSG_3
2008 					EAPOL_PAIR_MSG_4
2009 					EAPOL_GROUP_MSG_1
2010 					EAPOL_GROUP_MSG_2
2011 
2012     Return:
2013          message type string
2014 
2015     ==========================================================================
2016 */
GetEapolMsgType(char msg)2017 char *GetEapolMsgType(char msg)
2018 {
2019 	if (msg == EAPOL_PAIR_MSG_1)
2020 		return "Pairwise Message 1";
2021 	else if (msg == EAPOL_PAIR_MSG_2)
2022 		return "Pairwise Message 2";
2023 	else if (msg == EAPOL_PAIR_MSG_3)
2024 		return "Pairwise Message 3";
2025 	else if (msg == EAPOL_PAIR_MSG_4)
2026 		return "Pairwise Message 4";
2027 	else if (msg == EAPOL_GROUP_MSG_1)
2028 		return "Group Message 1";
2029 	else if (msg == EAPOL_GROUP_MSG_2)
2030 		return "Group Message 2";
2031 	else
2032 		return "Invalid Message";
2033 }
2034 
2035 /*
2036 	========================================================================
2037 
2038 	Routine Description:
2039     Check Sanity RSN IE of EAPoL message
2040 
2041 	Arguments:
2042 
2043 	Return Value:
2044 
2045 	========================================================================
2046 */
RTMPCheckRSNIE(struct rt_rtmp_adapter * pAd,u8 * pData,u8 DataLen,struct rt_mac_table_entry * pEntry,u8 * Offset)2047 BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
2048 		       u8 *pData,
2049 		       u8 DataLen,
2050 		       struct rt_mac_table_entry *pEntry, u8 * Offset)
2051 {
2052 	u8 *pVIE;
2053 	u8 len;
2054 	struct rt_eid * pEid;
2055 	BOOLEAN result = FALSE;
2056 
2057 	pVIE = pData;
2058 	len = DataLen;
2059 	*Offset = 0;
2060 
2061 	while (len > sizeof(struct rt_rsnie2)) {
2062 		pEid = (struct rt_eid *) pVIE;
2063 		/* WPA RSN IE */
2064 		if ((pEid->Eid == IE_WPA)
2065 		    && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
2066 			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
2067 			     || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
2068 			    &&
2069 			    (NdisEqualMemory
2070 			     (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
2071 			    && (pEntry->RSNIE_Len == (pEid->Len + 2))) {
2072 				result = TRUE;
2073 			}
2074 
2075 			*Offset += (pEid->Len + 2);
2076 		}
2077 		/* WPA2 RSN IE */
2078 		else if ((pEid->Eid == IE_RSN)
2079 			 && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) {
2080 			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2
2081 			     || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
2082 			    && (pEid->Eid == pEntry->RSN_IE[0])
2083 			    && ((pEid->Len + 2) >= pEntry->RSNIE_Len)
2084 			    &&
2085 			    (NdisEqualMemory
2086 			     (pEid->Octet, &pEntry->RSN_IE[2],
2087 			      pEntry->RSNIE_Len - 2))) {
2088 
2089 				result = TRUE;
2090 			}
2091 
2092 			*Offset += (pEid->Len + 2);
2093 		} else {
2094 			break;
2095 		}
2096 
2097 		pVIE += (pEid->Len + 2);
2098 		len -= (pEid->Len + 2);
2099 	}
2100 
2101 	return result;
2102 
2103 }
2104 
2105 /*
2106 	========================================================================
2107 
2108 	Routine Description:
2109     Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
2110     GTK  is encaptulated in KDE format at  p.83 802.11i D10
2111 
2112 	Arguments:
2113 
2114 	Return Value:
2115 
2116 	Note:
2117         802.11i D10
2118 
2119 	========================================================================
2120 */
RTMPParseEapolKeyData(struct rt_rtmp_adapter * pAd,u8 * pKeyData,u8 KeyDataLen,u8 GroupKeyIndex,u8 MsgType,IN BOOLEAN bWPA2,struct rt_mac_table_entry * pEntry)2121 BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
2122 			      u8 *pKeyData,
2123 			      u8 KeyDataLen,
2124 			      u8 GroupKeyIndex,
2125 			      u8 MsgType,
2126 			      IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
2127 {
2128 	struct rt_kde_encap * pKDE = NULL;
2129 	u8 *pMyKeyData = pKeyData;
2130 	u8 KeyDataLength = KeyDataLen;
2131 	u8 GTKLEN = 0;
2132 	u8 DefaultIdx = 0;
2133 	u8 skip_offset;
2134 
2135 	/* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */
2136 	if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) {
2137 		/* Check RSN IE whether it is WPA2/WPA2PSK */
2138 		if (!RTMPCheckRSNIE
2139 		    (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) {
2140 			/* send wireless event - for RSN IE different */
2141 			if (pAd->CommonCfg.bWirelessEvent)
2142 				RTMPSendWirelessEvent(pAd,
2143 						      IW_RSNIE_DIFF_EVENT_FLAG,
2144 						      pEntry->Addr,
2145 						      pEntry->apidx, 0);
2146 
2147 			DBGPRINT(RT_DEBUG_ERROR,
2148 				 ("RSN_IE Different in msg %d of 4-way handshake!\n",
2149 				  MsgType));
2150 			hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
2151 			hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
2152 				 pEntry->RSNIE_Len);
2153 
2154 			return FALSE;
2155 		} else {
2156 			if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
2157 				WpaShowAllsuite(pMyKeyData, skip_offset);
2158 
2159 				/* skip RSN IE */
2160 				pMyKeyData += skip_offset;
2161 				KeyDataLength -= skip_offset;
2162 				DBGPRINT(RT_DEBUG_TRACE,
2163 					 ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n",
2164 					  skip_offset));
2165 			} else
2166 				return TRUE;
2167 		}
2168 	}
2169 
2170 	DBGPRINT(RT_DEBUG_TRACE,
2171 		 ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
2172 		  KeyDataLength));
2173 	/*hex_dump("remain data", pMyKeyData, KeyDataLength); */
2174 
2175 	/* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
2176 	if (bWPA2
2177 	    && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
2178 		if (KeyDataLength >= 8)	/* KDE format exclude GTK length */
2179 		{
2180 			pKDE = (struct rt_kde_encap *) pMyKeyData;
2181 
2182 			DefaultIdx = pKDE->GTKEncap.Kid;
2183 
2184 			/* Sanity check - KED length */
2185 			if (KeyDataLength < (pKDE->Len + 2)) {
2186 				DBGPRINT(RT_DEBUG_ERROR,
2187 					 ("ERROR: The len from KDE is too short \n"));
2188 				return FALSE;
2189 			}
2190 			/* Get GTK length - refer to IEEE 802.11i-2004 p.82 */
2191 			GTKLEN = pKDE->Len - 6;
2192 			if (GTKLEN < LEN_AES_KEY) {
2193 				DBGPRINT(RT_DEBUG_ERROR,
2194 					 ("ERROR: GTK Key length is too short (%d) \n",
2195 					  GTKLEN));
2196 				return FALSE;
2197 			}
2198 
2199 		} else {
2200 			DBGPRINT(RT_DEBUG_ERROR,
2201 				 ("ERROR: KDE format length is too short \n"));
2202 			return FALSE;
2203 		}
2204 
2205 		DBGPRINT(RT_DEBUG_TRACE,
2206 			 ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
2207 			  DefaultIdx, GTKLEN));
2208 		/* skip it */
2209 		pMyKeyData += 8;
2210 		KeyDataLength -= 8;
2211 
2212 	} else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
2213 		DefaultIdx = GroupKeyIndex;
2214 		DBGPRINT(RT_DEBUG_TRACE,
2215 			 ("GTK DefaultKeyID=%d \n", DefaultIdx));
2216 	}
2217 	/* Sanity check - shared key index must be 1 ~ 3 */
2218 	if (DefaultIdx < 1 || DefaultIdx > 3) {
2219 		DBGPRINT(RT_DEBUG_ERROR,
2220 			 ("ERROR: GTK Key index(%d) is invalid in %s %s \n",
2221 			  DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"),
2222 			  GetEapolMsgType(MsgType)));
2223 		return FALSE;
2224 	}
2225 
2226 	{
2227 		struct rt_cipher_key *pSharedKey;
2228 
2229 		/* set key material, TxMic and RxMic */
2230 		NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
2231 		pAd->StaCfg.DefaultKeyId = DefaultIdx;
2232 
2233 		pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
2234 
2235 		/* Prepare pair-wise key information into shared key table */
2236 		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
2237 		pSharedKey->KeyLen = LEN_TKIP_EK;
2238 		NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
2239 		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
2240 			       LEN_TKIP_RXMICK);
2241 		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
2242 			       LEN_TKIP_TXMICK);
2243 
2244 		/* Update Shared Key CipherAlg */
2245 		pSharedKey->CipherAlg = CIPHER_NONE;
2246 		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
2247 			pSharedKey->CipherAlg = CIPHER_TKIP;
2248 		else if (pAd->StaCfg.GroupCipher ==
2249 			 Ndis802_11Encryption3Enabled)
2250 			pSharedKey->CipherAlg = CIPHER_AES;
2251 		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
2252 			pSharedKey->CipherAlg = CIPHER_WEP64;
2253 		else if (pAd->StaCfg.GroupCipher ==
2254 			 Ndis802_11GroupWEP104Enabled)
2255 			pSharedKey->CipherAlg = CIPHER_WEP128;
2256 
2257 		/* Update group key information to ASIC Shared Key Table */
2258 		AsicAddSharedKeyEntry(pAd,
2259 				      BSS0,
2260 				      pAd->StaCfg.DefaultKeyId,
2261 				      pSharedKey->CipherAlg,
2262 				      pSharedKey->Key,
2263 				      pSharedKey->TxMic, pSharedKey->RxMic);
2264 
2265 		/* Update ASIC WCID attribute table and IVEIV table */
2266 		RTMPAddWcidAttributeEntry(pAd,
2267 					  BSS0,
2268 					  pAd->StaCfg.DefaultKeyId,
2269 					  pSharedKey->CipherAlg, NULL);
2270 	}
2271 
2272 	return TRUE;
2273 
2274 }
2275 
2276 /*
2277 	========================================================================
2278 
2279 	Routine Description:
2280 		Construct EAPoL message for WPA handshaking
2281 		Its format is below,
2282 
2283 		+--------------------+
2284 		| Protocol Version	 |  1 octet
2285 		+--------------------+
2286 		| Protocol Type		 |	1 octet
2287 		+--------------------+
2288 		| Body Length		 |  2 octets
2289 		+--------------------+
2290 		| Descriptor Type	 |	1 octet
2291 		+--------------------+
2292 		| Key Information    |	2 octets
2293 		+--------------------+
2294 		| Key Length	     |  1 octet
2295 		+--------------------+
2296 		| Key Repaly Counter |	8 octets
2297 		+--------------------+
2298 		| Key Nonce		     |  32 octets
2299 		+--------------------+
2300 		| Key IV			 |  16 octets
2301 		+--------------------+
2302 		| Key RSC			 |  8 octets
2303 		+--------------------+
2304 		| Key ID or Reserved |	8 octets
2305 		+--------------------+
2306 		| Key MIC			 |	16 octets
2307 		+--------------------+
2308 		| Key Data Length	 |	2 octets
2309 		+--------------------+
2310 		| Key Data			 |	n octets
2311 		+--------------------+
2312 
2313 	Arguments:
2314 		pAd			Pointer	to our adapter
2315 
2316 	Return Value:
2317 		None
2318 
2319 	Note:
2320 
2321 	========================================================================
2322 */
ConstructEapolMsg(struct rt_mac_table_entry * pEntry,u8 GroupKeyWepStatus,u8 MsgType,u8 DefaultKeyIdx,u8 * KeyNonce,u8 * TxRSC,u8 * GTK,u8 * RSNIE,u8 RSNIE_Len,struct rt_eapol_packet * pMsg)2323 void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
2324 		       u8 GroupKeyWepStatus,
2325 		       u8 MsgType,
2326 		       u8 DefaultKeyIdx,
2327 		       u8 * KeyNonce,
2328 		       u8 * TxRSC,
2329 		       u8 * GTK,
2330 		       u8 * RSNIE,
2331 		       u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
2332 {
2333 	BOOLEAN bWPA2 = FALSE;
2334 	u8 KeyDescVer;
2335 
2336 	/* Choose WPA2 or not */
2337 	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2338 	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2339 		bWPA2 = TRUE;
2340 
2341 	/* Init Packet and Fill header */
2342 	pMsg->ProVer = EAPOL_VER;
2343 	pMsg->ProType = EAPOLKey;
2344 
2345 	/* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
2346 	SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
2347 
2348 	/* Fill in EAPoL descriptor */
2349 	if (bWPA2)
2350 		pMsg->KeyDesc.Type = WPA2_KEY_DESC;
2351 	else
2352 		pMsg->KeyDesc.Type = WPA1_KEY_DESC;
2353 
2354 	/* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
2355 	{
2356 		/* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */
2357 		/* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */
2358 		KeyDescVer =
2359 		    (((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
2360 		      || (GroupKeyWepStatus ==
2361 			  Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
2362 		     : (DESC_TYPE_TKIP));
2363 	}
2364 
2365 	pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
2366 
2367 	/* Specify Key Type as Group(0) or Pairwise(1) */
2368 	if (MsgType >= EAPOL_GROUP_MSG_1)
2369 		pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
2370 	else
2371 		pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
2372 
2373 	/* Specify Key Index, only group_msg1_WPA1 */
2374 	if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
2375 		pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
2376 
2377 	if (MsgType == EAPOL_PAIR_MSG_3)
2378 		pMsg->KeyDesc.KeyInfo.Install = 1;
2379 
2380 	if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
2381 	    || (MsgType == EAPOL_GROUP_MSG_1))
2382 		pMsg->KeyDesc.KeyInfo.KeyAck = 1;
2383 
2384 	if (MsgType != EAPOL_PAIR_MSG_1)
2385 		pMsg->KeyDesc.KeyInfo.KeyMic = 1;
2386 
2387 	if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
2388 	    (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
2389 		pMsg->KeyDesc.KeyInfo.Secure = 1;
2390 	}
2391 
2392 	if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
2393 		      (MsgType == EAPOL_GROUP_MSG_1))) {
2394 		pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
2395 	}
2396 	/* key Information element has done. */
2397 	*(u16 *) (&pMsg->KeyDesc.KeyInfo) =
2398 	    cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));
2399 
2400 	/* Fill in Key Length */
2401 	{
2402 		if (MsgType >= EAPOL_GROUP_MSG_1) {
2403 			/* the length of group key cipher */
2404 			pMsg->KeyDesc.KeyLength[1] =
2405 			    ((GroupKeyWepStatus ==
2406 			      Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH :
2407 			     LEN_AES_KEY);
2408 		} else {
2409 			/* the length of pairwise key cipher */
2410 			pMsg->KeyDesc.KeyLength[1] =
2411 			    ((pEntry->WepStatus ==
2412 			      Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
2413 			     LEN_AES_KEY);
2414 		}
2415 	}
2416 
2417 	/* Fill in replay counter */
2418 	NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
2419 		       LEN_KEY_DESC_REPLAY);
2420 
2421 	/* Fill Key Nonce field */
2422 	/* ANonce : pairwise_msg1 & pairwise_msg3 */
2423 	/* SNonce : pairwise_msg2 */
2424 	/* GNonce : group_msg1_wpa1 */
2425 	if ((MsgType <= EAPOL_PAIR_MSG_3)
2426 	    || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
2427 		NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce,
2428 			       LEN_KEY_DESC_NONCE);
2429 
2430 	/* Fill key IV - WPA2 as 0, WPA1 as random */
2431 	if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) {
2432 		/* Suggest IV be random number plus some number, */
2433 		NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16],
2434 			       LEN_KEY_DESC_IV);
2435 		pMsg->KeyDesc.KeyIv[15] += 2;
2436 	}
2437 	/* Fill Key RSC field */
2438 	/* It contains the RSC for the GTK being installed. */
2439 	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
2440 	    || (MsgType == EAPOL_GROUP_MSG_1)) {
2441 		NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
2442 	}
2443 	/* Clear Key MIC field for MIC calculation later */
2444 	NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
2445 
2446 	ConstructEapolKeyData(pEntry,
2447 			      GroupKeyWepStatus,
2448 			      KeyDescVer,
2449 			      MsgType,
2450 			      DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);
2451 
2452 	/* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */
2453 	if (MsgType != EAPOL_PAIR_MSG_1) {
2454 		CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
2455 	}
2456 
2457 	DBGPRINT(RT_DEBUG_TRACE,
2458 		 ("===> ConstructEapolMsg for %s %s\n",
2459 		  ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
2460 	DBGPRINT(RT_DEBUG_TRACE,
2461 		 ("	     Body length = %d \n",
2462 		  CONV_ARRARY_TO_u16(pMsg->Body_Len)));
2463 	DBGPRINT(RT_DEBUG_TRACE,
2464 		 ("	     Key length  = %d \n",
2465 		  CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength)));
2466 
2467 }
2468 
2469 /*
2470 	========================================================================
2471 
2472 	Routine Description:
2473 		Construct the Key Data field of EAPoL message
2474 
2475 	Arguments:
2476 		pAd			Pointer	to our adapter
2477 		Elem		Message body
2478 
2479 	Return Value:
2480 		None
2481 
2482 	Note:
2483 
2484 	========================================================================
2485 */
ConstructEapolKeyData(struct rt_mac_table_entry * pEntry,u8 GroupKeyWepStatus,u8 keyDescVer,u8 MsgType,u8 DefaultKeyIdx,u8 * GTK,u8 * RSNIE,u8 RSNIE_LEN,struct rt_eapol_packet * pMsg)2486 void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
2487 			   u8 GroupKeyWepStatus,
2488 			   u8 keyDescVer,
2489 			   u8 MsgType,
2490 			   u8 DefaultKeyIdx,
2491 			   u8 * GTK,
2492 			   u8 * RSNIE,
2493 			   u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
2494 {
2495 	u8 *mpool, *Key_Data, *Rc4GTK;
2496 	u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)];
2497 	unsigned long data_offset;
2498 	BOOLEAN bWPA2Capable = FALSE;
2499 	struct rt_rtmp_adapter *pAd = pEntry->pAd;
2500 	BOOLEAN GTK_Included = FALSE;
2501 
2502 	/* Choose WPA2 or not */
2503 	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2504 	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2505 		bWPA2Capable = TRUE;
2506 
2507 	if (MsgType == EAPOL_PAIR_MSG_1 ||
2508 	    MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
2509 		return;
2510 
2511 	/* allocate memory pool */
2512 	os_alloc_mem(NULL, (u8 **) & mpool, 1500);
2513 
2514 	if (mpool == NULL)
2515 		return;
2516 
2517 	/* Rc4GTK Len = 512 */
2518 	Rc4GTK = (u8 *) ROUND_UP(mpool, 4);
2519 	/* Key_Data Len = 512 */
2520 	Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4);
2521 
2522 	NdisZeroMemory(Key_Data, 512);
2523 	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
2524 	data_offset = 0;
2525 
2526 	/* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
2527 	if (RSNIE_LEN
2528 	    && ((MsgType == EAPOL_PAIR_MSG_2)
2529 		|| (MsgType == EAPOL_PAIR_MSG_3))) {
2530 		u8 *pmkid_ptr = NULL;
2531 		u8 pmkid_len = 0;
2532 
2533 		RTMPInsertRSNIE(&Key_Data[data_offset],
2534 				&data_offset,
2535 				RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
2536 	}
2537 
2538 	/* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
2539 	if (bWPA2Capable
2540 	    && ((MsgType == EAPOL_PAIR_MSG_3)
2541 		|| (MsgType == EAPOL_GROUP_MSG_1))) {
2542 		/* Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h */
2543 		Key_Data[data_offset + 0] = 0xDD;
2544 
2545 		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2546 			Key_Data[data_offset + 1] = 0x16;	/* 4+2+16(OUI+DataType+DataField) */
2547 		} else {
2548 			Key_Data[data_offset + 1] = 0x26;	/* 4+2+32(OUI+DataType+DataField) */
2549 		}
2550 
2551 		Key_Data[data_offset + 2] = 0x00;
2552 		Key_Data[data_offset + 3] = 0x0F;
2553 		Key_Data[data_offset + 4] = 0xAC;
2554 		Key_Data[data_offset + 5] = 0x01;
2555 
2556 		/* GTK KDE format - 802.11i-2004  Figure-43x */
2557 		Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
2558 		Key_Data[data_offset + 7] = 0x00;	/* Reserved Byte */
2559 
2560 		data_offset += 8;
2561 	}
2562 
2563 	/* Encapsulate GTK */
2564 	/* Only for pairwise_msg3_WPA2 and group_msg1 */
2565 	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
2566 	    || (MsgType == EAPOL_GROUP_MSG_1)) {
2567 		/* Fill in GTK */
2568 		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2569 			NdisMoveMemory(&Key_Data[data_offset], GTK,
2570 				       LEN_AES_KEY);
2571 			data_offset += LEN_AES_KEY;
2572 		} else {
2573 			NdisMoveMemory(&Key_Data[data_offset], GTK,
2574 				       TKIP_GTK_LENGTH);
2575 			data_offset += TKIP_GTK_LENGTH;
2576 		}
2577 
2578 		GTK_Included = TRUE;
2579 	}
2580 
2581 	/* This whole key-data field shall be encrypted if a GTK is included. */
2582 	/* Encrypt the data material in key data field with KEK */
2583 	if (GTK_Included) {
2584 		/*hex_dump("GTK_Included", Key_Data, data_offset); */
2585 
2586 		if ((keyDescVer == DESC_TYPE_AES)) {
2587 			u8 remainder = 0;
2588 			u8 pad_len = 0;
2589 
2590 			/* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */
2591 			/* shall be used to encrypt the Key Data field using the KEK field from */
2592 			/* the derived PTK. */
2593 
2594 			/* If the Key Data field uses the NIST AES key wrap, then the Key Data field */
2595 			/* shall be padded before encrypting if the key data length is less than 16 */
2596 			/* octets or if it is not a multiple of 8. The padding consists of appending */
2597 			/* a single octet 0xdd followed by zero or more 0x00 octets. */
2598 			if ((remainder = data_offset & 0x07) != 0) {
2599 				int i;
2600 
2601 				pad_len = (8 - remainder);
2602 				Key_Data[data_offset] = 0xDD;
2603 				for (i = 1; i < pad_len; i++)
2604 					Key_Data[data_offset + i] = 0;
2605 
2606 				data_offset += pad_len;
2607 			}
2608 
2609 			AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
2610 					 data_offset, Rc4GTK);
2611 			/* AES wrap function will grow 8 bytes in length */
2612 			data_offset += 8;
2613 		} else {
2614 			/*      Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
2615 			   using the KEK field from the derived PTK. */
2616 
2617 			/* PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */
2618 			/* put TxTsc in Key RSC field */
2619 			pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;	/*Init crc32. */
2620 
2621 			/* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
2622 			NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
2623 				       LEN_KEY_DESC_IV);
2624 			NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
2625 				       LEN_EAP_EK);
2626 			ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));	/*INIT SBOX, KEYLEN+3(IV) */
2627 			pAd->PrivateInfo.FCSCRC32 =
2628 			    RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data,
2629 					    data_offset);
2630 			WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
2631 					   Key_Data, data_offset);
2632 		}
2633 
2634 		NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
2635 	} else {
2636 		NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
2637 	}
2638 
2639 	/* Update key data length field and total body length */
2640 	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
2641 	INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset);
2642 
2643 	os_free_mem(NULL, mpool);
2644 
2645 }
2646 
2647 /*
2648 	========================================================================
2649 
2650 	Routine Description:
2651 		Calcaulate MIC. It is used during 4-ways handsharking.
2652 
2653 	Arguments:
2654 		pAd			-	pointer to our pAdapter context
2655 	PeerWepStatus	-	indicate the encryption type
2656 
2657 	Return Value:
2658 
2659 	Note:
2660 
2661 	========================================================================
2662 */
CalculateMIC(u8 KeyDescVer,u8 * PTK,struct rt_eapol_packet * pMsg)2663 static void CalculateMIC(u8 KeyDescVer,
2664 			 u8 * PTK, struct rt_eapol_packet * pMsg)
2665 {
2666 	u8 *OutBuffer;
2667 	unsigned long FrameLen = 0;
2668 	u8 mic[LEN_KEY_DESC_MIC];
2669 	u8 digest[80];
2670 
2671 	/* allocate memory for MIC calculation */
2672 	os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);
2673 
2674 	if (OutBuffer == NULL) {
2675 		DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
2676 		return;
2677 	}
2678 	/* make a frame for calculating MIC. */
2679 	MakeOutgoingFrame(OutBuffer, &FrameLen,
2680 			  CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
2681 			  END_OF_ARGS);
2682 
2683 	NdisZeroMemory(mic, sizeof(mic));
2684 
2685 	/* Calculate MIC */
2686 	if (KeyDescVer == DESC_TYPE_AES) {
2687 		HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
2688 			  SHA1_DIGEST_SIZE);
2689 		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
2690 	} else {
2691 		HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
2692 			 MD5_DIGEST_SIZE);
2693 	}
2694 
2695 	/* store the calculated MIC */
2696 	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
2697 
2698 	os_free_mem(NULL, OutBuffer);
2699 }
2700 
2701 /*
2702 	========================================================================
2703 
2704 	Routine Description:
2705 		Some received frames can't decrypt by Asic, so decrypt them by software.
2706 
2707 	Arguments:
2708 		pAd			-	pointer to our pAdapter context
2709 	PeerWepStatus	-	indicate the encryption type
2710 
2711 	Return Value:
2712 		NDIS_STATUS_SUCCESS		-	decryption successful
2713 		NDIS_STATUS_FAILURE		-	decryption failure
2714 
2715 	========================================================================
2716 */
RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk,IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,struct rt_cipher_key * pShard_key)2717 int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
2718 					 struct rt_rx_blk *pRxBlk,
2719 					 IN NDIS_802_11_ENCRYPTION_STATUS
2720 					 GroupCipher, struct rt_cipher_key *pShard_key)
2721 {
2722 	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
2723 
2724 	/* handle WEP decryption */
2725 	if (GroupCipher == Ndis802_11Encryption1Enabled) {
2726 		if (RTMPSoftDecryptWEP
2727 		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2728 		     pShard_key)) {
2729 
2730 			/*Minus IV[4] & ICV[4] */
2731 			pRxWI->MPDUtotalByteCount -= 8;
2732 		} else {
2733 			DBGPRINT(RT_DEBUG_ERROR,
2734 				 ("ERROR : Software decrypt WEP data fails.\n"));
2735 			/* give up this frame */
2736 			return NDIS_STATUS_FAILURE;
2737 		}
2738 	}
2739 	/* handle TKIP decryption */
2740 	else if (GroupCipher == Ndis802_11Encryption2Enabled) {
2741 		if (RTMPSoftDecryptTKIP
2742 		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
2743 		     pShard_key)) {
2744 
2745 			/*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
2746 			pRxWI->MPDUtotalByteCount -= 20;
2747 		} else {
2748 			DBGPRINT(RT_DEBUG_ERROR,
2749 				 ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
2750 			/* give up this frame */
2751 			return NDIS_STATUS_FAILURE;
2752 		}
2753 	}
2754 	/* handle AES decryption */
2755 	else if (GroupCipher == Ndis802_11Encryption3Enabled) {
2756 		if (RTMPSoftDecryptAES
2757 		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2758 		     pShard_key)) {
2759 
2760 			/*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
2761 			pRxWI->MPDUtotalByteCount -= 16;
2762 		} else {
2763 			DBGPRINT(RT_DEBUG_ERROR,
2764 				 ("ERROR : RTMPSoftDecryptAES Failed\n"));
2765 			/* give up this frame */
2766 			return NDIS_STATUS_FAILURE;
2767 		}
2768 	} else {
2769 		/* give up this frame */
2770 		return NDIS_STATUS_FAILURE;
2771 	}
2772 
2773 	return NDIS_STATUS_SUCCESS;
2774 
2775 }
2776 
GetSuiteFromRSNIE(u8 * rsnie,u32 rsnie_len,u8 type,u8 * count)2777 u8 *GetSuiteFromRSNIE(u8 *rsnie,
2778 			 u32 rsnie_len, u8 type, u8 * count)
2779 {
2780 	struct rt_eid * pEid;
2781 	int len;
2782 	u8 *pBuf;
2783 	int offset = 0;
2784 	struct rt_rsnie_auth *pAkm;
2785 	u16 acount;
2786 	BOOLEAN isWPA2 = FALSE;
2787 
2788 	pEid = (struct rt_eid *) rsnie;
2789 	len = rsnie_len - 2;	/* exclude IE and length */
2790 	pBuf = (u8 *)& pEid->Octet[0];
2791 
2792 	/* set default value */
2793 	*count = 0;
2794 
2795 	/* Check length */
2796 	if ((len <= 0) || (pEid->Len != len)) {
2797 		DBGPRINT_ERR("%s : The length is invalid\n", __func__);
2798 		return NULL;
2799 	}
2800 	/* Check WPA or WPA2 */
2801 	if (pEid->Eid == IE_WPA) {
2802 		struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
2803 		u16 ucount;
2804 
2805 		if (len < sizeof(struct rt_rsnie)) {
2806 			DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__);
2807 			return NULL;
2808 		}
2809 		/* Get the count of pairwise cipher */
2810 		ucount = cpu2le16(pRsnie->ucount);
2811 		if (ucount > 2) {
2812 			DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2813 			return NULL;
2814 		}
2815 		/* Get the group cipher */
2816 		if (type == GROUP_SUITE) {
2817 			*count = 1;
2818 			return pRsnie->mcast;
2819 		}
2820 		/* Get the pairwise cipher suite */
2821 		else if (type == PAIRWISE_SUITE) {
2822 			DBGPRINT(RT_DEBUG_TRACE,
2823 				 ("%s : The count of pairwise cipher is %d\n",
2824 				  __func__, ucount));
2825 			*count = ucount;
2826 			return pRsnie->ucast[0].oui;
2827 		}
2828 
2829 		offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));
2830 
2831 	} else if (pEid->Eid == IE_RSN) {
2832 		struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
2833 		u16 ucount;
2834 
2835 		isWPA2 = TRUE;
2836 
2837 		if (len < sizeof(struct rt_rsnie2)) {
2838 			DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__);
2839 			return NULL;
2840 		}
2841 		/* Get the count of pairwise cipher */
2842 		ucount = cpu2le16(pRsnie->ucount);
2843 		if (ucount > 2) {
2844 			DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2845 			return NULL;
2846 		}
2847 		/* Get the group cipher */
2848 		if (type == GROUP_SUITE) {
2849 			*count = 1;
2850 			return pRsnie->mcast;
2851 		}
2852 		/* Get the pairwise cipher suite */
2853 		else if (type == PAIRWISE_SUITE) {
2854 			DBGPRINT(RT_DEBUG_TRACE,
2855 				 ("%s : The count of pairwise cipher is %d\n",
2856 				  __func__, ucount));
2857 			*count = ucount;
2858 			return pRsnie->ucast[0].oui;
2859 		}
2860 
2861 		offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));
2862 
2863 	} else {
2864 		DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid);
2865 		return NULL;
2866 	}
2867 
2868 	/* skip group cipher and pairwise cipher suite */
2869 	pBuf += offset;
2870 	len -= offset;
2871 
2872 	if (len < sizeof(struct rt_rsnie_auth)) {
2873 		DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__);
2874 		return NULL;
2875 	}
2876 	/* pointer to AKM count */
2877 	pAkm = (struct rt_rsnie_auth *)pBuf;
2878 
2879 	/* Get the count of pairwise cipher */
2880 	acount = cpu2le16(pAkm->acount);
2881 	if (acount > 2) {
2882 		DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount);
2883 		return NULL;
2884 	}
2885 	/* Get the AKM suite */
2886 	if (type == AKM_SUITE) {
2887 		DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
2888 					  __func__, acount));
2889 		*count = acount;
2890 		return pAkm->auth[0].oui;
2891 	}
2892 	offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));
2893 
2894 	pBuf += offset;
2895 	len -= offset;
2896 
2897 	/* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */
2898 	if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) {
2899 		/* Skip RSN capability and PMKID-Count */
2900 		pBuf += (sizeof(RSN_CAPABILITIES) + 2);
2901 		len -= (sizeof(RSN_CAPABILITIES) + 2);
2902 
2903 		/* Get PMKID */
2904 		if (type == PMKID_LIST) {
2905 			*count = 1;
2906 			return pBuf;
2907 		}
2908 	} else {
2909 		DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__);
2910 		return NULL;
2911 	}
2912 
2913 	*count = 0;
2914 	/*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
2915 	return NULL;
2916 
2917 }
2918 
WpaShowAllsuite(u8 * rsnie,u32 rsnie_len)2919 void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
2920 {
2921 	u8 *pSuite = NULL;
2922 	u8 count;
2923 
2924 	hex_dump("RSNIE", rsnie, rsnie_len);
2925 
2926 	/* group cipher */
2927 	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count);
2928 	if (pSuite != NULL) {
2929 		hex_dump("group cipher", pSuite, 4 * count);
2930 	}
2931 	/* pairwise cipher */
2932 	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count);
2933 	if (pSuite != NULL) {
2934 		hex_dump("pairwise cipher", pSuite, 4 * count);
2935 	}
2936 	/* AKM */
2937 	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count);
2938 	if (pSuite != NULL) {
2939 		hex_dump("AKM suite", pSuite, 4 * count);
2940 	}
2941 	/* PMKID */
2942 	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count);
2943 	if (pSuite != NULL) {
2944 		hex_dump("PMKID", pSuite, LEN_PMKID);
2945 	}
2946 
2947 }
2948 
RTMPInsertRSNIE(u8 * pFrameBuf,unsigned long * pFrameLen,u8 * rsnie_ptr,u8 rsnie_len,u8 * pmkid_ptr,u8 pmkid_len)2949 void RTMPInsertRSNIE(u8 *pFrameBuf,
2950 		     unsigned long *pFrameLen,
2951 		     u8 *rsnie_ptr,
2952 		     u8 rsnie_len,
2953 		     u8 *pmkid_ptr, u8 pmkid_len)
2954 {
2955 	u8 *pTmpBuf;
2956 	unsigned long TempLen = 0;
2957 	u8 extra_len = 0;
2958 	u16 pmk_count = 0;
2959 	u8 ie_num;
2960 	u8 total_len = 0;
2961 	u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
2962 
2963 	pTmpBuf = pFrameBuf;
2964 
2965 	/* PMKID-List Must larger than 0 and the multiple of 16. */
2966 	if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) {
2967 		extra_len = sizeof(u16)+ pmkid_len;
2968 
2969 		pmk_count = (pmkid_len >> 4);
2970 		pmk_count = cpu2le16(pmk_count);
2971 	} else {
2972 		DBGPRINT(RT_DEBUG_WARN,
2973 			 ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
2974 			  __func__, pmkid_len));
2975 	}
2976 
2977 	if (rsnie_len != 0) {
2978 		ie_num = IE_WPA;
2979 		total_len = rsnie_len;
2980 
2981 		if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
2982 			ie_num = IE_RSN;
2983 			total_len += extra_len;
2984 		}
2985 
2986 		/* construct RSNIE body */
2987 		MakeOutgoingFrame(pTmpBuf, &TempLen,
2988 				  1, &ie_num,
2989 				  1, &total_len,
2990 				  rsnie_len, rsnie_ptr, END_OF_ARGS);
2991 
2992 		pTmpBuf += TempLen;
2993 		*pFrameLen = *pFrameLen + TempLen;
2994 
2995 		if (ie_num == IE_RSN) {
2996 			/* Insert PMKID-List field */
2997 			if (extra_len > 0) {
2998 				MakeOutgoingFrame(pTmpBuf, &TempLen,
2999 						  2, &pmk_count,
3000 						  pmkid_len, pmkid_ptr,
3001 						  END_OF_ARGS);
3002 
3003 				pTmpBuf += TempLen;
3004 				*pFrameLen = *pFrameLen + TempLen;
3005 			}
3006 		}
3007 	}
3008 
3009 	return;
3010 }
3011