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 	auth.c
29 
30 	Abstract:
31 
32 	Revision History:
33 	Who			When			What
34 	--------	----------		----------------------------------------------
35 	John			2004-9-3		porting from RT2500
36 	Justin P. Mattock	11/07/2010		Fix typos
37 */
38 #include "../rt_config.h"
39 
40 /*
41     ==========================================================================
42     Description:
43         authenticate state machine init, including state transition and timer init
44     Parameters:
45         Sm - pointer to the auth state machine
46     Note:
47         The state machine looks like this
48 
49                         AUTH_REQ_IDLE           AUTH_WAIT_SEQ2                   AUTH_WAIT_SEQ4
50     MT2_MLME_AUTH_REQ   mlme_auth_req_action    invalid_state_when_auth          invalid_state_when_auth
51     MT2_PEER_AUTH_EVEN  drop                    peer_auth_even_at_seq2_action    peer_auth_even_at_seq4_action
52     MT2_AUTH_TIMEOUT    Drop                    auth_timeout_action              auth_timeout_action
53 
54 	IRQL = PASSIVE_LEVEL
55 
56     ==========================================================================
57  */
58 
AuthStateMachineInit(struct rt_rtmp_adapter * pAd,struct rt_state_machine * Sm,OUT STATE_MACHINE_FUNC Trans[])59 void AuthStateMachineInit(struct rt_rtmp_adapter *pAd,
60 			  struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
61 {
62 	StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG,
63 			 (STATE_MACHINE_FUNC) Drop, AUTH_REQ_IDLE,
64 			 AUTH_MACHINE_BASE);
65 
66 	/* the first column */
67 	StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ,
68 			      (STATE_MACHINE_FUNC) MlmeAuthReqAction);
69 
70 	/* the second column */
71 	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ,
72 			      (STATE_MACHINE_FUNC) InvalidStateWhenAuth);
73 	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN,
74 			      (STATE_MACHINE_FUNC) PeerAuthRspAtSeq2Action);
75 	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT,
76 			      (STATE_MACHINE_FUNC) AuthTimeoutAction);
77 
78 	/* the third column */
79 	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ,
80 			      (STATE_MACHINE_FUNC) InvalidStateWhenAuth);
81 	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN,
82 			      (STATE_MACHINE_FUNC) PeerAuthRspAtSeq4Action);
83 	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT,
84 			      (STATE_MACHINE_FUNC) AuthTimeoutAction);
85 
86 	RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer,
87 		      GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
88 }
89 
90 /*
91     ==========================================================================
92     Description:
93         function to be executed at timer thread when auth timer expires
94 
95 	IRQL = DISPATCH_LEVEL
96 
97     ==========================================================================
98  */
AuthTimeout(void * SystemSpecific1,void * FunctionContext,void * SystemSpecific2,void * SystemSpecific3)99 void AuthTimeout(void *SystemSpecific1,
100 		 void *FunctionContext,
101 		 void *SystemSpecific2, void *SystemSpecific3)
102 {
103 	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
104 
105 	DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeout\n"));
106 
107 	/* Do nothing if the driver is starting halt state. */
108 	/* This might happen when timer already been fired before cancel timer with mlmehalt */
109 	if (RTMP_TEST_FLAG
110 	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
111 		return;
112 
113 	/* send a de-auth to reset AP's state machine (Patch AP-Dir635) */
114 	if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
115 		Cls2errAction(pAd, pAd->MlmeAux.Bssid);
116 
117 	MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
118 	RTMP_MLME_HANDLER(pAd);
119 }
120 
121 /*
122     ==========================================================================
123     Description:
124 
125 	IRQL = DISPATCH_LEVEL
126 
127     ==========================================================================
128  */
MlmeAuthReqAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)129 void MlmeAuthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
130 {
131 	if (AUTH_ReqSend
132 	    (pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0))
133 		pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
134 	else {
135 		u16 Status;
136 
137 		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
138 		Status = MLME_INVALID_FORMAT;
139 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2,
140 			    &Status);
141 	}
142 }
143 
144 /*
145     ==========================================================================
146     Description:
147 
148 	IRQL = DISPATCH_LEVEL
149 
150     ==========================================================================
151  */
PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)152 void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
153 {
154 	u8 Addr2[MAC_ADDR_LEN];
155 	u16 Seq, Status, RemoteStatus, Alg;
156 	u8 ChlgText[CIPHER_TEXT_LEN];
157 	u8 CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
158 	u8 Element[2];
159 	struct rt_header_802_11 AuthHdr;
160 	BOOLEAN TimerCancelled;
161 	u8 *pOutBuffer = NULL;
162 	int NStatus;
163 	unsigned long FrameLen = 0;
164 	u16 Status2;
165 
166 	if (PeerAuthSanity
167 	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status,
168 	     (char *)ChlgText)) {
169 		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2) {
170 			DBGPRINT(RT_DEBUG_TRACE,
171 				 ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n",
172 				  Alg, Status));
173 			RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,
174 					&TimerCancelled);
175 
176 			if (Status == MLME_SUCCESS) {
177 				/* Authentication Mode "LEAP" has allow for CCX 1.X */
178 				if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) {
179 					pAd->Mlme.AuthMachine.CurrState =
180 					    AUTH_REQ_IDLE;
181 					MlmeEnqueue(pAd,
182 						    MLME_CNTL_STATE_MACHINE,
183 						    MT2_AUTH_CONF, 2, &Status);
184 				} else {
185 					/* 2. shared key, need to be challenged */
186 					Seq++;
187 					RemoteStatus = MLME_SUCCESS;
188 
189 					/* Get an unused nonpaged memory */
190 					NStatus =
191 					    MlmeAllocateMemory(pAd,
192 							       &pOutBuffer);
193 					if (NStatus != NDIS_STATUS_SUCCESS) {
194 						DBGPRINT(RT_DEBUG_TRACE,
195 							 ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
196 						pAd->Mlme.AuthMachine.
197 						    CurrState = AUTH_REQ_IDLE;
198 						Status2 = MLME_FAIL_NO_RESOURCE;
199 						MlmeEnqueue(pAd,
200 							    MLME_CNTL_STATE_MACHINE,
201 							    MT2_AUTH_CONF, 2,
202 							    &Status2);
203 						return;
204 					}
205 
206 					DBGPRINT(RT_DEBUG_TRACE,
207 						 ("AUTH - Send AUTH request seq#3...\n"));
208 					MgtMacHeaderInit(pAd, &AuthHdr,
209 							 SUBTYPE_AUTH, 0, Addr2,
210 							 pAd->MlmeAux.Bssid);
211 					AuthHdr.FC.Wep = 1;
212 					/* Encrypt challenge text & auth information */
213 					RTMPInitWepEngine(pAd,
214 							  pAd->
215 							  SharedKey[BSS0][pAd->
216 									  StaCfg.
217 									  DefaultKeyId].
218 							  Key,
219 							  pAd->StaCfg.
220 							  DefaultKeyId,
221 							  pAd->
222 							  SharedKey[BSS0][pAd->
223 									  StaCfg.
224 									  DefaultKeyId].
225 							  KeyLen,
226 							  CyperChlgText);
227 
228 					Alg = cpu2le16(*(u16 *) & Alg);
229 					Seq = cpu2le16(*(u16 *) & Seq);
230 					RemoteStatus =
231 					    cpu2le16(*(u16 *) &
232 						     RemoteStatus);
233 
234 					RTMPEncryptData(pAd, (u8 *)& Alg,
235 							CyperChlgText + 4, 2);
236 					RTMPEncryptData(pAd, (u8 *)& Seq,
237 							CyperChlgText + 6, 2);
238 					RTMPEncryptData(pAd,
239 							(u8 *)& RemoteStatus,
240 							CyperChlgText + 8, 2);
241 					Element[0] = 16;
242 					Element[1] = 128;
243 					RTMPEncryptData(pAd, Element,
244 							CyperChlgText + 10, 2);
245 					RTMPEncryptData(pAd, ChlgText,
246 							CyperChlgText + 12,
247 							128);
248 					RTMPSetICV(pAd, CyperChlgText + 140);
249 					MakeOutgoingFrame(pOutBuffer, &FrameLen,
250 							  sizeof(struct rt_header_802_11),
251 							  &AuthHdr,
252 							  CIPHER_TEXT_LEN + 16,
253 							  CyperChlgText,
254 							  END_OF_ARGS);
255 					MiniportMMRequest(pAd, 0, pOutBuffer,
256 							  FrameLen);
257 					MlmeFreeMemory(pAd, pOutBuffer);
258 
259 					RTMPSetTimer(&pAd->MlmeAux.AuthTimer,
260 						     AUTH_TIMEOUT);
261 					pAd->Mlme.AuthMachine.CurrState =
262 					    AUTH_WAIT_SEQ4;
263 				}
264 			} else {
265 				pAd->StaCfg.AuthFailReason = Status;
266 				COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
267 				pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
268 				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
269 					    MT2_AUTH_CONF, 2, &Status);
270 			}
271 		}
272 	} else {
273 		DBGPRINT(RT_DEBUG_TRACE,
274 			 ("AUTH - PeerAuthSanity() sanity check fail\n"));
275 	}
276 }
277 
278 /*
279     ==========================================================================
280     Description:
281 
282 	IRQL = DISPATCH_LEVEL
283 
284     ==========================================================================
285  */
PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)286 void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
287 {
288 	u8 Addr2[MAC_ADDR_LEN];
289 	u16 Alg, Seq, Status;
290 	char ChlgText[CIPHER_TEXT_LEN];
291 	BOOLEAN TimerCancelled;
292 
293 	if (PeerAuthSanity
294 	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status,
295 	     ChlgText)) {
296 		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4) {
297 			DBGPRINT(RT_DEBUG_TRACE,
298 				 ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
299 			RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,
300 					&TimerCancelled);
301 
302 			if (Status != MLME_SUCCESS) {
303 				pAd->StaCfg.AuthFailReason = Status;
304 				COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
305 			}
306 
307 			pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
308 			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF,
309 				    2, &Status);
310 		}
311 	} else {
312 		DBGPRINT(RT_DEBUG_TRACE,
313 			 ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
314 	}
315 }
316 
317 /*
318     ==========================================================================
319     Description:
320 
321 	IRQL = DISPATCH_LEVEL
322 
323     ==========================================================================
324  */
MlmeDeauthReqAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)325 void MlmeDeauthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
326 {
327 	struct rt_mlme_deauth_req *pInfo;
328 	struct rt_header_802_11 DeauthHdr;
329 	u8 *pOutBuffer = NULL;
330 	int NStatus;
331 	unsigned long FrameLen = 0;
332 	u16 Status;
333 
334 	pInfo = (struct rt_mlme_deauth_req *)Elem->Msg;
335 
336 	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
337 	if (NStatus != NDIS_STATUS_SUCCESS) {
338 		DBGPRINT(RT_DEBUG_TRACE,
339 			 ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
340 		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
341 		Status = MLME_FAIL_NO_RESOURCE;
342 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2,
343 			    &Status);
344 		return;
345 	}
346 
347 	DBGPRINT(RT_DEBUG_TRACE,
348 		 ("AUTH - Send DE-AUTH request (Reason=%d)...\n",
349 		  pInfo->Reason));
350 	MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr,
351 			 pAd->MlmeAux.Bssid);
352 	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
353 			  &DeauthHdr, 2, &pInfo->Reason, END_OF_ARGS);
354 	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
355 	MlmeFreeMemory(pAd, pOutBuffer);
356 
357 	pAd->StaCfg.DeauthReason = pInfo->Reason;
358 	COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
359 	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
360 	Status = MLME_SUCCESS;
361 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
362 
363 	/* send wireless event - for deauthentication */
364 	if (pAd->CommonCfg.bWirelessEvent)
365 		RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG,
366 				      pAd->MacTab.Content[BSSID_WCID].Addr,
367 				      BSS0, 0);
368 }
369 
370 /*
371     ==========================================================================
372     Description:
373 
374 	IRQL = DISPATCH_LEVEL
375 
376     ==========================================================================
377  */
AuthTimeoutAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)378 void AuthTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
379 {
380 	u16 Status;
381 	DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
382 	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
383 	Status = MLME_REJ_TIMEOUT;
384 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
385 }
386 
387 /*
388     ==========================================================================
389     Description:
390 
391 	IRQL = DISPATCH_LEVEL
392 
393     ==========================================================================
394  */
InvalidStateWhenAuth(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)395 void InvalidStateWhenAuth(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
396 {
397 	u16 Status;
398 	DBGPRINT(RT_DEBUG_TRACE,
399 		 ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n",
400 		  pAd->Mlme.AuthMachine.CurrState));
401 	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
402 	Status = MLME_STATE_MACHINE_REJECT;
403 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
404 }
405 
406 /*
407     ==========================================================================
408     Description:
409         Some STA/AP
410     Note:
411         This action should never trigger AUTH state transition, therefore we
412         separate it from AUTH state machine, and make it as a standalone service
413 
414 	IRQL = DISPATCH_LEVEL
415 
416     ==========================================================================
417  */
Cls2errAction(struct rt_rtmp_adapter * pAd,u8 * pAddr)418 void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr)
419 {
420 	struct rt_header_802_11 DeauthHdr;
421 	u8 *pOutBuffer = NULL;
422 	int NStatus;
423 	unsigned long FrameLen = 0;
424 	u16 Reason = REASON_CLS2ERR;
425 
426 	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
427 	if (NStatus != NDIS_STATUS_SUCCESS)
428 		return;
429 
430 	DBGPRINT(RT_DEBUG_TRACE,
431 		 ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
432 	MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr,
433 			 pAd->MlmeAux.Bssid);
434 	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
435 			  &DeauthHdr, 2, &Reason, END_OF_ARGS);
436 	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
437 	MlmeFreeMemory(pAd, pOutBuffer);
438 
439 	pAd->StaCfg.DeauthReason = Reason;
440 	COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
441 }
442 
AUTH_ReqSend(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * pElem,struct rt_ralink_timer * pAuthTimer,char * pSMName,u16 SeqNo,u8 * pNewElement,unsigned long ElementLen)443 BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd,
444 		     struct rt_mlme_queue_elem *pElem,
445 		     struct rt_ralink_timer *pAuthTimer,
446 		     char *pSMName,
447 		     u16 SeqNo,
448 		     u8 *pNewElement, unsigned long ElementLen)
449 {
450 	u16 Alg, Seq, Status;
451 	u8 Addr[6];
452 	unsigned long Timeout;
453 	struct rt_header_802_11 AuthHdr;
454 	BOOLEAN TimerCancelled;
455 	int NStatus;
456 	u8 *pOutBuffer = NULL;
457 	unsigned long FrameLen = 0, tmp = 0;
458 
459 	/* Block all authentication request during WPA block period */
460 	if (pAd->StaCfg.bBlockAssoc == TRUE) {
461 		DBGPRINT(RT_DEBUG_TRACE,
462 			 ("%s - Block Auth request during WPA block period!\n",
463 			  pSMName));
464 		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
465 		Status = MLME_STATE_MACHINE_REJECT;
466 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2,
467 			    &Status);
468 	} else
469 	    if (MlmeAuthReqSanity
470 		(pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg)) {
471 		/* reset timer */
472 		RTMPCancelTimer(pAuthTimer, &TimerCancelled);
473 
474 		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
475 		pAd->MlmeAux.Alg = Alg;
476 		Seq = SeqNo;
477 		Status = MLME_SUCCESS;
478 
479 		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
480 		if (NStatus != NDIS_STATUS_SUCCESS) {
481 			DBGPRINT(RT_DEBUG_TRACE,
482 				 ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n",
483 				  pSMName, Alg));
484 			pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
485 			Status = MLME_FAIL_NO_RESOURCE;
486 			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF,
487 				    2, &Status);
488 			return FALSE;
489 		}
490 
491 		DBGPRINT(RT_DEBUG_TRACE,
492 			 ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName,
493 			  Alg));
494 		MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr,
495 				 pAd->MlmeAux.Bssid);
496 		MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
497 				  &AuthHdr, 2, &Alg, 2, &Seq, 2, &Status,
498 				  END_OF_ARGS);
499 
500 		if (pNewElement && ElementLen) {
501 			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
502 					  ElementLen, pNewElement, END_OF_ARGS);
503 			FrameLen += tmp;
504 		}
505 
506 		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
507 		MlmeFreeMemory(pAd, pOutBuffer);
508 
509 		RTMPSetTimer(pAuthTimer, Timeout);
510 		return TRUE;
511 	} else {
512 		DBGPRINT_ERR("%s - MlmeAuthReqAction() sanity check failed\n", pSMName);
513 		return FALSE;
514 	}
515 
516 	return TRUE;
517 }
518