MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / Module / auth.c
blob9eb2cec3d1207f342e460889885d7cc159d29eb3
1 /*************************************************************************
2 * Ralink Tech Inc. *
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
6 * *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
8 * *
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. *
13 * *
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. *
18 * *
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. *
23 * *
24 ************************************************************************/
26 #include "rt_config.h"
29 ==========================================================================
30 Description:
31 authenticate state machine init, including state transition and timer init
32 Parameters:
33 Sm - pointer to the auth state machine
34 Note:
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(
47 IN PRTMP_ADAPTER pAd,
48 IN STATE_MACHINE *Sm,
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);
53 // the first column
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);
58 // the second column
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);
65 // the third column
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 ==========================================================================
77 Description:
78 function to be executed at timer thread when auth timer expires
79 ==========================================================================
81 VOID AuthTimeout(
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);
88 MlmeHandler(pAd);
93 ==========================================================================
94 Description:
95 ==========================================================================
97 VOID MlmeAuthReqAction(
98 IN PRTMP_ADAPTER pAd,
99 IN MLME_QUEUE_ELEM *Elem)
101 MACADDR Addr;
102 USHORT Alg, Seq, Status;
103 ULONG Timeout;
104 MACHDR AuthHdr;
105 NDIS_STATUS NStatus;
106 UCHAR *OutBuffer = NULL;
107 ULONG FrameLen = 0;
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))
118 // reset timer
119 RTMPCancelTimer(&pAd->Mlme.AuthAux.AuthTimer);
120 pAd->Mlme.AuthAux.Addr = Addr;
121 pAd->Mlme.AuthAux.Alg = Alg;
122 pAd->PortCfg.Mauth = FALSE;
123 Seq = 1;
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);
132 return;
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,
139 2, &Alg,
140 2, &Seq,
141 2, &Status,
142 END_OF_ARGS);
143 MiniportMMRequest(pAd, OutBuffer, FrameLen);
145 RTMPSetTimer(pAd, &pAd->Mlme.AuthAux.AuthTimer, Timeout);
146 pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
148 else
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 ==========================================================================
158 Description:
159 ==========================================================================
161 VOID PeerAuthRspAtSeq2Action(
162 IN PRTMP_ADAPTER pAd,
163 IN MLME_QUEUE_ELEM *Elem)
165 MACADDR Addr2;
166 USHORT Seq, Status, RemoteStatus, Alg;
167 UCHAR ChlgText[CIPHER_TEXT_LEN];
168 UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
169 UCHAR Element[2];
170 MACHDR AuthHdr;
171 UCHAR *OutBuffer = NULL;
172 NDIS_STATUS NStatus;
173 ULONG FrameLen = 0;
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);
190 else
192 // 2. shared key, need to be challenged
193 Seq++;
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);
201 return;
204 DBGPRINT(RT_DEBUG_TRACE, "AUTH - Send AUTH request seq#3...\n");
205 MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, &Addr2, &pAd->PortCfg.Bssid);
206 AuthHdr.Wep = 1;
207 // Encrypt challenge text & auth information
208 RTMPInitWepEngine(
209 pAd,
210 pAd->PortCfg.SharedKey[pAd->PortCfg.DefaultKeyId].Key,
211 pAd->PortCfg.DefaultKeyId,
212 pAd->PortCfg.SharedKey[pAd->PortCfg.DefaultKeyId].KeyLen,
213 CyperChlgText);
214 #ifdef BIG_ENDIAN
215 Alg = SWAP16(*(USHORT *)&Alg);
216 Seq = SWAP16(*(USHORT *)&Seq);
217 RemoteStatus= SWAP16(*(USHORT *)&RemoteStatus);
218 pAd->NeedSwapToLittleEndian = FALSE;
219 #endif
220 RTMPEncryptData(pAd, (PUCHAR) &Alg, CyperChlgText + 4, 2);
221 RTMPEncryptData(pAd, (PUCHAR) &Seq, CyperChlgText + 6, 2);
222 RTMPEncryptData(pAd, (PUCHAR) &RemoteStatus, CyperChlgText + 8, 2);
224 Element[0] = 16;
225 Element[1] = 128;
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,
232 END_OF_ARGS);
233 MiniportMMRequest(pAd, OutBuffer, FrameLen);
234 #ifdef BIG_ENDIAN
235 pAd->NeedSwapToLittleEndian = TRUE;
236 #endif
237 RTMPSetTimer(pAd, &pAd->Mlme.AuthAux.AuthTimer, AUTH_TIMEOUT);
238 pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4;
241 else
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);
250 else
252 DBGPRINT(RT_DEBUG_TRACE, "AUTH - PeerAuthSanity() sanity check fail\n");
257 ==========================================================================
258 Description:
259 ==========================================================================
261 VOID PeerAuthRspAtSeq4Action(
262 IN PRTMP_ADAPTER pAd,
263 IN MLME_QUEUE_ELEM *Elem)
265 MACADDR Addr2;
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;
280 else
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);
290 else
292 DBGPRINT(RT_DEBUG_TRACE, "AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n");
297 ==========================================================================
298 Description:
299 ==========================================================================
301 VOID MlmeDeauthReqAction(
302 IN PRTMP_ADAPTER pAd,
303 IN MLME_QUEUE_ELEM *Elem)
305 MLME_DEAUTH_REQ_STRUCT *Info;
306 MACHDR Hdr;
307 UCHAR *OutBuffer = NULL;
308 NDIS_STATUS NStatus;
309 ULONG FrameLen = 0;
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);
319 return;
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,
326 2, &Info->Reason,
327 END_OF_ARGS);
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 ==========================================================================
338 Description:
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 ==========================================================================
352 Description:
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 ==========================================================================
366 Description:
367 Some STA/AP
368 Note:
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 ==========================================================================
373 VOID Cls2errAction(
374 IN PRTMP_ADAPTER pAd,
375 IN PMACADDR pAddr)
377 MACHDR Hdr;
378 UCHAR *OutBuffer = NULL;
379 NDIS_STATUS NStatus;
380 ULONG FrameLen = 0;
381 USHORT Reason = REASON_CLS2ERR;
383 NStatus = MlmeAllocateMemory(pAd, (PVOID)&OutBuffer); //Get an unused nonpaged memory
384 if (NStatus != NDIS_STATUS_SUCCESS)
385 return;
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,
391 2, &Reason,
392 END_OF_ARGS);
393 MiniportMMRequest(pAd, OutBuffer, FrameLen);
395 pAd->PortCfg.DeauthReason = Reason;
396 COPY_MAC_ADDR(&pAd->PortCfg.DeauthSta, pAddr);