2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John 2004-9-3 porting from RT2500
36 Justin P. Mattock 11/07/2010 Fix typos
38 #include "../rt_config.h"
41 ==========================================================================
43 authenticate state machine init, including state transition and timer init
45 Sm - pointer to the auth state machine
47 The state machine looks like this
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
56 ==========================================================================
59 void AuthStateMachineInit(struct rt_rtmp_adapter
*pAd
,
60 struct rt_state_machine
*Sm
, OUT STATE_MACHINE_FUNC Trans
[])
62 StateMachineInit(Sm
, Trans
, MAX_AUTH_STATE
, MAX_AUTH_MSG
,
63 (STATE_MACHINE_FUNC
) Drop
, AUTH_REQ_IDLE
,
66 /* the first column */
67 StateMachineSetAction(Sm
, AUTH_REQ_IDLE
, MT2_MLME_AUTH_REQ
,
68 (STATE_MACHINE_FUNC
) MlmeAuthReqAction
);
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
);
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
);
86 RTMPInitTimer(pAd
, &pAd
->MlmeAux
.AuthTimer
,
87 GET_TIMER_FUNCTION(AuthTimeout
), pAd
, FALSE
);
91 ==========================================================================
93 function to be executed at timer thread when auth timer expires
97 ==========================================================================
99 void AuthTimeout(void *SystemSpecific1
,
100 void *FunctionContext
,
101 void *SystemSpecific2
, void *SystemSpecific3
)
103 struct rt_rtmp_adapter
*pAd
= (struct rt_rtmp_adapter
*)FunctionContext
;
105 DBGPRINT(RT_DEBUG_TRACE
, ("AUTH - AuthTimeout\n"));
107 /* Do nothing if the driver is starting halt state. */
108 /* This might happen when timer already been fired before cancel timer with mlmehalt */
110 (pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
))
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
);
117 MlmeEnqueue(pAd
, AUTH_STATE_MACHINE
, MT2_AUTH_TIMEOUT
, 0, NULL
);
118 RTMP_MLME_HANDLER(pAd
);
122 ==========================================================================
125 IRQL = DISPATCH_LEVEL
127 ==========================================================================
129 void MlmeAuthReqAction(struct rt_rtmp_adapter
*pAd
, struct rt_mlme_queue_elem
*Elem
)
132 (pAd
, Elem
, &pAd
->MlmeAux
.AuthTimer
, "AUTH", 1, NULL
, 0))
133 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_WAIT_SEQ2
;
137 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
138 Status
= MLME_INVALID_FORMAT
;
139 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_AUTH_CONF
, 2,
145 ==========================================================================
148 IRQL = DISPATCH_LEVEL
150 ==========================================================================
152 void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter
*pAd
, struct rt_mlme_queue_elem
*Elem
)
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];
159 struct rt_header_802_11 AuthHdr
;
160 BOOLEAN TimerCancelled
;
161 u8
*pOutBuffer
= NULL
;
163 unsigned long FrameLen
= 0;
167 (pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr2
, &Alg
, &Seq
, &Status
,
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",
173 RTMPCancelTimer(&pAd
->MlmeAux
.AuthTimer
,
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
=
182 MLME_CNTL_STATE_MACHINE
,
183 MT2_AUTH_CONF
, 2, &Status
);
185 /* 2. shared key, need to be challenged */
187 RemoteStatus
= MLME_SUCCESS
;
189 /* Get an unused nonpaged memory */
191 MlmeAllocateMemory(pAd
,
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
;
200 MLME_CNTL_STATE_MACHINE
,
206 DBGPRINT(RT_DEBUG_TRACE
,
207 ("AUTH - Send AUTH request seq#3...\n"));
208 MgtMacHeaderInit(pAd
, &AuthHdr
,
209 SUBTYPE_AUTH
, 0, Addr2
,
212 /* Encrypt challenge text & auth information */
213 RTMPInitWepEngine(pAd
,
215 SharedKey
[BSS0
][pAd
->
222 SharedKey
[BSS0
][pAd
->
228 Alg
= cpu2le16(*(u16
*) & Alg
);
229 Seq
= cpu2le16(*(u16
*) & Seq
);
234 RTMPEncryptData(pAd
, (u8
*)& Alg
,
235 CyperChlgText
+ 4, 2);
236 RTMPEncryptData(pAd
, (u8
*)& Seq
,
237 CyperChlgText
+ 6, 2);
239 (u8
*)& RemoteStatus
,
240 CyperChlgText
+ 8, 2);
243 RTMPEncryptData(pAd
, Element
,
244 CyperChlgText
+ 10, 2);
245 RTMPEncryptData(pAd
, ChlgText
,
248 RTMPSetICV(pAd
, CyperChlgText
+ 140);
249 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
250 sizeof(struct rt_header_802_11
),
252 CIPHER_TEXT_LEN
+ 16,
255 MiniportMMRequest(pAd
, 0, pOutBuffer
,
257 MlmeFreeMemory(pAd
, pOutBuffer
);
259 RTMPSetTimer(&pAd
->MlmeAux
.AuthTimer
,
261 pAd
->Mlme
.AuthMachine
.CurrState
=
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
);
273 DBGPRINT(RT_DEBUG_TRACE
,
274 ("AUTH - PeerAuthSanity() sanity check fail\n"));
279 ==========================================================================
282 IRQL = DISPATCH_LEVEL
284 ==========================================================================
286 void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter
*pAd
, struct rt_mlme_queue_elem
*Elem
)
288 u8 Addr2
[MAC_ADDR_LEN
];
289 u16 Alg
, Seq
, Status
;
290 char ChlgText
[CIPHER_TEXT_LEN
];
291 BOOLEAN TimerCancelled
;
294 (pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr2
, &Alg
, &Seq
, &Status
,
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
,
302 if (Status
!= MLME_SUCCESS
) {
303 pAd
->StaCfg
.AuthFailReason
= Status
;
304 COPY_MAC_ADDR(pAd
->StaCfg
.AuthFailSta
, Addr2
);
307 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
308 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_AUTH_CONF
,
312 DBGPRINT(RT_DEBUG_TRACE
,
313 ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
318 ==========================================================================
321 IRQL = DISPATCH_LEVEL
323 ==========================================================================
325 void MlmeDeauthReqAction(struct rt_rtmp_adapter
*pAd
, struct rt_mlme_queue_elem
*Elem
)
327 struct rt_mlme_deauth_req
*pInfo
;
328 struct rt_header_802_11 DeauthHdr
;
329 u8
*pOutBuffer
= NULL
;
331 unsigned long FrameLen
= 0;
334 pInfo
= (struct rt_mlme_deauth_req
*)Elem
->Msg
;
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,
347 DBGPRINT(RT_DEBUG_TRACE
,
348 ("AUTH - Send DE-AUTH request (Reason=%d)...\n",
350 MgtMacHeaderInit(pAd
, &DeauthHdr
, SUBTYPE_DEAUTH
, 0, pInfo
->Addr
,
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
);
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
);
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
,
371 ==========================================================================
374 IRQL = DISPATCH_LEVEL
376 ==========================================================================
378 void AuthTimeoutAction(struct rt_rtmp_adapter
*pAd
, struct rt_mlme_queue_elem
*Elem
)
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
);
388 ==========================================================================
391 IRQL = DISPATCH_LEVEL
393 ==========================================================================
395 void InvalidStateWhenAuth(struct rt_rtmp_adapter
*pAd
, struct rt_mlme_queue_elem
*Elem
)
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
);
407 ==========================================================================
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
414 IRQL = DISPATCH_LEVEL
416 ==========================================================================
418 void Cls2errAction(struct rt_rtmp_adapter
*pAd
, u8
*pAddr
)
420 struct rt_header_802_11 DeauthHdr
;
421 u8
*pOutBuffer
= NULL
;
423 unsigned long FrameLen
= 0;
424 u16 Reason
= REASON_CLS2ERR
;
426 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); /*Get an unused nonpaged memory */
427 if (NStatus
!= NDIS_STATUS_SUCCESS
)
430 DBGPRINT(RT_DEBUG_TRACE
,
431 ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
432 MgtMacHeaderInit(pAd
, &DeauthHdr
, SUBTYPE_DEAUTH
, 0, pAddr
,
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
);
439 pAd
->StaCfg
.DeauthReason
= Reason
;
440 COPY_MAC_ADDR(pAd
->StaCfg
.DeauthSta
, pAddr
);
443 BOOLEAN
AUTH_ReqSend(struct rt_rtmp_adapter
*pAd
,
444 struct rt_mlme_queue_elem
*pElem
,
445 struct rt_ralink_timer
*pAuthTimer
,
448 u8
*pNewElement
, unsigned long ElementLen
)
450 u16 Alg
, Seq
, Status
;
452 unsigned long Timeout
;
453 struct rt_header_802_11 AuthHdr
;
454 BOOLEAN TimerCancelled
;
456 u8
*pOutBuffer
= NULL
;
457 unsigned long FrameLen
= 0, tmp
= 0;
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",
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,
469 if (MlmeAuthReqSanity
470 (pAd
, pElem
->Msg
, pElem
->MsgLen
, Addr
, &Timeout
, &Alg
)) {
472 RTMPCancelTimer(pAuthTimer
, &TimerCancelled
);
474 COPY_MAC_ADDR(pAd
->MlmeAux
.Bssid
, Addr
);
475 pAd
->MlmeAux
.Alg
= Alg
;
477 Status
= MLME_SUCCESS
;
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",
484 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
485 Status
= MLME_FAIL_NO_RESOURCE
;
486 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_AUTH_CONF
,
491 DBGPRINT(RT_DEBUG_TRACE
,
492 ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName
,
494 MgtMacHeaderInit(pAd
, &AuthHdr
, SUBTYPE_AUTH
, 0, Addr
,
496 MakeOutgoingFrame(pOutBuffer
, &FrameLen
, sizeof(struct rt_header_802_11
),
497 &AuthHdr
, 2, &Alg
, 2, &Seq
, 2, &Status
,
500 if (pNewElement
&& ElementLen
) {
501 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
502 ElementLen
, pNewElement
, END_OF_ARGS
);
506 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
507 MlmeFreeMemory(pAd
, pOutBuffer
);
509 RTMPSetTimer(pAuthTimer
, Timeout
);
512 DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n",