1 /****************************************************************************
3 * 4F, No. 2 Technology 5th Rd.
4 * Science-based Industrial Park
5 * Hsin-chu, Taiwan, R.O.C.
6 * (c) Copyright 2002, Ralink Technology, Inc.
8 * All rights reserved. Ralink's source code is an unpublished work and the
9 * use of a copyright notice does not imply otherwise. This source code
10 * contains confidential trade secret material of Ralink Tech. Any attemp
11 * or participation in deciphering, decoding, reverse engineering or in any
12 * way altering the source code is stricitly prohibited, unless the prior
13 * written consent of Ralink Technology, Inc. is obtained.
14 ****************************************************************************/
16 #include "rt_config.h"
19 ==========================================================================
21 authenticate state machine init, including state transition and timer init
23 Sm - pointer to the auth state machine
25 The state machine looks like this
27 AUTH_REQ_IDLE AUTH_WAIT_SEQ2 AUTH_WAIT_SEQ4
28 MT2_MLME_AUTH_REQ mlme_auth_req_action invalid_state_when_auth invalid_state_when_auth
29 MT2_MLME_DEAUTH_REQ mlme_deauth_req_action mlme_deauth_req_action mlme_deauth_req_action
30 MT2_CLS2ERR cls2err_action cls2err_action cls2err_action
31 MT2_PEER_AUTH_EVEN drop peer_auth_even_at_seq2_action peer_auth_even_at_seq4_action
32 MT2_AUTH_TIMEOUT Drop auth_timeout_action auth_timeout_action
33 ==========================================================================
36 void AuthStateMachineInit(
39 OUT STATE_MACHINE_FUNC Trans
[])
41 StateMachineInit(Sm
, (STATE_MACHINE_FUNC
*)Trans
, MAX_AUTH_STATE
, MAX_AUTH_MSG
, (STATE_MACHINE_FUNC
)Drop
, AUTH_REQ_IDLE
, AUTH_MACHINE_BASE
);
44 StateMachineSetAction(Sm
, AUTH_REQ_IDLE
, MT2_MLME_AUTH_REQ
, (STATE_MACHINE_FUNC
)MlmeAuthReqAction
);
45 // StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)MlmeDeauthReqAction);
46 // StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_CLS2ERR, (STATE_MACHINE_FUNC)Cls2errAction);
49 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ2
, MT2_MLME_AUTH_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenAuth
);
50 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)MlmeDeauthReqAction);
51 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_CLS2ERR, (STATE_MACHINE_FUNC)Cls2errAction);
52 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ2
, MT2_PEER_AUTH_EVEN
, (STATE_MACHINE_FUNC
)PeerAuthRspAtSeq2Action
);
53 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ2
, MT2_AUTH_TIMEOUT
, (STATE_MACHINE_FUNC
)AuthTimeoutAction
);
56 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ4
, MT2_MLME_AUTH_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenAuth
);
57 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)MlmeDeauthReqAction);
58 // StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_CLS2ERR, (STATE_MACHINE_FUNC)Cls2errAction);
59 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ4
, MT2_PEER_AUTH_EVEN
, (STATE_MACHINE_FUNC
)PeerAuthRspAtSeq4Action
);
60 StateMachineSetAction(Sm
, AUTH_WAIT_SEQ4
, MT2_AUTH_TIMEOUT
, (STATE_MACHINE_FUNC
)AuthTimeoutAction
);
62 RTMPInitTimer(pAd
, &pAd
->Mlme
.AuthAux
.AuthTimer
, AuthTimeout
);
66 ==========================================================================
68 function to be executed at timer thread when auth timer expires
69 ==========================================================================
72 IN
unsigned long data
)
74 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)data
;
76 DBGPRINT(RT_DEBUG_TRACE
,"AUTH - AuthTimeout\n");
77 MlmeEnqueue(&pAd
->Mlme
.Queue
, AUTH_STATE_MACHINE
, MT2_AUTH_TIMEOUT
, 0, NULL
);
83 ==========================================================================
85 ==========================================================================
87 VOID
MlmeAuthReqAction(
89 IN MLME_QUEUE_ELEM
*Elem
)
92 USHORT Alg
, Seq
, Status
;
96 UCHAR
*OutBuffer
= NULL
;
99 // Block all authentication request durning WPA block period
100 if (pAd
->PortCfg
.bBlockAssoc
== TRUE
)
102 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Block Auth request durning WPA block period!\n");
103 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
104 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_STATE_MACHINE_REJECT
);
106 else if(MlmeAuthReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr
, &Timeout
, &Alg
))
109 RTMPCancelTimer(&pAd
->Mlme
.AuthAux
.AuthTimer
);
110 pAd
->Mlme
.AuthAux
.Addr
= Addr
;
111 pAd
->Mlme
.AuthAux
.Alg
= Alg
;
112 pAd
->PortCfg
.Mauth
= FALSE
;
114 Status
= MLME_SUCCESS
;
116 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
117 if(NStatus
!= NDIS_STATUS_SUCCESS
)
119 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - MlmeAuthReqAction() allocate memory failed\n");
120 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
121 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_FAIL_NO_RESOURCE
);
125 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg
);
126 MgtMacHeaderInit(pAd
, &AuthHdr
, SUBTYPE_AUTH
, 0, &Addr
, &pAd
->PortCfg
.Bssid
);
127 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
128 MAC_HDR_LEN
, &AuthHdr
,
133 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
135 RTMPSetTimer(pAd
, &pAd
->Mlme
.AuthAux
.AuthTimer
, Timeout
);
136 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_WAIT_SEQ2
;
140 DBGPRINT(RT_DEBUG_ERROR
, "AUTH - MlmeAuthReqAction() sanity check failed. BUG!!!!!\n");
141 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
142 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_INVALID_FORMAT
);
147 ==========================================================================
149 ==========================================================================
151 VOID
PeerAuthRspAtSeq2Action(
152 IN PRTMP_ADAPTER pAd
,
153 IN MLME_QUEUE_ELEM
*Elem
)
156 USHORT Seq
, Status
, RemoteStatus
, Alg
;
157 UCHAR ChlgText
[CIPHER_TEXT_LEN
];
158 UCHAR CyperChlgText
[CIPHER_TEXT_LEN
+ 8 + 8];
161 UCHAR
*OutBuffer
= NULL
;
165 if (PeerAuthSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr2
, &Alg
, &Seq
, &Status
, ChlgText
))
167 if (MAC_ADDR_EQUAL(&pAd
->Mlme
.AuthAux
.Addr
, &Addr2
) && Seq
== 2)
169 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg
, Status
);
170 RTMPCancelTimer(&pAd
->Mlme
.AuthAux
.AuthTimer
);
172 if (Status
== MLME_SUCCESS
)
174 if (pAd
->Mlme
.AuthAux
.Alg
== Ndis802_11AuthModeOpen
)
176 pAd
->PortCfg
.Mauth
= TRUE
;
177 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
178 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_SUCCESS
);
182 // 2. shared key, need to be challenged
184 RemoteStatus
= MLME_SUCCESS
;
185 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
186 if(NStatus
!= NDIS_STATUS_SUCCESS
)
188 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n");
189 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
190 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_FAIL_NO_RESOURCE
);
194 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Send AUTH request seq#3...\n");
195 MgtMacHeaderInit(pAd
, &AuthHdr
, SUBTYPE_AUTH
, 0, &Addr2
, &pAd
->PortCfg
.Bssid
);
197 // Encrypt challenge text & auth information
200 pAd
->PortCfg
.SharedKey
[pAd
->PortCfg
.DefaultKeyId
].Key
,
201 pAd
->PortCfg
.DefaultKeyId
,
202 pAd
->PortCfg
.SharedKey
[pAd
->PortCfg
.DefaultKeyId
].KeyLen
,
205 Alg
= SWAP16(*(USHORT
*)&Alg
);
206 Seq
= SWAP16(*(USHORT
*)&Seq
);
207 RemoteStatus
= SWAP16(*(USHORT
*)&RemoteStatus
);
208 pAd
->NeedSwapToLittleEndian
= FALSE
;
210 RTMPEncryptData(pAd
, (PUCHAR
) &Alg
, CyperChlgText
+ 4, 2);
211 RTMPEncryptData(pAd
, (PUCHAR
) &Seq
, CyperChlgText
+ 6, 2);
212 RTMPEncryptData(pAd
, (PUCHAR
) &RemoteStatus
, CyperChlgText
+ 8, 2);
216 RTMPEncryptData(pAd
, Element
, CyperChlgText
+ 10, 2);
217 RTMPEncryptData(pAd
, ChlgText
, CyperChlgText
+ 12, 128);
218 RTMPSetICV(pAd
, CyperChlgText
+ 140);
219 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
220 MAC_HDR_LEN
, &AuthHdr
,
221 CIPHER_TEXT_LEN
+ 16, CyperChlgText
,
223 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
225 pAd
->NeedSwapToLittleEndian
= TRUE
;
227 RTMPSetTimer(pAd
, &pAd
->Mlme
.AuthAux
.AuthTimer
, AUTH_TIMEOUT
);
228 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_WAIT_SEQ4
;
233 pAd
->PortCfg
.AuthFailReason
= Status
;
234 COPY_MAC_ADDR(&pAd
->PortCfg
.AuthFailSta
, &Addr2
);
235 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
236 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, Status
);
242 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - PeerAuthSanity() sanity check fail\n");
247 ==========================================================================
249 ==========================================================================
251 VOID
PeerAuthRspAtSeq4Action(
252 IN PRTMP_ADAPTER pAd
,
253 IN MLME_QUEUE_ELEM
*Elem
)
256 USHORT Alg
, Seq
, Status
;
257 CHAR ChlgText
[CIPHER_TEXT_LEN
];
259 if(PeerAuthSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr2
, &Alg
, &Seq
, &Status
, ChlgText
))
261 if(MAC_ADDR_EQUAL(&(pAd
->Mlme
.AuthAux
.Addr
), &Addr2
) && Seq
== 4)
263 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Receive AUTH_RSP seq#4 to me\n");
264 RTMPCancelTimer(&pAd
->Mlme
.AuthAux
.AuthTimer
);
266 if(Status
== MLME_SUCCESS
)
268 pAd
->PortCfg
.Mauth
= TRUE
;
272 pAd
->PortCfg
.AuthFailReason
= Status
;
273 pAd
->PortCfg
.AuthFailSta
= Addr2
;
276 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
277 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, Status
);
282 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n");
287 ==========================================================================
289 ==========================================================================
291 VOID
MlmeDeauthReqAction(
292 IN PRTMP_ADAPTER pAd
,
293 IN MLME_QUEUE_ELEM
*Elem
)
295 MLME_DEAUTH_REQ_STRUCT
*Info
;
297 UCHAR
*OutBuffer
= NULL
;
301 Info
= (MLME_DEAUTH_REQ_STRUCT
*)Elem
->Msg
;
303 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
304 if (NStatus
!= NDIS_STATUS_SUCCESS
)
306 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - MlmeDeauthReqAction() allocate memory fail\n");
307 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
308 MlmeCntlConfirm(pAd
, MT2_DEAUTH_CONF
, MLME_FAIL_NO_RESOURCE
);
312 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Send DE-AUTH request...\n");
313 MgtMacHeaderInit(pAd
, &Hdr
, SUBTYPE_DEAUTH
, 0, &Info
->Addr
, &pAd
->PortCfg
.Bssid
);
314 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
315 sizeof(MACHDR
), &Hdr
,
318 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
320 pAd
->PortCfg
.DeauthReason
= Info
->Reason
;
321 COPY_MAC_ADDR(&pAd
->PortCfg
.DeauthSta
, &Info
->Addr
);
322 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
323 MlmeCntlConfirm(pAd
, MT2_DEAUTH_CONF
, MLME_SUCCESS
);
327 ==========================================================================
329 ==========================================================================
331 VOID
AuthTimeoutAction(
332 IN PRTMP_ADAPTER pAd
,
333 IN MLME_QUEUE_ELEM
*Elem
)
335 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - AuthTimeoutAction\n");
336 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
337 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_REJ_TIMEOUT
);
341 ==========================================================================
343 ==========================================================================
345 VOID
InvalidStateWhenAuth(
346 IN PRTMP_ADAPTER pAd
,
347 IN MLME_QUEUE_ELEM
*Elem
)
349 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - InvalidStateWhenAuth (state=%d), reset AUTH state machine\n", pAd
->Mlme
.AuthMachine
.CurrState
);
350 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
351 MlmeCntlConfirm(pAd
, MT2_AUTH_CONF
, MLME_STATE_MACHINE_REJECT
);
355 ==========================================================================
359 This action should never trigger AUTH state transition, therefore we
360 separate it from AUTH state machine, and make it as a standalone service
361 ==========================================================================
364 IN PRTMP_ADAPTER pAd
,
368 UCHAR
*OutBuffer
= NULL
;
371 USHORT Reason
= REASON_CLS2ERR
;
373 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
374 if (NStatus
!= NDIS_STATUS_SUCCESS
)
377 DBGPRINT(RT_DEBUG_TRACE
, "AUTH - Class 2 error, Send DEAUTH frame...\n");
378 MgtMacHeaderInit(pAd
, &Hdr
, SUBTYPE_DEAUTH
, 0, pAddr
, &pAd
->PortCfg
.Bssid
);
379 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
380 sizeof(MACHDR
), &Hdr
,
383 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
385 pAd
->PortCfg
.DeauthReason
= Reason
;
386 COPY_MAC_ADDR(&pAd
->PortCfg
.DeauthSta
, pAddr
);