1 /*************************************************************************
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 ************************************************************************/
26 #include "rt_config.h"
29 ==========================================================================
31 authenticate state machine init, including state transition and timer init
33 Sm - pointer to the auth state machine
35 The state machine looks like this
37 AUTH_REQ_IDLE AUTH_WAIT_SEQ2 AUTH_WAIT_SEQ4
38 MT2_MLME_AUTH_REQ mlme_auth_req_action invalid_state_when_auth invalid_state_when_auth
39 MT2_MLME_DEAUTH_REQ mlme_deauth_req_action mlme_deauth_req_action mlme_deauth_req_action
40 MT2_CLS2ERR cls2err_action cls2err_action cls2err_action
41 MT2_PEER_AUTH_EVEN drop peer_auth_even_at_seq2_action peer_auth_even_at_seq4_action
42 MT2_AUTH_TIMEOUT Drop auth_timeout_action auth_timeout_action
43 ==========================================================================
46 void AuthStateMachineInit(
49 OUT STATE_MACHINE_FUNC Trans
[])
51 StateMachineInit(Sm
, (STATE_MACHINE_FUNC
*)Trans
, MAX_AUTH_STATE
, MAX_AUTH_MSG
, (STATE_MACHINE_FUNC
)Drop
, AUTH_REQ_IDLE
, AUTH_MACHINE_BASE
);
54 StateMachineSetAction(Sm
, AUTH_REQ_IDLE
, MT2_MLME_AUTH_REQ
, (STATE_MACHINE_FUNC
)MlmeAuthReqAction
);
55 // StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)MlmeDeauthReqAction);
56 // StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_CLS2ERR, (STATE_MACHINE_FUNC)Cls2errAction);
59 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ2
, MT2_MLME_AUTH_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenAuth
);
60 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)MlmeDeauthReqAction);
61 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_CLS2ERR, (STATE_MACHINE_FUNC)Cls2errAction);
62 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ2
, MT2_PEER_AUTH_EVEN
, (STATE_MACHINE_FUNC
)PeerAuthRspAtSeq2Action
);
63 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ2
, MT2_AUTH_TIMEOUT
, (STATE_MACHINE_FUNC
)AuthTimeoutAction
);
66 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ4
, MT2_MLME_AUTH_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenAuth
);
67 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)MlmeDeauthReqAction);
68 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_CLS2ERR, (STATE_MACHINE_FUNC)Cls2errAction);
69 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ4
, MT2_PEER_AUTH_EVEN
, (STATE_MACHINE_FUNC
)PeerAuthRspAtSeq4Action
);
70 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ4
, MT2_AUTH_TIMEOUT
, (STATE_MACHINE_FUNC
)AuthTimeoutAction
);
72 RTMPInitTimer(pAd
, &pAd
->Mlme
.AuthAux
.AuthTimer
, AuthTimeout
);
76 ==========================================================================
78 function to be executed at timer thread when auth timer expires
79 ==========================================================================
82 IN
unsigned long data
)
84 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)data
;
86 DBGPRINT(RT_DEBUG_TRACE
,"AUTH - AuthTimeout\n");
87 MlmeEnqueue(&pAd
->Mlme
.Queue
, AUTH_STATE_MACHINE
, MT2_AUTH_TIMEOUT
, 0, NULL
);
93 ==========================================================================
95 ==========================================================================
97 VOID
MlmeAuthReqAction(
99 IN MLME_QUEUE_ELEM
*Elem
)
102 USHORT Alg
, Seq
, Status
;
106 UCHAR
*OutBuffer
= NULL
;
109 // Block all authentication request durning WPA block period
110 if (pAd
->PortCfg
.bBlockAssoc
== TRUE
)
112 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Block Auth request durning WPA block period!\n");
113 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
114 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_STATE_MACHINE_REJECT
);
116 else if(MlmeAuthReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr
, &Timeout
, &Alg
))
119 RTMPCancelTimer(&pAd
->Mlme
.AuthAux
.AuthTimer
);
120 pAd
->Mlme
.AuthAux
.Addr
= Addr
;
121 pAd
->Mlme
.AuthAux
.Alg
= Alg
;
122 pAd
->PortCfg
.Mauth
= FALSE
;
124 Status
= MLME_SUCCESS
;
126 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
127 if(NStatus
!= NDIS_STATUS_SUCCESS
)
129 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - MlmeAuthReqAction() allocate memory failed\n");
130 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
131 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_FAIL_NO_RESOURCE
);
135 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg
);
136 MgtMacHeaderInit(pAd
, &AuthHdr
, SUBTYPE_AUTH
, 0, &Addr
, &pAd
->PortCfg
.Bssid
);
137 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
138 MAC_HDR_LEN
, &AuthHdr
,
143 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
145 RTMPSetTimer(pAd
, &pAd
->Mlme
.AuthAux
.AuthTimer
, Timeout
);
146 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_WAIT_SEQ2
;
150 DBGPRINT(RT_DEBUG_ERROR
, "AUTH - MlmeAuthReqAction() sanity check failed. BUG!!!!!\n");
151 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
152 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_INVALID_FORMAT
);
157 ==========================================================================
159 ==========================================================================
161 VOID
PeerAuthRspAtSeq2Action(
162 IN PRTMP_ADAPTER pAd
,
163 IN MLME_QUEUE_ELEM
*Elem
)
166 USHORT Seq
, Status
, RemoteStatus
, Alg
;
167 UCHAR ChlgText
[CIPHER_TEXT_LEN
];
168 UCHAR CyperChlgText
[CIPHER_TEXT_LEN
+ 8 + 8];
171 UCHAR
*OutBuffer
= NULL
;
175 if (PeerAuthSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr2
, &Alg
, &Seq
, &Status
, ChlgText
))
177 if (MAC_ADDR_EQUAL(&pAd
->Mlme
.AuthAux
.Addr
, &Addr2
) && Seq
== 2)
179 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg
, Status
);
180 RTMPCancelTimer(&pAd
->Mlme
.AuthAux
.AuthTimer
);
182 if (Status
== MLME_SUCCESS
)
184 if (pAd
->Mlme
.AuthAux
.Alg
== Ndis802_11AuthModeOpen
)
186 pAd
->PortCfg
.Mauth
= TRUE
;
187 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
188 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_SUCCESS
);
192 // 2. shared key, need to be challenged
194 RemoteStatus
= MLME_SUCCESS
;
195 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
196 if(NStatus
!= NDIS_STATUS_SUCCESS
)
198 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n");
199 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
200 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_FAIL_NO_RESOURCE
);
204 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Send AUTH request seq#3...\n");
205 MgtMacHeaderInit(pAd
, &AuthHdr
, SUBTYPE_AUTH
, 0, &Addr2
, &pAd
->PortCfg
.Bssid
);
207 // Encrypt challenge text & auth information
210 pAd
->PortCfg
.SharedKey
[pAd
->PortCfg
.DefaultKeyId
].Key
,
211 pAd
->PortCfg
.DefaultKeyId
,
212 pAd
->PortCfg
.SharedKey
[pAd
->PortCfg
.DefaultKeyId
].KeyLen
,
215 Alg
= SWAP16(*(USHORT
*)&Alg
);
216 Seq
= SWAP16(*(USHORT
*)&Seq
);
217 RemoteStatus
= SWAP16(*(USHORT
*)&RemoteStatus
);
218 pAd
->NeedSwapToLittleEndian
= FALSE
;
220 RTMPEncryptData(pAd
, (PUCHAR
) &Alg
, CyperChlgText
+ 4, 2);
221 RTMPEncryptData(pAd
, (PUCHAR
) &Seq
, CyperChlgText
+ 6, 2);
222 RTMPEncryptData(pAd
, (PUCHAR
) &RemoteStatus
, CyperChlgText
+ 8, 2);
226 RTMPEncryptData(pAd
, Element
, CyperChlgText
+ 10, 2);
227 RTMPEncryptData(pAd
, ChlgText
, CyperChlgText
+ 12, 128);
228 RTMPSetICV(pAd
, CyperChlgText
+ 140);
229 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
230 MAC_HDR_LEN
, &AuthHdr
,
231 CIPHER_TEXT_LEN
+ 16, CyperChlgText
,
233 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
235 pAd
->NeedSwapToLittleEndian
= TRUE
;
237 RTMPSetTimer(pAd
, &pAd
->Mlme
.AuthAux
.AuthTimer
, AUTH_TIMEOUT
);
238 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_WAIT_SEQ4
;
243 pAd
->PortCfg
.AuthFailReason
= Status
;
244 COPY_MAC_ADDR(&pAd
->PortCfg
.AuthFailSta
, &Addr2
);
245 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
246 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, Status
);
252 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - PeerAuthSanity() sanity check fail\n");
257 ==========================================================================
259 ==========================================================================
261 VOID
PeerAuthRspAtSeq4Action(
262 IN PRTMP_ADAPTER pAd
,
263 IN MLME_QUEUE_ELEM
*Elem
)
266 USHORT Alg
, Seq
, Status
;
267 CHAR ChlgText
[CIPHER_TEXT_LEN
];
269 if(PeerAuthSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr2
, &Alg
, &Seq
, &Status
, ChlgText
))
271 if(MAC_ADDR_EQUAL(&(pAd
->Mlme
.AuthAux
.Addr
), &Addr2
) && Seq
== 4)
273 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Receive AUTH_RSP seq#4 to me\n");
274 RTMPCancelTimer(&pAd
->Mlme
.AuthAux
.AuthTimer
);
276 if(Status
== MLME_SUCCESS
)
278 pAd
->PortCfg
.Mauth
= TRUE
;
282 pAd
->PortCfg
.AuthFailReason
= Status
;
283 pAd
->PortCfg
.AuthFailSta
= Addr2
;
286 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
287 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, Status
);
292 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n");
297 ==========================================================================
299 ==========================================================================
301 VOID
MlmeDeauthReqAction(
302 IN PRTMP_ADAPTER pAd
,
303 IN MLME_QUEUE_ELEM
*Elem
)
305 MLME_DEAUTH_REQ_STRUCT
*Info
;
307 UCHAR
*OutBuffer
= NULL
;
311 Info
= (MLME_DEAUTH_REQ_STRUCT
*)Elem
->Msg
;
313 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
314 if (NStatus
!= NDIS_STATUS_SUCCESS
)
316 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - MlmeDeauthReqAction() allocate memory fail\n");
317 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
318 MlmeCntlConfirm(pAd
, MT2_DEAUTH_CONF
, MLME_FAIL_NO_RESOURCE
);
322 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Send DE-AUTH request...\n");
323 MgtMacHeaderInit(pAd
, &Hdr
, SUBTYPE_DEAUTH
, 0, &Info
->Addr
, &pAd
->PortCfg
.Bssid
);
324 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
325 sizeof(MACHDR
), &Hdr
,
328 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
330 pAd
->PortCfg
.DeauthReason
= Info
->Reason
;
331 COPY_MAC_ADDR(&pAd
->PortCfg
.DeauthSta
, &Info
->Addr
);
332 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
333 MlmeCntlConfirm(pAd
, MT2_DEAUTH_CONF
, MLME_SUCCESS
);
337 ==========================================================================
339 ==========================================================================
341 VOID
AuthTimeoutAction(
342 IN PRTMP_ADAPTER pAd
,
343 IN MLME_QUEUE_ELEM
*Elem
)
345 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - AuthTimeoutAction\n");
346 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
347 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_REJ_TIMEOUT
);
351 ==========================================================================
353 ==========================================================================
355 VOID
InvalidStateWhenAuth(
356 IN PRTMP_ADAPTER pAd
,
357 IN MLME_QUEUE_ELEM
*Elem
)
359 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - InvalidStateWhenAuth (state=%d), reset AUTH state machine\n", pAd
->Mlme
.AuthMachine
.CurrState
);
360 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
361 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_STATE_MACHINE_REJECT
);
365 ==========================================================================
369 This action should never trigger AUTH state transition, therefore we
370 separate it from AUTH state machine, and make it as a standalone service
371 ==========================================================================
374 IN PRTMP_ADAPTER pAd
,
378 UCHAR
*OutBuffer
= NULL
;
381 USHORT Reason
= REASON_CLS2ERR
;
383 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
384 if (NStatus
!= NDIS_STATUS_SUCCESS
)
387 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Class 2 error, Send DEAUTH frame...\n");
388 MgtMacHeaderInit(pAd
, &Hdr
, SUBTYPE_DEAUTH
, 0, pAddr
, &pAd
->PortCfg
.Bssid
);
389 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
390 sizeof(MACHDR
), &Hdr
,
393 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
395 pAd
->PortCfg
.DeauthReason
= Reason
;
396 COPY_MAC_ADDR(&pAd
->PortCfg
.DeauthSta
, pAddr
);