~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to drivers/staging/rt2860/common/cmm_wpa.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
        wpa.c
29
 
 
30
 
        Abstract:
31
 
 
32
 
        Revision History:
33
 
        Who                     When                    What
34
 
        --------        ----------              ----------------------------------------------
35
 
        Jan     Lee             03-07-22                Initial
36
 
        Paul Lin        03-11-28                Modify for supplicant
37
 
*/
38
 
#include "../rt_config.h"
39
 
/* WPA OUI */
40
 
u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 };
41
 
u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 };
42
 
u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 };
43
 
u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 };
44
 
u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 };
45
 
u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 };
46
 
u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 };
47
 
u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 };
48
 
 
49
 
/* WPA2 OUI */
50
 
u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
51
 
u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
52
 
u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
53
 
u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 };
54
 
u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 };
55
 
u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
56
 
 
57
 
static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
58
 
                                  u8 GroupKeyWepStatus,
59
 
                                  u8 keyDescVer,
60
 
                                  u8 MsgType,
61
 
                                  u8 DefaultKeyIdx,
62
 
                                  u8 * GTK,
63
 
                                  u8 * RSNIE,
64
 
                                  u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);
65
 
 
66
 
static void CalculateMIC(u8 KeyDescVer,
67
 
                         u8 * PTK, struct rt_eapol_packet * pMsg);
68
 
 
69
 
static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
70
 
 
71
 
static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
72
 
                                   struct rt_mlme_queue_elem *Elem);
73
 
 
74
 
static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
75
 
                                 struct rt_mlme_queue_elem *Elem);
76
 
 
77
 
static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
78
 
                                struct rt_mlme_queue_elem *Elem);
79
 
 
80
 
static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
81
 
 
82
 
/*
83
 
    ==========================================================================
84
 
    Description:
85
 
        association state machine init, including state transition and timer init
86
 
    Parameters:
87
 
        S - pointer to the association state machine
88
 
    ==========================================================================
89
 
 */
90
 
void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
91
 
                         struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
92
 
{
93
 
        StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE,
94
 
                         MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK,
95
 
                         WPA_MACHINE_BASE);
96
 
 
97
 
        StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket,
98
 
                              (STATE_MACHINE_FUNC) WpaEAPPacketAction);
99
 
        StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart,
100
 
                              (STATE_MACHINE_FUNC) WpaEAPOLStartAction);
101
 
        StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff,
102
 
                              (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction);
103
 
        StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey,
104
 
                              (STATE_MACHINE_FUNC) WpaEAPOLKeyAction);
105
 
        StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert,
106
 
                              (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction);
107
 
}
108
 
 
109
 
/*
110
 
    ==========================================================================
111
 
    Description:
112
 
        this is state machine function.
113
 
        When receiving EAP packets which is  for 802.1x authentication use.
114
 
        Not use in PSK case
115
 
    Return:
116
 
    ==========================================================================
117
 
*/
118
 
void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
119
 
{
120
 
}
121
 
 
122
 
void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
123
 
{
124
 
}
125
 
 
126
 
void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
127
 
{
128
 
}
129
 
 
130
 
/*
131
 
    ==========================================================================
132
 
    Description:
133
 
       Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
134
 
    Return:
135
 
    ==========================================================================
136
 
*/
137
 
void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
138
 
{
139
 
        struct rt_mac_table_entry *pEntry;
140
 
        struct rt_header_802_11 * pHeader;
141
 
 
142
 
        DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
143
 
 
144
 
        pHeader = (struct rt_header_802_11 *) Elem->Msg;
145
 
 
146
 
        /*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */
147
 
        if (Elem->MsgLen == 6)
148
 
                pEntry = MacTableLookup(pAd, Elem->Msg);
149
 
        else {
150
 
                pEntry = MacTableLookup(pAd, pHeader->Addr2);
151
 
        }
152
 
 
153
 
        if (pEntry) {
154
 
                DBGPRINT(RT_DEBUG_TRACE,
155
 
                         (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n",
156
 
                          pEntry->PortSecured, pEntry->WpaState,
157
 
                          pEntry->AuthMode, pEntry->PMKID_CacheIdx));
158
 
 
159
 
                if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
160
 
                    && (pEntry->WpaState < AS_PTKSTART)
161
 
                    && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
162
 
                        || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
163
 
                        || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
164
 
                            && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) {
165
 
                        pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
166
 
                        pEntry->WpaState = AS_INITPSK;
167
 
                        pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
168
 
                        NdisZeroMemory(pEntry->R_Counter,
169
 
                                       sizeof(pEntry->R_Counter));
170
 
                        pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
171
 
 
172
 
                        WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
173
 
                }
174
 
        }
175
 
}
176
 
 
177
 
/*
178
 
    ==========================================================================
179
 
    Description:
180
 
        This is state machine function.
181
 
        When receiving EAPOL packets which is  for 802.1x key management.
182
 
        Use both in WPA, and WPAPSK case.
183
 
        In this function, further dispatch to different functions according to the received packet.  3 categories are :
184
 
          1.  normal 4-way pairwisekey and 2-way groupkey handshake
185
 
          2.  MIC error (Countermeasures attack)  report packet from STA.
186
 
          3.  Request for pairwise/group key update from STA
187
 
    Return:
188
 
    ==========================================================================
189
 
*/
190
 
void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
191
 
{
192
 
        struct rt_mac_table_entry *pEntry;
193
 
        struct rt_header_802_11 * pHeader;
194
 
        struct rt_eapol_packet * pEapol_packet;
195
 
        struct rt_key_info peerKeyInfo;
196
 
 
197
 
        DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
198
 
 
199
 
        pHeader = (struct rt_header_802_11 *) Elem->Msg;
200
 
        pEapol_packet =
201
 
            (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
202
 
 
203
 
        NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
204
 
        NdisMoveMemory((u8 *)& peerKeyInfo,
205
 
                       (u8 *)& pEapol_packet->KeyDesc.KeyInfo,
206
 
                       sizeof(struct rt_key_info));
207
 
 
208
 
        hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
209
 
                 (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
210
 
 
211
 
        *((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));
212
 
 
213
 
        do {
214
 
                pEntry = MacTableLookup(pAd, pHeader->Addr2);
215
 
 
216
 
                if (!pEntry
217
 
                    || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
218
 
                        break;
219
 
 
220
 
                if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
221
 
                        break;
222
 
 
223
 
                DBGPRINT(RT_DEBUG_TRACE,
224
 
                        ("Receive EAPoL-Key frame from STA %pMF\n",
225
 
                                pEntry->Addr));
226
 
 
227
 
                if (((pEapol_packet->ProVer != EAPOL_VER)
228
 
                     && (pEapol_packet->ProVer != EAPOL_VER2))
229
 
                    || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC)
230
 
                        && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) {
231
 
                        DBGPRINT(RT_DEBUG_ERROR,
232
 
                                 ("Key descripter does not match with WPA rule\n"));
233
 
                        break;
234
 
                }
235
 
                /* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */
236
 
                /* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */
237
 
                if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
238
 
                    && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) {
239
 
                        DBGPRINT(RT_DEBUG_ERROR,
240
 
                                 ("Key descripter version not match(TKIP) \n"));
241
 
                        break;
242
 
                }
243
 
                /* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */
244
 
                /* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */
245
 
                else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
246
 
                         && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) {
247
 
                        DBGPRINT(RT_DEBUG_ERROR,
248
 
                                 ("Key descripter version not match(AES) \n"));
249
 
                        break;
250
 
                }
251
 
                /* Check if this STA is in class 3 state and the WPA state is started */
252
 
                if ((pEntry->Sst == SST_ASSOC)
253
 
                    && (pEntry->WpaState >= AS_INITPSK)) {
254
 
                        /* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */
255
 
                        /* or not. */
256
 
                        /* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */
257
 
                        /* Key frame from the Authenticator must not have the Ack bit set. */
258
 
                        if (peerKeyInfo.KeyAck == 1) {
259
 
                                /* The frame is snet by Authenticator. */
260
 
                                /* So the Supplicant side shall handle this. */
261
 
 
262
 
                                if ((peerKeyInfo.Secure == 0)
263
 
                                    && (peerKeyInfo.Request == 0)
264
 
                                    && (peerKeyInfo.Error == 0)
265
 
                                    && (peerKeyInfo.KeyType == PAIRWISEKEY)) {
266
 
                                        /* Process 1. the message 1 of 4-way HS in WPA or WPA2 */
267
 
                                        /*                        EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
268
 
                                        /*                 2. the message 3 of 4-way HS in WPA */
269
 
                                        /*                        EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
270
 
                                        if (peerKeyInfo.KeyMic == 0)
271
 
                                                PeerPairMsg1Action(pAd, pEntry,
272
 
                                                                   Elem);
273
 
                                        else
274
 
                                                PeerPairMsg3Action(pAd, pEntry,
275
 
                                                                   Elem);
276
 
                                } else if ((peerKeyInfo.Secure == 1)
277
 
                                           && (peerKeyInfo.KeyMic == 1)
278
 
                                           && (peerKeyInfo.Request == 0)
279
 
                                           && (peerKeyInfo.Error == 0)) {
280
 
                                        /* Process 1. the message 3 of 4-way HS in WPA2 */
281
 
                                        /*                        EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
282
 
                                        /*                 2. the message 1 of group KS in WPA or WPA2 */
283
 
                                        /*                        EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */
284
 
                                        if (peerKeyInfo.KeyType == PAIRWISEKEY)
285
 
                                                PeerPairMsg3Action(pAd, pEntry,
286
 
                                                                   Elem);
287
 
                                        else
288
 
                                                PeerGroupMsg1Action(pAd, pEntry,
289
 
                                                                    Elem);
290
 
                                }
291
 
                        } else {
292
 
                                /* The frame is snet by Supplicant. */
293
 
                                /* So the Authenticator side shall handle this. */
294
 
                                if ((peerKeyInfo.Request == 0) &&
295
 
                                    (peerKeyInfo.Error == 0) &&
296
 
                                    (peerKeyInfo.KeyMic == 1)) {
297
 
                                        if (peerKeyInfo.Secure == 0
298
 
                                            && peerKeyInfo.KeyType ==
299
 
                                            PAIRWISEKEY) {
300
 
                                                /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */
301
 
                                                /* Process 1. message 2 of 4-way HS in WPA or WPA2 */
302
 
                                                /*                 2. message 4 of 4-way HS in WPA */
303
 
                                                if (CONV_ARRARY_TO_u16
304
 
                                                    (pEapol_packet->KeyDesc.
305
 
                                                     KeyDataLen) == 0) {
306
 
                                                        PeerPairMsg4Action(pAd,
307
 
                                                                           pEntry,
308
 
                                                                           Elem);
309
 
                                                } else {
310
 
                                                        PeerPairMsg2Action(pAd,
311
 
                                                                           pEntry,
312
 
                                                                           Elem);
313
 
                                                }
314
 
                                        } else if (peerKeyInfo.Secure == 1
315
 
                                                   && peerKeyInfo.KeyType ==
316
 
                                                   PAIRWISEKEY) {
317
 
                                                /* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */
318
 
                                                /* Process message 4 of 4-way HS in WPA2 */
319
 
                                                PeerPairMsg4Action(pAd, pEntry,
320
 
                                                                   Elem);
321
 
                                        } else if (peerKeyInfo.Secure == 1
322
 
                                                   && peerKeyInfo.KeyType ==
323
 
                                                   GROUPKEY) {
324
 
                                                /* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */
325
 
                                                /* Process message 2 of Group key HS in WPA or WPA2 */
326
 
                                                PeerGroupMsg2Action(pAd, pEntry,
327
 
                                                                    &Elem->
328
 
                                                                    Msg
329
 
                                                                    [LENGTH_802_11],
330
 
                                                                    (Elem->
331
 
                                                                     MsgLen -
332
 
                                                                     LENGTH_802_11));
333
 
                                        }
334
 
                                }
335
 
                        }
336
 
                }
337
 
        } while (FALSE);
338
 
}
339
 
 
340
 
/*
341
 
        ========================================================================
342
 
 
343
 
        Routine Description:
344
 
                Copy frame from waiting queue into relative ring buffer and set
345
 
        appropriate ASIC register to kick hardware encryption before really
346
 
        sent out to air.
347
 
 
348
 
        Arguments:
349
 
                pAd             Pointer to our adapter
350
 
                void *  Pointer to outgoing Ndis frame
351
 
                NumberOfFrag    Number of fragment required
352
 
 
353
 
        Return Value:
354
 
                None
355
 
 
356
 
        Note:
357
 
 
358
 
        ========================================================================
359
 
*/
360
 
void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
361
 
                       struct rt_mac_table_entry *pEntry,
362
 
                       u8 *pHeader802_3,
363
 
                       u32 HdrLen,
364
 
                       u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
365
 
{
366
 
        void *pPacket;
367
 
        int Status;
368
 
 
369
 
        if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
370
 
                return;
371
 
 
372
 
        do {
373
 
                /* build a NDIS packet */
374
 
                Status =
375
 
                    RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
376
 
                                           pData, DataLen);
377
 
                if (Status != NDIS_STATUS_SUCCESS)
378
 
                        break;
379
 
 
380
 
                if (bClearFrame)
381
 
                        RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
382
 
                else
383
 
                        RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
384
 
                {
385
 
                        RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
386
 
 
387
 
                        RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);        /* set a default value */
388
 
                        if (pEntry->apidx != 0)
389
 
                                RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket,
390
 
                                                                  pEntry->
391
 
                                                                  apidx);
392
 
 
393
 
                        RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
394
 
                        RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
395
 
                }
396
 
 
397
 
                {
398
 
                        /* send out the packet */
399
 
                        Status = STASendPacket(pAd, pPacket);
400
 
                        if (Status == NDIS_STATUS_SUCCESS) {
401
 
                                u8 Index;
402
 
 
403
 
                                /* Dequeue one frame from TxSwQueue0..3 queue and process it */
404
 
                                /* There are three place calling dequeue for TX ring. */
405
 
                                /* 1. Here, right after queueing the frame. */
406
 
                                /* 2. At the end of TxRingTxDone service routine. */
407
 
                                /* 3. Upon NDIS call RTMPSendPackets */
408
 
                                if ((!RTMP_TEST_FLAG
409
 
                                     (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
410
 
                                    &&
411
 
                                    (!RTMP_TEST_FLAG
412
 
                                     (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
413
 
                                        for (Index = 0; Index < 5; Index++)
414
 
                                                if (pAd->TxSwQueue[Index].
415
 
                                                    Number > 0)
416
 
                                                        RTMPDeQueuePacket(pAd,
417
 
                                                                          FALSE,
418
 
                                                                          Index,
419
 
                                                                          MAX_TX_PROCESS);
420
 
                                }
421
 
                        }
422
 
                }
423
 
 
424
 
        } while (FALSE);
425
 
}
426
 
 
427
 
/*
428
 
    ==========================================================================
429
 
    Description:
430
 
        This is a function to initialize 4-way handshake
431
 
 
432
 
    Return:
433
 
 
434
 
    ==========================================================================
435
 
*/
436
 
void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
437
 
                    struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
438
 
{
439
 
        u8 Header802_3[14];
440
 
        struct rt_eapol_packet EAPOLPKT;
441
 
        u8 *pBssid = NULL;
442
 
        u8 group_cipher = Ndis802_11WEPDisabled;
443
 
 
444
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
445
 
 
446
 
        if (RTMP_TEST_FLAG
447
 
            (pAd,
448
 
             fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
449
 
        {
450
 
                DBGPRINT(RT_DEBUG_ERROR,
451
 
                         ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
452
 
                return;
453
 
        }
454
 
 
455
 
        if (pBssid == NULL) {
456
 
                DBGPRINT(RT_DEBUG_ERROR,
457
 
                         ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
458
 
                return;
459
 
        }
460
 
        /* Check the status */
461
 
        if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) {
462
 
                DBGPRINT(RT_DEBUG_ERROR,
463
 
                         ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
464
 
                return;
465
 
        }
466
 
 
467
 
        /* Increment replay counter by 1 */
468
 
        ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
469
 
 
470
 
        /* Randomly generate ANonce */
471
 
        GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);
472
 
 
473
 
        /* Construct EAPoL message - Pairwise Msg 1 */
474
 
        /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
475
 
        NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
476
 
        ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0,    /* Default key index */
477
 
                          pEntry->ANonce, NULL, /* TxRSC */
478
 
                          NULL, /* GTK */
479
 
                          NULL, /* RSNIE */
480
 
                          0,    /* RSNIE length */
481
 
                          &EAPOLPKT);
482
 
 
483
 
        /* Make outgoing frame */
484
 
        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
485
 
        RTMPToWirelessSta(pAd, pEntry, Header802_3,
486
 
                          LENGTH_802_3, (u8 *)& EAPOLPKT,
487
 
                          CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
488
 
                          (pEntry->PortSecured ==
489
 
                           WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
490
 
 
491
 
        /* Trigger Retry Timer */
492
 
        RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
493
 
 
494
 
        /* Update State */
495
 
        pEntry->WpaState = AS_PTKSTART;
496
 
 
497
 
        DBGPRINT(RT_DEBUG_TRACE,
498
 
                 ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
499
 
 
500
 
}
501
 
 
502
 
/*
503
 
        ========================================================================
504
 
 
505
 
        Routine Description:
506
 
                Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
507
 
 
508
 
        Arguments:
509
 
                pAd                     Pointer to our adapter
510
 
                Elem            Message body
511
 
 
512
 
        Return Value:
513
 
                None
514
 
 
515
 
        Note:
516
 
 
517
 
        ========================================================================
518
 
*/
519
 
void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
520
 
                        struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
521
 
{
522
 
        u8 PTK[80];
523
 
        u8 Header802_3[14];
524
 
        struct rt_eapol_packet * pMsg1;
525
 
        u32 MsgLen;
526
 
        struct rt_eapol_packet EAPOLPKT;
527
 
        u8 *pCurrentAddr = NULL;
528
 
        u8 *pmk_ptr = NULL;
529
 
        u8 group_cipher = Ndis802_11WEPDisabled;
530
 
        u8 *rsnie_ptr = NULL;
531
 
        u8 rsnie_len = 0;
532
 
 
533
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
534
 
 
535
 
        if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
536
 
                return;
537
 
 
538
 
        if (Elem->MsgLen <
539
 
            (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
540
 
             sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
541
 
                return;
542
 
 
543
 
        {
544
 
                pCurrentAddr = pAd->CurrentAddress;
545
 
                pmk_ptr = pAd->StaCfg.PMK;
546
 
                group_cipher = pAd->StaCfg.GroupCipher;
547
 
                rsnie_ptr = pAd->StaCfg.RSN_IE;
548
 
                rsnie_len = pAd->StaCfg.RSNIE_Len;
549
 
        }
550
 
 
551
 
        /* Store the received frame */
552
 
        pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
553
 
        MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
554
 
 
555
 
        /* Sanity Check peer Pairwise message 1 - Replay Counter */
556
 
        if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
557
 
            == FALSE)
558
 
                return;
559
 
 
560
 
        /* Store Replay counter, it will use to verify message 3 and construct message 2 */
561
 
        NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter,
562
 
                       LEN_KEY_DESC_REPLAY);
563
 
 
564
 
        /* Store ANonce */
565
 
        NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
566
 
                       LEN_KEY_DESC_NONCE);
567
 
 
568
 
        /* Generate random SNonce */
569
 
        GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);
570
 
 
571
 
        {
572
 
                /* Calculate PTK(ANonce, SNonce) */
573
 
                WpaDerivePTK(pAd,
574
 
                             pmk_ptr,
575
 
                             pEntry->ANonce,
576
 
                             pEntry->Addr,
577
 
                             pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);
578
 
 
579
 
                /* Save key to PTK entry */
580
 
                NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
581
 
        }
582
 
 
583
 
        /* Update WpaState */
584
 
        pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
585
 
 
586
 
        /* Construct EAPoL message - Pairwise Msg 2 */
587
 
        /*  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */
588
 
        NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
589
 
        ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0,    /* DefaultKeyIdx */
590
 
                          pEntry->SNonce, NULL, /* TxRsc */
591
 
                          NULL, /* GTK */
592
 
                          (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
593
 
 
594
 
        /* Make outgoing frame */
595
 
        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
596
 
 
597
 
        RTMPToWirelessSta(pAd, pEntry,
598
 
                          Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
599
 
                          CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
600
 
 
601
 
        DBGPRINT(RT_DEBUG_TRACE,
602
 
                 ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
603
 
}
604
 
 
605
 
/*
606
 
    ==========================================================================
607
 
    Description:
608
 
        When receiving the second packet of 4-way pairwisekey handshake.
609
 
    Return:
610
 
    ==========================================================================
611
 
*/
612
 
void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
613
 
                        struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
614
 
{
615
 
        u8 PTK[80];
616
 
        BOOLEAN Cancelled;
617
 
        struct rt_header_802_11 * pHeader;
618
 
        struct rt_eapol_packet EAPOLPKT;
619
 
        struct rt_eapol_packet * pMsg2;
620
 
        u32 MsgLen;
621
 
        u8 Header802_3[LENGTH_802_3];
622
 
        u8 TxTsc[6];
623
 
        u8 *pBssid = NULL;
624
 
        u8 *pmk_ptr = NULL;
625
 
        u8 *gtk_ptr = NULL;
626
 
        u8 default_key = 0;
627
 
        u8 group_cipher = Ndis802_11WEPDisabled;
628
 
        u8 *rsnie_ptr = NULL;
629
 
        u8 rsnie_len = 0;
630
 
 
631
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
632
 
 
633
 
        if ((!pEntry) || (!pEntry->ValidAsCLI))
634
 
                return;
635
 
 
636
 
        if (Elem->MsgLen <
637
 
            (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
638
 
             sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
639
 
                return;
640
 
 
641
 
        /* check Entry in valid State */
642
 
        if (pEntry->WpaState < AS_PTKSTART)
643
 
                return;
644
 
 
645
 
        /* pointer to 802.11 header */
646
 
        pHeader = (struct rt_header_802_11 *) Elem->Msg;
647
 
 
648
 
        /* skip 802.11_header(24-byte) and LLC_header(8) */
649
 
        pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
650
 
        MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
651
 
 
652
 
        /* Store SNonce */
653
 
        NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
654
 
                       LEN_KEY_DESC_NONCE);
655
 
 
656
 
        {
657
 
                /* Derive PTK */
658
 
                WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce,       /* ANONCE */
659
 
                             (u8 *) pBssid, pEntry->SNonce,     /* SNONCE */
660
 
                             pEntry->Addr, PTK, LEN_PTK);
661
 
 
662
 
                NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
663
 
        }
664
 
 
665
 
        /* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
666
 
        if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
667
 
            == FALSE)
668
 
                return;
669
 
 
670
 
        do {
671
 
                /* delete retry timer */
672
 
                RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
673
 
 
674
 
                /* Change state */
675
 
                pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
676
 
 
677
 
                /* Increment replay counter by 1 */
678
 
                ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
679
 
 
680
 
                /* Construct EAPoL message - Pairwise Msg 3 */
681
 
                NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
682
 
                ConstructEapolMsg(pEntry,
683
 
                                  group_cipher,
684
 
                                  EAPOL_PAIR_MSG_3,
685
 
                                  default_key,
686
 
                                  pEntry->ANonce,
687
 
                                  TxTsc,
688
 
                                  (u8 *) gtk_ptr,
689
 
                                  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
690
 
 
691
 
                /* Make outgoing frame */
692
 
                MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
693
 
                RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
694
 
                                  (u8 *)& EAPOLPKT,
695
 
                                  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
696
 
                                  (pEntry->PortSecured ==
697
 
                                   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
698
 
 
699
 
                pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
700
 
                RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
701
 
 
702
 
                /* Update State */
703
 
                pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
704
 
        } while (FALSE);
705
 
 
706
 
        DBGPRINT(RT_DEBUG_TRACE,
707
 
                 ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
708
 
}
709
 
 
710
 
/*
711
 
        ========================================================================
712
 
 
713
 
        Routine Description:
714
 
                Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
715
 
 
716
 
        Arguments:
717
 
                pAd     Pointer to our adapter
718
 
                Elem            Message body
719
 
 
720
 
        Return Value:
721
 
                None
722
 
 
723
 
        Note:
724
 
 
725
 
        ========================================================================
726
 
*/
727
 
void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
728
 
                        struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
729
 
{
730
 
        struct rt_header_802_11 * pHeader;
731
 
        u8 Header802_3[14];
732
 
        struct rt_eapol_packet EAPOLPKT;
733
 
        struct rt_eapol_packet * pMsg3;
734
 
        u32 MsgLen;
735
 
        u8 *pCurrentAddr = NULL;
736
 
        u8 group_cipher = Ndis802_11WEPDisabled;
737
 
 
738
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
739
 
 
740
 
        if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
741
 
                return;
742
 
 
743
 
        if (Elem->MsgLen <
744
 
            (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
745
 
             sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
746
 
                return;
747
 
 
748
 
        {
749
 
                pCurrentAddr = pAd->CurrentAddress;
750
 
                group_cipher = pAd->StaCfg.GroupCipher;
751
 
 
752
 
        }
753
 
 
754
 
        /* Record 802.11 header & the received EAPOL packet Msg3 */
755
 
        pHeader = (struct rt_header_802_11 *) Elem->Msg;
756
 
        pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
757
 
        MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
758
 
 
759
 
        /* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
760
 
        if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
761
 
            == FALSE)
762
 
                return;
763
 
 
764
 
        /* Save Replay counter, it will use construct message 4 */
765
 
        NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
766
 
                       LEN_KEY_DESC_REPLAY);
767
 
 
768
 
        /* Double check ANonce */
769
 
        if (!NdisEqualMemory
770
 
            (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
771
 
                return;
772
 
        }
773
 
        /* Construct EAPoL message - Pairwise Msg 4 */
774
 
        NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
775
 
        ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0,    /* group key index not used in message 4 */
776
 
                          NULL, /* Nonce not used in message 4 */
777
 
                          NULL, /* TxRSC not used in message 4 */
778
 
                          NULL, /* GTK not used in message 4 */
779
 
                          NULL, /* RSN IE not used in message 4 */
780
 
                          0, &EAPOLPKT);
781
 
 
782
 
        /* Update WpaState */
783
 
        pEntry->WpaState = AS_PTKINITDONE;
784
 
 
785
 
        /* Update pairwise key */
786
 
        {
787
 
                struct rt_cipher_key *pSharedKey;
788
 
 
789
 
                pSharedKey = &pAd->SharedKey[BSS0][0];
790
 
 
791
 
                NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
792
 
 
793
 
                /* Prepare pair-wise key information into shared key table */
794
 
                NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
795
 
                pSharedKey->KeyLen = LEN_TKIP_EK;
796
 
                NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32],
797
 
                               LEN_TKIP_EK);
798
 
                NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
799
 
                               LEN_TKIP_RXMICK);
800
 
                NdisMoveMemory(pSharedKey->TxMic,
801
 
                               &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
802
 
                               LEN_TKIP_TXMICK);
803
 
 
804
 
                /* Decide its ChiperAlg */
805
 
                if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
806
 
                        pSharedKey->CipherAlg = CIPHER_TKIP;
807
 
                else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
808
 
                        pSharedKey->CipherAlg = CIPHER_AES;
809
 
                else
810
 
                        pSharedKey->CipherAlg = CIPHER_NONE;
811
 
 
812
 
                /* Update these related information to struct rt_mac_table_entry */
813
 
                pEntry = &pAd->MacTab.Content[BSSID_WCID];
814
 
                NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
815
 
                               LEN_TKIP_EK);
816
 
                NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
817
 
                               LEN_TKIP_RXMICK);
818
 
                NdisMoveMemory(pEntry->PairwiseKey.TxMic,
819
 
                               &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
820
 
                               LEN_TKIP_TXMICK);
821
 
                pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
822
 
 
823
 
                /* Update pairwise key information to ASIC Shared Key Table */
824
 
                AsicAddSharedKeyEntry(pAd,
825
 
                                      BSS0,
826
 
                                      0,
827
 
                                      pSharedKey->CipherAlg,
828
 
                                      pSharedKey->Key,
829
 
                                      pSharedKey->TxMic, pSharedKey->RxMic);
830
 
 
831
 
                /* Update ASIC WCID attribute table and IVEIV table */
832
 
                RTMPAddWcidAttributeEntry(pAd,
833
 
                                          BSS0,
834
 
                                          0, pSharedKey->CipherAlg, pEntry);
835
 
 
836
 
        }
837
 
 
838
 
        /* open 802.1x port control and privacy filter */
839
 
        if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
840
 
            pEntry->AuthMode == Ndis802_11AuthModeWPA2) {
841
 
                pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
842
 
                pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
843
 
 
844
 
                STA_PORT_SECURED(pAd);
845
 
                /* Indicate Connected for GUI */
846
 
                pAd->IndicateMediaState = NdisMediaStateConnected;
847
 
                DBGPRINT(RT_DEBUG_TRACE,
848
 
                         ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
849
 
                          GetAuthMode(pEntry->AuthMode),
850
 
                          GetEncryptType(pEntry->WepStatus),
851
 
                          GetEncryptType(group_cipher)));
852
 
        } else {
853
 
        }
854
 
 
855
 
        /* Init 802.3 header and send out */
856
 
        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
857
 
        RTMPToWirelessSta(pAd, pEntry,
858
 
                          Header802_3, sizeof(Header802_3),
859
 
                          (u8 *)& EAPOLPKT,
860
 
                          CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
861
 
 
862
 
        DBGPRINT(RT_DEBUG_TRACE,
863
 
                 ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
864
 
}
865
 
 
866
 
/*
867
 
    ==========================================================================
868
 
    Description:
869
 
        When receiving the last packet of 4-way pairwisekey handshake.
870
 
        Initialize 2-way groupkey handshake following.
871
 
    Return:
872
 
    ==========================================================================
873
 
*/
874
 
void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
875
 
                        struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
876
 
{
877
 
        struct rt_eapol_packet * pMsg4;
878
 
        struct rt_header_802_11 * pHeader;
879
 
        u32 MsgLen;
880
 
        BOOLEAN Cancelled;
881
 
        u8 group_cipher = Ndis802_11WEPDisabled;
882
 
 
883
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
884
 
 
885
 
        do {
886
 
                if ((!pEntry) || (!pEntry->ValidAsCLI))
887
 
                        break;
888
 
 
889
 
                if (Elem->MsgLen <
890
 
                    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
891
 
                     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
892
 
                        break;
893
 
 
894
 
                if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
895
 
                        break;
896
 
 
897
 
                /* pointer to 802.11 header */
898
 
                pHeader = (struct rt_header_802_11 *) Elem->Msg;
899
 
 
900
 
                /* skip 802.11_header(24-byte) and LLC_header(8) */
901
 
                pMsg4 =
902
 
                    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
903
 
                MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
904
 
 
905
 
                /* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
906
 
                if (PeerWpaMessageSanity
907
 
                    (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
908
 
                        break;
909
 
 
910
 
                /* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
911
 
                NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));
912
 
 
913
 
                /* reset IVEIV in Asic */
914
 
                AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
915
 
 
916
 
                pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
917
 
                NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
918
 
                               LEN_TKIP_EK);
919
 
                NdisMoveMemory(pEntry->PairwiseKey.RxMic,
920
 
                               &pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
921
 
                               LEN_TKIP_RXMICK);
922
 
                NdisMoveMemory(pEntry->PairwiseKey.TxMic,
923
 
                               &pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
924
 
                               LEN_TKIP_TXMICK);
925
 
 
926
 
                /* Set pairwise key to Asic */
927
 
                {
928
 
                        pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
929
 
                        if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
930
 
                                pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
931
 
                        else if (pEntry->WepStatus ==
932
 
                                 Ndis802_11Encryption3Enabled)
933
 
                                pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
934
 
 
935
 
                        /* Add Pair-wise key to Asic */
936
 
                        AsicAddPairwiseKeyEntry(pAd,
937
 
                                                pEntry->Addr,
938
 
                                                (u8)pEntry->Aid,
939
 
                                                &pEntry->PairwiseKey);
940
 
 
941
 
                        /* update WCID attribute table and IVEIV table for this entry */
942
 
                        RTMPAddWcidAttributeEntry(pAd,
943
 
                                                  pEntry->apidx,
944
 
                                                  0,
945
 
                                                  pEntry->PairwiseKey.CipherAlg,
946
 
                                                  pEntry);
947
 
                }
948
 
 
949
 
                /* 4. upgrade state */
950
 
                pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
951
 
                pEntry->WpaState = AS_PTKINITDONE;
952
 
                pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
953
 
 
954
 
                if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
955
 
                    pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
956
 
                        pEntry->GTKState = REKEY_ESTABLISHED;
957
 
                        RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
958
 
 
959
 
                        /* send wireless event - for set key done WPA2 */
960
 
                        if (pAd->CommonCfg.bWirelessEvent)
961
 
                                RTMPSendWirelessEvent(pAd,
962
 
                                                      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
963
 
                                                      pEntry->Addr,
964
 
                                                      pEntry->apidx, 0);
965
 
 
966
 
                        DBGPRINT(RT_DEBUG_OFF,
967
 
                                 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
968
 
                                  pEntry->AuthMode,
969
 
                                  GetAuthMode(pEntry->AuthMode),
970
 
                                  pEntry->WepStatus,
971
 
                                  GetEncryptType(pEntry->WepStatus),
972
 
                                  group_cipher, GetEncryptType(group_cipher)));
973
 
                } else {
974
 
                        /* 5. init Group 2-way handshake if necessary. */
975
 
                        WPAStart2WayGroupHS(pAd, pEntry);
976
 
 
977
 
                        pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
978
 
                        RTMPModTimer(&pEntry->RetryTimer,
979
 
                                     PEER_MSG3_RETRY_EXEC_INTV);
980
 
                }
981
 
        } while (FALSE);
982
 
 
983
 
}
984
 
 
985
 
/*
986
 
    ==========================================================================
987
 
    Description:
988
 
        This is a function to send the first packet of 2-way groupkey handshake
989
 
    Return:
990
 
 
991
 
    ==========================================================================
992
 
*/
993
 
void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
994
 
{
995
 
        u8 Header802_3[14];
996
 
        u8 TxTsc[6];
997
 
        struct rt_eapol_packet EAPOLPKT;
998
 
        u8 group_cipher = Ndis802_11WEPDisabled;
999
 
        u8 default_key = 0;
1000
 
        u8 *gnonce_ptr = NULL;
1001
 
        u8 *gtk_ptr = NULL;
1002
 
        u8 *pBssid = NULL;
1003
 
 
1004
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
1005
 
 
1006
 
        if ((!pEntry) || (!pEntry->ValidAsCLI))
1007
 
                return;
1008
 
 
1009
 
        do {
1010
 
                /* Increment replay counter by 1 */
1011
 
                ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
1012
 
 
1013
 
                /* Construct EAPoL message - Group Msg 1 */
1014
 
                NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
1015
 
                ConstructEapolMsg(pEntry,
1016
 
                                  group_cipher,
1017
 
                                  EAPOL_GROUP_MSG_1,
1018
 
                                  default_key,
1019
 
                                  (u8 *) gnonce_ptr,
1020
 
                                  TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);
1021
 
 
1022
 
                /* Make outgoing frame */
1023
 
                MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
1024
 
                RTMPToWirelessSta(pAd, pEntry,
1025
 
                                  Header802_3, LENGTH_802_3,
1026
 
                                  (u8 *)& EAPOLPKT,
1027
 
                                  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
1028
 
                                  FALSE);
1029
 
 
1030
 
        } while (FALSE);
1031
 
 
1032
 
        DBGPRINT(RT_DEBUG_TRACE,
1033
 
                 ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
1034
 
 
1035
 
        return;
1036
 
}
1037
 
 
1038
 
/*
1039
 
        ========================================================================
1040
 
 
1041
 
        Routine Description:
1042
 
                Process Group key 2-way handshaking
1043
 
 
1044
 
        Arguments:
1045
 
                pAd     Pointer to our adapter
1046
 
                Elem            Message body
1047
 
 
1048
 
        Return Value:
1049
 
                None
1050
 
 
1051
 
        Note:
1052
 
 
1053
 
        ========================================================================
1054
 
*/
1055
 
void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
1056
 
                         struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
1057
 
{
1058
 
        u8 Header802_3[14];
1059
 
        struct rt_eapol_packet EAPOLPKT;
1060
 
        struct rt_eapol_packet * pGroup;
1061
 
        u32 MsgLen;
1062
 
        BOOLEAN Cancelled;
1063
 
        u8 default_key = 0;
1064
 
        u8 group_cipher = Ndis802_11WEPDisabled;
1065
 
        u8 *pCurrentAddr = NULL;
1066
 
 
1067
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
1068
 
 
1069
 
        if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
1070
 
                return;
1071
 
 
1072
 
        {
1073
 
                pCurrentAddr = pAd->CurrentAddress;
1074
 
                group_cipher = pAd->StaCfg.GroupCipher;
1075
 
                default_key = pAd->StaCfg.DefaultKeyId;
1076
 
        }
1077
 
 
1078
 
        /* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */
1079
 
        pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1080
 
        MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
1081
 
 
1082
 
        /* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
1083
 
        if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
1084
 
            == FALSE)
1085
 
                return;
1086
 
 
1087
 
        /* delete retry timer */
1088
 
        RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1089
 
 
1090
 
        /* Save Replay counter, it will use to construct message 2 */
1091
 
        NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
1092
 
                       LEN_KEY_DESC_REPLAY);
1093
 
 
1094
 
        /* Construct EAPoL message - Group Msg 2 */
1095
 
        NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
1096
 
        ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL,   /* Nonce not used */
1097
 
                          NULL, /* TxRSC not used */
1098
 
                          NULL, /* GTK not used */
1099
 
                          NULL, /* RSN IE not used */
1100
 
                          0, &EAPOLPKT);
1101
 
 
1102
 
        /* open 802.1x port control and privacy filter */
1103
 
        pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1104
 
        pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1105
 
 
1106
 
        STA_PORT_SECURED(pAd);
1107
 
        /* Indicate Connected for GUI */
1108
 
        pAd->IndicateMediaState = NdisMediaStateConnected;
1109
 
 
1110
 
        DBGPRINT(RT_DEBUG_TRACE,
1111
 
                 ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
1112
 
                  GetAuthMode(pEntry->AuthMode),
1113
 
                  GetEncryptType(pEntry->WepStatus),
1114
 
                  GetEncryptType(group_cipher)));
1115
 
 
1116
 
        /* init header and Fill Packet and send Msg 2 to authenticator */
1117
 
        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
1118
 
        RTMPToWirelessSta(pAd, pEntry,
1119
 
                          Header802_3, sizeof(Header802_3),
1120
 
                          (u8 *)& EAPOLPKT,
1121
 
                          CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);
1122
 
 
1123
 
        DBGPRINT(RT_DEBUG_TRACE,
1124
 
                 ("<=== PeerGroupMsg1Action: sned group message 2\n"));
1125
 
}
1126
 
 
1127
 
/*
1128
 
    ==========================================================================
1129
 
    Description:
1130
 
        When receiving the last packet of 2-way groupkey handshake.
1131
 
    Return:
1132
 
    ==========================================================================
1133
 
*/
1134
 
void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
1135
 
                         struct rt_mac_table_entry *pEntry,
1136
 
                         void * Msg, u32 MsgLen)
1137
 
{
1138
 
        u32 Len;
1139
 
        u8 *pData;
1140
 
        BOOLEAN Cancelled;
1141
 
        struct rt_eapol_packet * pMsg2;
1142
 
        u8 group_cipher = Ndis802_11WEPDisabled;
1143
 
 
1144
 
        DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
1145
 
 
1146
 
        do {
1147
 
                if ((!pEntry) || (!pEntry->ValidAsCLI))
1148
 
                        break;
1149
 
 
1150
 
                if (MsgLen <
1151
 
                    (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
1152
 
                     MAX_LEN_OF_RSNIE - 2))
1153
 
                        break;
1154
 
 
1155
 
                if (pEntry->WpaState != AS_PTKINITDONE)
1156
 
                        break;
1157
 
 
1158
 
                pData = (u8 *)Msg;
1159
 
                pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
1160
 
                Len = MsgLen - LENGTH_802_1_H;
1161
 
 
1162
 
                /* Sanity Check peer group message 2 - Replay Counter, MIC */
1163
 
                if (PeerWpaMessageSanity
1164
 
                    (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
1165
 
                        break;
1166
 
 
1167
 
                /* 3.  upgrade state */
1168
 
 
1169
 
                RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1170
 
                pEntry->GTKState = REKEY_ESTABLISHED;
1171
 
 
1172
 
                if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
1173
 
                    || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) {
1174
 
                        /* send wireless event - for set key done WPA2 */
1175
 
                        if (pAd->CommonCfg.bWirelessEvent)
1176
 
                                RTMPSendWirelessEvent(pAd,
1177
 
                                                      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
1178
 
                                                      pEntry->Addr,
1179
 
                                                      pEntry->apidx, 0);
1180
 
 
1181
 
                        DBGPRINT(RT_DEBUG_OFF,
1182
 
                                 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1183
 
                                  pEntry->AuthMode,
1184
 
                                  GetAuthMode(pEntry->AuthMode),
1185
 
                                  pEntry->WepStatus,
1186
 
                                  GetEncryptType(pEntry->WepStatus),
1187
 
                                  group_cipher, GetEncryptType(group_cipher)));
1188
 
                } else {
1189
 
                        /* send wireless event - for set key done WPA */
1190
 
                        if (pAd->CommonCfg.bWirelessEvent)
1191
 
                                RTMPSendWirelessEvent(pAd,
1192
 
                                                      IW_SET_KEY_DONE_WPA1_EVENT_FLAG,
1193
 
                                                      pEntry->Addr,
1194
 
                                                      pEntry->apidx, 0);
1195
 
 
1196
 
                        DBGPRINT(RT_DEBUG_OFF,
1197
 
                                 ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1198
 
                                  pEntry->AuthMode,
1199
 
                                  GetAuthMode(pEntry->AuthMode),
1200
 
                                  pEntry->WepStatus,
1201
 
                                  GetEncryptType(pEntry->WepStatus),
1202
 
                                  group_cipher, GetEncryptType(group_cipher)));
1203
 
                }
1204
 
        } while (FALSE);
1205
 
}
1206
 
 
1207
 
/*
1208
 
        ========================================================================
1209
 
 
1210
 
        Routine Description:
1211
 
                Classify WPA EAP message type
1212
 
 
1213
 
        Arguments:
1214
 
                EAPType         Value of EAP message type
1215
 
                MsgType         Internal Message definition for MLME state machine
1216
 
 
1217
 
        Return Value:
1218
 
                TRUE            Found appropriate message type
1219
 
                FALSE           No appropriate message type
1220
 
 
1221
 
        IRQL = DISPATCH_LEVEL
1222
 
 
1223
 
        Note:
1224
 
                All these constants are defined in wpa.h
1225
 
                For supplicant, there is only EAPOL Key message available
1226
 
 
1227
 
        ========================================================================
1228
 
*/
1229
 
BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
1230
 
{
1231
 
        switch (EAPType) {
1232
 
        case EAPPacket:
1233
 
                *MsgType = MT2_EAPPacket;
1234
 
                break;
1235
 
        case EAPOLStart:
1236
 
                *MsgType = MT2_EAPOLStart;
1237
 
                break;
1238
 
        case EAPOLLogoff:
1239
 
                *MsgType = MT2_EAPOLLogoff;
1240
 
                break;
1241
 
        case EAPOLKey:
1242
 
                *MsgType = MT2_EAPOLKey;
1243
 
                break;
1244
 
        case EAPOLASFAlert:
1245
 
                *MsgType = MT2_EAPOLASFAlert;
1246
 
                break;
1247
 
        default:
1248
 
                return FALSE;
1249
 
        }
1250
 
        return TRUE;
1251
 
}
1252
 
 
1253
 
/*
1254
 
        ========================================================================
1255
 
 
1256
 
        Routine Description:
1257
 
                The pseudo-random function(PRF) that hashes various inputs to
1258
 
                derive a pseudo-random value. To add liveness to the pseudo-random
1259
 
                value, a nonce should be one of the inputs.
1260
 
 
1261
 
                It is used to generate PTK, GTK or some specific random value.
1262
 
 
1263
 
        Arguments:
1264
 
                u8      *key,           -       the key material for HMAC_SHA1 use
1265
 
                int             key_len         -       the length of key
1266
 
                u8      *prefix         -       a prefix label
1267
 
                int             prefix_len      -       the length of the label
1268
 
                u8      *data           -       a specific data with variable length
1269
 
                int             data_len        -       the length of a specific data
1270
 
                int             len                     -       the output length
1271
 
 
1272
 
        Return Value:
1273
 
                u8      *output         -       the calculated result
1274
 
 
1275
 
        Note:
1276
 
                802.11i-2004    Annex H.3
1277
 
 
1278
 
        ========================================================================
1279
 
*/
1280
 
void PRF(u8 * key,
1281
 
         int key_len,
1282
 
         u8 * prefix,
1283
 
         int prefix_len,
1284
 
         u8 * data, int data_len, u8 * output, int len)
1285
 
{
1286
 
        int i;
1287
 
        u8 *input;
1288
 
        int currentindex = 0;
1289
 
        int total_len;
1290
 
 
1291
 
        /* Allocate memory for input */
1292
 
        os_alloc_mem(NULL, (u8 **) & input, 1024);
1293
 
 
1294
 
        if (input == NULL) {
1295
 
                DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
1296
 
                return;
1297
 
        }
1298
 
        /* Generate concatenation input */
1299
 
        NdisMoveMemory(input, prefix, prefix_len);
1300
 
 
1301
 
        /* Concatenate a single octet containing 0 */
1302
 
        input[prefix_len] = 0;
1303
 
 
1304
 
        /* Concatenate specific data */
1305
 
        NdisMoveMemory(&input[prefix_len + 1], data, data_len);
1306
 
        total_len = prefix_len + 1 + data_len;
1307
 
 
1308
 
        /* Concatenate a single octet containing 0 */
1309
 
        /* This octet shall be update later */
1310
 
        input[total_len] = 0;
1311
 
        total_len++;
1312
 
 
1313
 
        /* Iterate to calculate the result by hmac-sha-1 */
1314
 
        /* Then concatenate to last result */
1315
 
        for (i = 0; i < (len + 19) / 20; i++) {
1316
 
                HMAC_SHA1(key, key_len, input, total_len, &output[currentindex],
1317
 
                          SHA1_DIGEST_SIZE);
1318
 
                currentindex += 20;
1319
 
 
1320
 
                /* update the last octet */
1321
 
                input[total_len - 1]++;
1322
 
        }
1323
 
        os_free_mem(NULL, input);
1324
 
}
1325
 
 
1326
 
/*
1327
 
* F(P, S, c, i) = U1 xor U2 xor ... Uc
1328
 
* U1 = PRF(P, S || Int(i))
1329
 
* U2 = PRF(P, U1)
1330
 
* Uc = PRF(P, Uc-1)
1331
 
*/
1332
 
 
1333
 
static void F(char *password, unsigned char *ssid, int ssidlength,
1334
 
              int iterations, int count, unsigned char *output)
1335
 
{
1336
 
        unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
1337
 
        int i, j;
1338
 
 
1339
 
        /* U1 = PRF(P, S || int(i)) */
1340
 
        memcpy(digest, ssid, ssidlength);
1341
 
        digest[ssidlength] = (unsigned char)((count >> 24) & 0xff);
1342
 
        digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff);
1343
 
        digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff);
1344
 
        digest[ssidlength + 3] = (unsigned char)(count & 0xff);
1345
 
        HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE); /* for WPA update */
1346
 
 
1347
 
        /* output = U1 */
1348
 
        memcpy(output, digest1, SHA1_DIGEST_SIZE);
1349
 
 
1350
 
        for (i = 1; i < iterations; i++) {
1351
 
                /* Un = PRF(P, Un-1) */
1352
 
                HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE);       /* for WPA update */
1353
 
                memcpy(digest1, digest, SHA1_DIGEST_SIZE);
1354
 
 
1355
 
                /* output = output xor Un */
1356
 
                for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1357
 
                        output[j] ^= digest[j];
1358
 
                }
1359
 
        }
1360
 
}
1361
 
 
1362
 
/*
1363
 
* password - ascii string up to 63 characters in length
1364
 
* ssid - octet string up to 32 octets
1365
 
* ssidlength - length of ssid in octets
1366
 
* output must be 40 octets in length and outputs 256 bits of key
1367
 
*/
1368
 
int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
1369
 
{
1370
 
        if ((strlen(password) > 63) || (ssidlength > 32))
1371
 
                return 0;
1372
 
 
1373
 
        F(password, ssid, ssidlength, 4096, 1, output);
1374
 
        F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
1375
 
        return 1;
1376
 
}
1377
 
 
1378
 
/*
1379
 
        ========================================================================
1380
 
 
1381
 
        Routine Description:
1382
 
                It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
1383
 
                It shall be called by 4-way handshake processing.
1384
 
 
1385
 
        Arguments:
1386
 
                pAd     -       pointer to our pAdapter context
1387
 
                PMK             -       pointer to PMK
1388
 
                ANonce  -       pointer to ANonce
1389
 
                AA              -       pointer to Authenticator Address
1390
 
                SNonce  -       pointer to SNonce
1391
 
                SA              -       pointer to Supplicant Address
1392
 
                len             -       indicate the length of PTK (octet)
1393
 
 
1394
 
        Return Value:
1395
 
                Output          pointer to the PTK
1396
 
 
1397
 
        Note:
1398
 
                Refer to IEEE 802.11i-2004 8.5.1.2
1399
 
 
1400
 
        ========================================================================
1401
 
*/
1402
 
void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
1403
 
                  u8 * PMK,
1404
 
                  u8 * ANonce,
1405
 
                  u8 * AA,
1406
 
                  u8 * SNonce,
1407
 
                  u8 * SA, u8 * output, u32 len)
1408
 
{
1409
 
        u8 concatenation[76];
1410
 
        u32 CurrPos = 0;
1411
 
        u8 temp[32];
1412
 
        u8 Prefix[] =
1413
 
            { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
1414
 
                'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
1415
 
        };
1416
 
 
1417
 
        /* initiate the concatenation input */
1418
 
        NdisZeroMemory(temp, sizeof(temp));
1419
 
        NdisZeroMemory(concatenation, 76);
1420
 
 
1421
 
        /* Get smaller address */
1422
 
        if (RTMPCompareMemory(SA, AA, 6) == 1)
1423
 
                NdisMoveMemory(concatenation, AA, 6);
1424
 
        else
1425
 
                NdisMoveMemory(concatenation, SA, 6);
1426
 
        CurrPos += 6;
1427
 
 
1428
 
        /* Get larger address */
1429
 
        if (RTMPCompareMemory(SA, AA, 6) == 1)
1430
 
                NdisMoveMemory(&concatenation[CurrPos], SA, 6);
1431
 
        else
1432
 
                NdisMoveMemory(&concatenation[CurrPos], AA, 6);
1433
 
 
1434
 
        /* store the larger mac address for backward compatible of */
1435
 
        /* ralink proprietary STA-key issue */
1436
 
        NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
1437
 
        CurrPos += 6;
1438
 
 
1439
 
        /* Get smaller Nonce */
1440
 
        if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
1441
 
                NdisMoveMemory(&concatenation[CurrPos], temp, 32);      /* patch for ralink proprietary STA-key issue */
1442
 
        else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
1443
 
                NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
1444
 
        else
1445
 
                NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
1446
 
        CurrPos += 32;
1447
 
 
1448
 
        /* Get larger Nonce */
1449
 
        if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
1450
 
                NdisMoveMemory(&concatenation[CurrPos], temp, 32);      /* patch for ralink proprietary STA-key issue */
1451
 
        else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
1452
 
                NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
1453
 
        else
1454
 
                NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
1455
 
        CurrPos += 32;
1456
 
 
1457
 
        hex_dump("concatenation=", concatenation, 76);
1458
 
 
1459
 
        /* Use PRF to generate PTK */
1460
 
        PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
1461
 
 
1462
 
}
1463
 
 
1464
 
/*
1465
 
        ========================================================================
1466
 
 
1467
 
        Routine Description:
1468
 
                Generate random number by software.
1469
 
 
1470
 
        Arguments:
1471
 
                pAd             -       pointer to our pAdapter context
1472
 
                macAddr -       pointer to local MAC address
1473
 
 
1474
 
        Return Value:
1475
 
 
1476
 
        Note:
1477
 
                802.1ii-2004  Annex H.5
1478
 
 
1479
 
        ========================================================================
1480
 
*/
1481
 
void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
1482
 
{
1483
 
        int i, curr;
1484
 
        u8 local[80], KeyCounter[32];
1485
 
        u8 result[80];
1486
 
        unsigned long CurrentTime;
1487
 
        u8 prefix[] =
1488
 
            { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };
1489
 
 
1490
 
        /* Zero the related information */
1491
 
        NdisZeroMemory(result, 80);
1492
 
        NdisZeroMemory(local, 80);
1493
 
        NdisZeroMemory(KeyCounter, 32);
1494
 
 
1495
 
        for (i = 0; i < 32; i++) {
1496
 
                /* copy the local MAC address */
1497
 
                COPY_MAC_ADDR(local, macAddr);
1498
 
                curr = MAC_ADDR_LEN;
1499
 
 
1500
 
                /* concatenate the current time */
1501
 
                NdisGetSystemUpTime(&CurrentTime);
1502
 
                NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
1503
 
                curr += sizeof(CurrentTime);
1504
 
 
1505
 
                /* concatenate the last result */
1506
 
                NdisMoveMemory(&local[curr], result, 32);
1507
 
                curr += 32;
1508
 
 
1509
 
                /* concatenate a variable */
1510
 
                NdisMoveMemory(&local[curr], &i, 2);
1511
 
                curr += 2;
1512
 
 
1513
 
                /* calculate the result */
1514
 
                PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
1515
 
        }
1516
 
 
1517
 
        NdisMoveMemory(random, result, 32);
1518
 
}
1519
 
 
1520
 
/*
1521
 
        ========================================================================
1522
 
 
1523
 
        Routine Description:
1524
 
                Build cipher suite in RSN-IE.
1525
 
                It only shall be called by RTMPMakeRSNIE.
1526
 
 
1527
 
        Arguments:
1528
 
                pAd                     -       pointer to our pAdapter context
1529
 
        ElementID       -       indicate the WPA1 or WPA2
1530
 
        WepStatus       -       indicate the encryption type
1531
 
                bMixCipher      -       a boolean to indicate the pairwise cipher and group
1532
 
                                                cipher are the same or not
1533
 
 
1534
 
        Return Value:
1535
 
 
1536
 
        Note:
1537
 
 
1538
 
        ========================================================================
1539
 
*/
1540
 
static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
1541
 
                                u8 ElementID,
1542
 
                                u32 WepStatus,
1543
 
                                IN BOOLEAN bMixCipher,
1544
 
                                u8 FlexibleCipher,
1545
 
                                u8 *pRsnIe, u8 * rsn_len)
1546
 
{
1547
 
        u8 PairwiseCnt;
1548
 
 
1549
 
        *rsn_len = 0;
1550
 
 
1551
 
        /* decide WPA2 or WPA1 */
1552
 
        if (ElementID == Wpa2Ie) {
1553
 
                struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;
1554
 
 
1555
 
                /* Assign the verson as 1 */
1556
 
                pRsnie_cipher->version = 1;
1557
 
 
1558
 
                switch (WepStatus) {
1559
 
                        /* TKIP mode */
1560
 
                case Ndis802_11Encryption2Enabled:
1561
 
                        NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
1562
 
                        pRsnie_cipher->ucount = 1;
1563
 
                        NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1564
 
                                       OUI_WPA2_TKIP, 4);
1565
 
                        *rsn_len = sizeof(struct rt_rsnie2);
1566
 
                        break;
1567
 
 
1568
 
                        /* AES mode */
1569
 
                case Ndis802_11Encryption3Enabled:
1570
 
                        if (bMixCipher)
1571
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1572
 
                                               OUI_WPA2_TKIP, 4);
1573
 
                        else
1574
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1575
 
                                               OUI_WPA2_CCMP, 4);
1576
 
                        pRsnie_cipher->ucount = 1;
1577
 
                        NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1578
 
                                       OUI_WPA2_CCMP, 4);
1579
 
                        *rsn_len = sizeof(struct rt_rsnie2);
1580
 
                        break;
1581
 
 
1582
 
                        /* TKIP-AES mix mode */
1583
 
                case Ndis802_11Encryption4Enabled:
1584
 
                        NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
1585
 
 
1586
 
                        PairwiseCnt = 1;
1587
 
                        /* Insert WPA2 TKIP as the first pairwise cipher */
1588
 
                        if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
1589
 
                                NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1590
 
                                               OUI_WPA2_TKIP, 4);
1591
 
                                /* Insert WPA2 AES as the secondary pairwise cipher */
1592
 
                                if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) {
1593
 
                                        NdisMoveMemory(pRsnie_cipher->ucast[0].
1594
 
                                                       oui + 4, OUI_WPA2_CCMP,
1595
 
                                                       4);
1596
 
                                        PairwiseCnt = 2;
1597
 
                                }
1598
 
                        } else {
1599
 
                                /* Insert WPA2 AES as the first pairwise cipher */
1600
 
                                NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1601
 
                                               OUI_WPA2_CCMP, 4);
1602
 
                        }
1603
 
 
1604
 
                        pRsnie_cipher->ucount = PairwiseCnt;
1605
 
                        *rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
1606
 
                        break;
1607
 
                }
1608
 
 
1609
 
                if ((pAd->OpMode == OPMODE_STA) &&
1610
 
                    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
1611
 
                    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
1612
 
                        u32 GroupCipher = pAd->StaCfg.GroupCipher;
1613
 
                        switch (GroupCipher) {
1614
 
                        case Ndis802_11GroupWEP40Enabled:
1615
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1616
 
                                               OUI_WPA2_WEP40, 4);
1617
 
                                break;
1618
 
                        case Ndis802_11GroupWEP104Enabled:
1619
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1620
 
                                               OUI_WPA2_WEP104, 4);
1621
 
                                break;
1622
 
                        }
1623
 
                }
1624
 
                /* swap for big-endian platform */
1625
 
                pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1626
 
                pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1627
 
        } else {
1628
 
                struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;
1629
 
 
1630
 
                /* Assign OUI and version */
1631
 
                NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
1632
 
                pRsnie_cipher->version = 1;
1633
 
 
1634
 
                switch (WepStatus) {
1635
 
                        /* TKIP mode */
1636
 
                case Ndis802_11Encryption2Enabled:
1637
 
                        NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
1638
 
                        pRsnie_cipher->ucount = 1;
1639
 
                        NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1640
 
                                       OUI_WPA_TKIP, 4);
1641
 
                        *rsn_len = sizeof(struct rt_rsnie);
1642
 
                        break;
1643
 
 
1644
 
                        /* AES mode */
1645
 
                case Ndis802_11Encryption3Enabled:
1646
 
                        if (bMixCipher)
1647
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1648
 
                                               OUI_WPA_TKIP, 4);
1649
 
                        else
1650
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1651
 
                                               OUI_WPA_CCMP, 4);
1652
 
                        pRsnie_cipher->ucount = 1;
1653
 
                        NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1654
 
                                       OUI_WPA_CCMP, 4);
1655
 
                        *rsn_len = sizeof(struct rt_rsnie);
1656
 
                        break;
1657
 
 
1658
 
                        /* TKIP-AES mix mode */
1659
 
                case Ndis802_11Encryption4Enabled:
1660
 
                        NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
1661
 
 
1662
 
                        PairwiseCnt = 1;
1663
 
                        /* Insert WPA TKIP as the first pairwise cipher */
1664
 
                        if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
1665
 
                                NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1666
 
                                               OUI_WPA_TKIP, 4);
1667
 
                                /* Insert WPA AES as the secondary pairwise cipher */
1668
 
                                if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) {
1669
 
                                        NdisMoveMemory(pRsnie_cipher->ucast[0].
1670
 
                                                       oui + 4, OUI_WPA_CCMP,
1671
 
                                                       4);
1672
 
                                        PairwiseCnt = 2;
1673
 
                                }
1674
 
                        } else {
1675
 
                                /* Insert WPA AES as the first pairwise cipher */
1676
 
                                NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1677
 
                                               OUI_WPA_CCMP, 4);
1678
 
                        }
1679
 
 
1680
 
                        pRsnie_cipher->ucount = PairwiseCnt;
1681
 
                        *rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
1682
 
                        break;
1683
 
                }
1684
 
 
1685
 
                if ((pAd->OpMode == OPMODE_STA) &&
1686
 
                    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
1687
 
                    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
1688
 
                        u32 GroupCipher = pAd->StaCfg.GroupCipher;
1689
 
                        switch (GroupCipher) {
1690
 
                        case Ndis802_11GroupWEP40Enabled:
1691
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1692
 
                                               OUI_WPA_WEP40, 4);
1693
 
                                break;
1694
 
                        case Ndis802_11GroupWEP104Enabled:
1695
 
                                NdisMoveMemory(pRsnie_cipher->mcast,
1696
 
                                               OUI_WPA_WEP104, 4);
1697
 
                                break;
1698
 
                        }
1699
 
                }
1700
 
                /* swap for big-endian platform */
1701
 
                pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1702
 
                pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1703
 
        }
1704
 
}
1705
 
 
1706
 
/*
1707
 
        ========================================================================
1708
 
 
1709
 
        Routine Description:
1710
 
                Build AKM suite in RSN-IE.
1711
 
                It only shall be called by RTMPMakeRSNIE.
1712
 
 
1713
 
        Arguments:
1714
 
                pAd                     -       pointer to our pAdapter context
1715
 
        ElementID       -       indicate the WPA1 or WPA2
1716
 
        AuthMode        -       indicate the authentication mode
1717
 
                apidx           -       indicate the interface index
1718
 
 
1719
 
        Return Value:
1720
 
 
1721
 
        Note:
1722
 
 
1723
 
        ========================================================================
1724
 
*/
1725
 
static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
1726
 
                             u8 ElementID,
1727
 
                             u32 AuthMode,
1728
 
                             u8 apidx,
1729
 
                             u8 *pRsnIe, u8 * rsn_len)
1730
 
{
1731
 
        struct rt_rsnie_auth *pRsnie_auth;
1732
 
        u8 AkmCnt = 1;  /* default as 1 */
1733
 
 
1734
 
        pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));
1735
 
 
1736
 
        /* decide WPA2 or WPA1 */
1737
 
        if (ElementID == Wpa2Ie) {
1738
 
 
1739
 
                switch (AuthMode) {
1740
 
                case Ndis802_11AuthModeWPA2:
1741
 
                case Ndis802_11AuthModeWPA1WPA2:
1742
 
                        NdisMoveMemory(pRsnie_auth->auth[0].oui,
1743
 
                                       OUI_WPA2_8021X_AKM, 4);
1744
 
                        break;
1745
 
 
1746
 
                case Ndis802_11AuthModeWPA2PSK:
1747
 
                case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1748
 
                        NdisMoveMemory(pRsnie_auth->auth[0].oui,
1749
 
                                       OUI_WPA2_PSK_AKM, 4);
1750
 
                        break;
1751
 
                default:
1752
 
                        AkmCnt = 0;
1753
 
                        break;
1754
 
 
1755
 
                }
1756
 
        } else {
1757
 
                switch (AuthMode) {
1758
 
                case Ndis802_11AuthModeWPA:
1759
 
                case Ndis802_11AuthModeWPA1WPA2:
1760
 
                        NdisMoveMemory(pRsnie_auth->auth[0].oui,
1761
 
                                       OUI_WPA_8021X_AKM, 4);
1762
 
                        break;
1763
 
 
1764
 
                case Ndis802_11AuthModeWPAPSK:
1765
 
                case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1766
 
                        NdisMoveMemory(pRsnie_auth->auth[0].oui,
1767
 
                                       OUI_WPA_PSK_AKM, 4);
1768
 
                        break;
1769
 
 
1770
 
                case Ndis802_11AuthModeWPANone:
1771
 
                        NdisMoveMemory(pRsnie_auth->auth[0].oui,
1772
 
                                       OUI_WPA_NONE_AKM, 4);
1773
 
                        break;
1774
 
                default:
1775
 
                        AkmCnt = 0;
1776
 
                        break;
1777
 
                }
1778
 
        }
1779
 
 
1780
 
        pRsnie_auth->acount = AkmCnt;
1781
 
        pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
1782
 
 
1783
 
        /* update current RSNIE length */
1784
 
        (*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));
1785
 
 
1786
 
}
1787
 
 
1788
 
/*
1789
 
        ========================================================================
1790
 
 
1791
 
        Routine Description:
1792
 
                Build capability in RSN-IE.
1793
 
                It only shall be called by RTMPMakeRSNIE.
1794
 
 
1795
 
        Arguments:
1796
 
                pAd                     -       pointer to our pAdapter context
1797
 
        ElementID       -       indicate the WPA1 or WPA2
1798
 
                apidx           -       indicate the interface index
1799
 
 
1800
 
        Return Value:
1801
 
 
1802
 
        Note:
1803
 
 
1804
 
        ========================================================================
1805
 
*/
1806
 
static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
1807
 
                             u8 ElementID,
1808
 
                             u8 apidx,
1809
 
                             u8 *pRsnIe, u8 * rsn_len)
1810
 
{
1811
 
        RSN_CAPABILITIES *pRSN_Cap;
1812
 
 
1813
 
        /* it could be ignored in WPA1 mode */
1814
 
        if (ElementID == WpaIe)
1815
 
                return;
1816
 
 
1817
 
        pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));
1818
 
 
1819
 
        pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
1820
 
 
1821
 
        (*rsn_len) += sizeof(RSN_CAPABILITIES); /* update current RSNIE length */
1822
 
 
1823
 
}
1824
 
 
1825
 
/*
1826
 
        ========================================================================
1827
 
 
1828
 
        Routine Description:
1829
 
                Build RSN IE context. It is not included element-ID and length.
1830
 
 
1831
 
        Arguments:
1832
 
                pAd                     -       pointer to our pAdapter context
1833
 
        AuthMode        -       indicate the authentication mode
1834
 
        WepStatus       -       indicate the encryption type
1835
 
                apidx           -       indicate the interface index
1836
 
 
1837
 
        Return Value:
1838
 
 
1839
 
        Note:
1840
 
 
1841
 
        ========================================================================
1842
 
*/
1843
 
void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
1844
 
                   u32 AuthMode, u32 WepStatus, u8 apidx)
1845
 
{
1846
 
        u8 *pRsnIe = NULL;      /* primary RSNIE */
1847
 
        u8 *rsnielen_cur_p = 0; /* the length of the primary RSNIE */
1848
 
        u8 *rsnielen_ex_cur_p = 0;      /* the length of the secondary RSNIE */
1849
 
        u8 PrimaryRsnie;
1850
 
        BOOLEAN bMixCipher = FALSE;     /* indicate the pairwise and group cipher are different */
1851
 
        u8 p_offset;
1852
 
        WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;  /* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */
1853
 
 
1854
 
        rsnielen_cur_p = NULL;
1855
 
        rsnielen_ex_cur_p = NULL;
1856
 
 
1857
 
        {
1858
 
                {
1859
 
                        if (pAd->StaCfg.WpaSupplicantUP !=
1860
 
                            WPA_SUPPLICANT_DISABLE) {
1861
 
                                if (AuthMode < Ndis802_11AuthModeWPA)
1862
 
                                        return;
1863
 
                        } else {
1864
 
                                /* Support WPAPSK or WPA2PSK in STA-Infra mode */
1865
 
                                /* Support WPANone in STA-Adhoc mode */
1866
 
                                if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
1867
 
                                    (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1868
 
                                    (AuthMode != Ndis802_11AuthModeWPANone)
1869
 
                                    )
1870
 
                                        return;
1871
 
                        }
1872
 
 
1873
 
                        DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));
1874
 
 
1875
 
                        /* Zero RSNIE context */
1876
 
                        pAd->StaCfg.RSNIE_Len = 0;
1877
 
                        NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
1878
 
 
1879
 
                        /* Pointer to RSNIE */
1880
 
                        rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
1881
 
                        pRsnIe = pAd->StaCfg.RSN_IE;
1882
 
 
1883
 
                        bMixCipher = pAd->StaCfg.bMixCipher;
1884
 
                }
1885
 
        }
1886
 
 
1887
 
        /* indicate primary RSNIE as WPA or WPA2 */
1888
 
        if ((AuthMode == Ndis802_11AuthModeWPA) ||
1889
 
            (AuthMode == Ndis802_11AuthModeWPAPSK) ||
1890
 
            (AuthMode == Ndis802_11AuthModeWPANone) ||
1891
 
            (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
1892
 
            (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
1893
 
                PrimaryRsnie = WpaIe;
1894
 
        else
1895
 
                PrimaryRsnie = Wpa2Ie;
1896
 
 
1897
 
        {
1898
 
                /* Build the primary RSNIE */
1899
 
                /* 1. insert cipher suite */
1900
 
                RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
1901
 
                                    FlexibleCipher, pRsnIe, &p_offset);
1902
 
 
1903
 
                /* 2. insert AKM */
1904
 
                RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
1905
 
                                 &p_offset);
1906
 
 
1907
 
                /* 3. insert capability */
1908
 
                RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
1909
 
        }
1910
 
 
1911
 
        /* 4. update the RSNIE length */
1912
 
        *rsnielen_cur_p = p_offset;
1913
 
 
1914
 
        hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
1915
 
 
1916
 
}
1917
 
 
1918
 
/*
1919
 
    ==========================================================================
1920
 
    Description:
1921
 
                Check whether the received frame is EAP frame.
1922
 
 
1923
 
        Arguments:
1924
 
                pAd                             -       pointer to our pAdapter context
1925
 
                pEntry                  -       pointer to active entry
1926
 
                pData                   -       the received frame
1927
 
                DataByteCount   -       the received frame's length
1928
 
                FromWhichBSSID  -       indicate the interface index
1929
 
 
1930
 
    Return:
1931
 
         TRUE                   -       This frame is EAP frame
1932
 
         FALSE                  -       otherwise
1933
 
    ==========================================================================
1934
 
*/
1935
 
BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
1936
 
                          struct rt_mac_table_entry *pEntry,
1937
 
                          u8 *pData,
1938
 
                          unsigned long DataByteCount, u8 FromWhichBSSID)
1939
 
{
1940
 
        unsigned long Body_len;
1941
 
        BOOLEAN Cancelled;
1942
 
 
1943
 
        if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
1944
 
                return FALSE;
1945
 
 
1946
 
        /* Skip LLC header */
1947
 
        if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
1948
 
            /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */
1949
 
            NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) {
1950
 
                pData += 6;
1951
 
        }
1952
 
        /* Skip 2-bytes EAPoL type */
1953
 
        if (NdisEqualMemory(EAPOL, pData, 2)) {
1954
 
                pData += 2;
1955
 
        } else
1956
 
                return FALSE;
1957
 
 
1958
 
        switch (*(pData + 1)) {
1959
 
        case EAPPacket:
1960
 
                Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1961
 
                DBGPRINT(RT_DEBUG_TRACE,
1962
 
                         ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
1963
 
                          Body_len));
1964
 
                break;
1965
 
        case EAPOLStart:
1966
 
                DBGPRINT(RT_DEBUG_TRACE,
1967
 
                         ("Receive EAPOL-Start frame, TYPE = 1 \n"));
1968
 
                if (pEntry->EnqueueEapolStartTimerRunning !=
1969
 
                    EAPOL_START_DISABLE) {
1970
 
                        DBGPRINT(RT_DEBUG_TRACE,
1971
 
                                 ("Cancel the EnqueueEapolStartTimerRunning \n"));
1972
 
                        RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer,
1973
 
                                        &Cancelled);
1974
 
                        pEntry->EnqueueEapolStartTimerRunning =
1975
 
                            EAPOL_START_DISABLE;
1976
 
                }
1977
 
                break;
1978
 
        case EAPOLLogoff:
1979
 
                DBGPRINT(RT_DEBUG_TRACE,
1980
 
                         ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
1981
 
                break;
1982
 
        case EAPOLKey:
1983
 
                Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1984
 
                DBGPRINT(RT_DEBUG_TRACE,
1985
 
                         ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
1986
 
                          Body_len));
1987
 
                break;
1988
 
        case EAPOLASFAlert:
1989
 
                DBGPRINT(RT_DEBUG_TRACE,
1990
 
                         ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
1991
 
                break;
1992
 
        default:
1993
 
                return FALSE;
1994
 
 
1995
 
        }
1996
 
        return TRUE;
1997
 
}
1998
 
 
1999
 
/*
2000
 
    ==========================================================================
2001
 
    Description:
2002
 
                Report the EAP message type
2003
 
 
2004
 
        Arguments:
2005
 
                msg             -       EAPOL_PAIR_MSG_1
2006
 
                                        EAPOL_PAIR_MSG_2
2007
 
                                        EAPOL_PAIR_MSG_3
2008
 
                                        EAPOL_PAIR_MSG_4
2009
 
                                        EAPOL_GROUP_MSG_1
2010
 
                                        EAPOL_GROUP_MSG_2
2011
 
 
2012
 
    Return:
2013
 
         message type string
2014
 
 
2015
 
    ==========================================================================
2016
 
*/
2017
 
char *GetEapolMsgType(char msg)
2018
 
{
2019
 
        if (msg == EAPOL_PAIR_MSG_1)
2020
 
                return "Pairwise Message 1";
2021
 
        else if (msg == EAPOL_PAIR_MSG_2)
2022
 
                return "Pairwise Message 2";
2023
 
        else if (msg == EAPOL_PAIR_MSG_3)
2024
 
                return "Pairwise Message 3";
2025
 
        else if (msg == EAPOL_PAIR_MSG_4)
2026
 
                return "Pairwise Message 4";
2027
 
        else if (msg == EAPOL_GROUP_MSG_1)
2028
 
                return "Group Message 1";
2029
 
        else if (msg == EAPOL_GROUP_MSG_2)
2030
 
                return "Group Message 2";
2031
 
        else
2032
 
                return "Invalid Message";
2033
 
}
2034
 
 
2035
 
/*
2036
 
        ========================================================================
2037
 
 
2038
 
        Routine Description:
2039
 
    Check Sanity RSN IE of EAPoL message
2040
 
 
2041
 
        Arguments:
2042
 
 
2043
 
        Return Value:
2044
 
 
2045
 
        ========================================================================
2046
 
*/
2047
 
BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
2048
 
                       u8 *pData,
2049
 
                       u8 DataLen,
2050
 
                       struct rt_mac_table_entry *pEntry, u8 * Offset)
2051
 
{
2052
 
        u8 *pVIE;
2053
 
        u8 len;
2054
 
        struct rt_eid * pEid;
2055
 
        BOOLEAN result = FALSE;
2056
 
 
2057
 
        pVIE = pData;
2058
 
        len = DataLen;
2059
 
        *Offset = 0;
2060
 
 
2061
 
        while (len > sizeof(struct rt_rsnie2)) {
2062
 
                pEid = (struct rt_eid *) pVIE;
2063
 
                /* WPA RSN IE */
2064
 
                if ((pEid->Eid == IE_WPA)
2065
 
                    && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
2066
 
                        if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
2067
 
                             || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
2068
 
                            &&
2069
 
                            (NdisEqualMemory
2070
 
                             (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
2071
 
                            && (pEntry->RSNIE_Len == (pEid->Len + 2))) {
2072
 
                                result = TRUE;
2073
 
                        }
2074
 
 
2075
 
                        *Offset += (pEid->Len + 2);
2076
 
                }
2077
 
                /* WPA2 RSN IE */
2078
 
                else if ((pEid->Eid == IE_RSN)
2079
 
                         && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) {
2080
 
                        if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2
2081
 
                             || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
2082
 
                            && (pEid->Eid == pEntry->RSN_IE[0])
2083
 
                            && ((pEid->Len + 2) >= pEntry->RSNIE_Len)
2084
 
                            &&
2085
 
                            (NdisEqualMemory
2086
 
                             (pEid->Octet, &pEntry->RSN_IE[2],
2087
 
                              pEntry->RSNIE_Len - 2))) {
2088
 
 
2089
 
                                result = TRUE;
2090
 
                        }
2091
 
 
2092
 
                        *Offset += (pEid->Len + 2);
2093
 
                } else {
2094
 
                        break;
2095
 
                }
2096
 
 
2097
 
                pVIE += (pEid->Len + 2);
2098
 
                len -= (pEid->Len + 2);
2099
 
        }
2100
 
 
2101
 
        return result;
2102
 
 
2103
 
}
2104
 
 
2105
 
/*
2106
 
        ========================================================================
2107
 
 
2108
 
        Routine Description:
2109
 
    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
2110
 
    GTK  is encaptulated in KDE format at  p.83 802.11i D10
2111
 
 
2112
 
        Arguments:
2113
 
 
2114
 
        Return Value:
2115
 
 
2116
 
        Note:
2117
 
        802.11i D10
2118
 
 
2119
 
        ========================================================================
2120
 
*/
2121
 
BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
2122
 
                              u8 *pKeyData,
2123
 
                              u8 KeyDataLen,
2124
 
                              u8 GroupKeyIndex,
2125
 
                              u8 MsgType,
2126
 
                              IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
2127
 
{
2128
 
        struct rt_kde_encap * pKDE = NULL;
2129
 
        u8 *pMyKeyData = pKeyData;
2130
 
        u8 KeyDataLength = KeyDataLen;
2131
 
        u8 GTKLEN = 0;
2132
 
        u8 DefaultIdx = 0;
2133
 
        u8 skip_offset;
2134
 
 
2135
 
        /* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */
2136
 
        if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) {
2137
 
                /* Check RSN IE whether it is WPA2/WPA2PSK */
2138
 
                if (!RTMPCheckRSNIE
2139
 
                    (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) {
2140
 
                        /* send wireless event - for RSN IE different */
2141
 
                        if (pAd->CommonCfg.bWirelessEvent)
2142
 
                                RTMPSendWirelessEvent(pAd,
2143
 
                                                      IW_RSNIE_DIFF_EVENT_FLAG,
2144
 
                                                      pEntry->Addr,
2145
 
                                                      pEntry->apidx, 0);
2146
 
 
2147
 
                        DBGPRINT(RT_DEBUG_ERROR,
2148
 
                                 ("RSN_IE Different in msg %d of 4-way handshake!\n",
2149
 
                                  MsgType));
2150
 
                        hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
2151
 
                        hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
2152
 
                                 pEntry->RSNIE_Len);
2153
 
 
2154
 
                        return FALSE;
2155
 
                } else {
2156
 
                        if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
2157
 
                                WpaShowAllsuite(pMyKeyData, skip_offset);
2158
 
 
2159
 
                                /* skip RSN IE */
2160
 
                                pMyKeyData += skip_offset;
2161
 
                                KeyDataLength -= skip_offset;
2162
 
                                DBGPRINT(RT_DEBUG_TRACE,
2163
 
                                         ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n",
2164
 
                                          skip_offset));
2165
 
                        } else
2166
 
                                return TRUE;
2167
 
                }
2168
 
        }
2169
 
 
2170
 
        DBGPRINT(RT_DEBUG_TRACE,
2171
 
                 ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
2172
 
                  KeyDataLength));
2173
 
        /*hex_dump("remain data", pMyKeyData, KeyDataLength); */
2174
 
 
2175
 
        /* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
2176
 
        if (bWPA2
2177
 
            && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
2178
 
                if (KeyDataLength >= 8) /* KDE format exclude GTK length */
2179
 
                {
2180
 
                        pKDE = (struct rt_kde_encap *) pMyKeyData;
2181
 
 
2182
 
                        DefaultIdx = pKDE->GTKEncap.Kid;
2183
 
 
2184
 
                        /* Sanity check - KED length */
2185
 
                        if (KeyDataLength < (pKDE->Len + 2)) {
2186
 
                                DBGPRINT(RT_DEBUG_ERROR,
2187
 
                                         ("ERROR: The len from KDE is too short \n"));
2188
 
                                return FALSE;
2189
 
                        }
2190
 
                        /* Get GTK length - refer to IEEE 802.11i-2004 p.82 */
2191
 
                        GTKLEN = pKDE->Len - 6;
2192
 
                        if (GTKLEN < LEN_AES_KEY) {
2193
 
                                DBGPRINT(RT_DEBUG_ERROR,
2194
 
                                         ("ERROR: GTK Key length is too short (%d) \n",
2195
 
                                          GTKLEN));
2196
 
                                return FALSE;
2197
 
                        }
2198
 
 
2199
 
                } else {
2200
 
                        DBGPRINT(RT_DEBUG_ERROR,
2201
 
                                 ("ERROR: KDE format length is too short \n"));
2202
 
                        return FALSE;
2203
 
                }
2204
 
 
2205
 
                DBGPRINT(RT_DEBUG_TRACE,
2206
 
                         ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
2207
 
                          DefaultIdx, GTKLEN));
2208
 
                /* skip it */
2209
 
                pMyKeyData += 8;
2210
 
                KeyDataLength -= 8;
2211
 
 
2212
 
        } else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
2213
 
                DefaultIdx = GroupKeyIndex;
2214
 
                DBGPRINT(RT_DEBUG_TRACE,
2215
 
                         ("GTK DefaultKeyID=%d \n", DefaultIdx));
2216
 
        }
2217
 
        /* Sanity check - shared key index must be 1 ~ 3 */
2218
 
        if (DefaultIdx < 1 || DefaultIdx > 3) {
2219
 
                DBGPRINT(RT_DEBUG_ERROR,
2220
 
                         ("ERROR: GTK Key index(%d) is invalid in %s %s \n",
2221
 
                          DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"),
2222
 
                          GetEapolMsgType(MsgType)));
2223
 
                return FALSE;
2224
 
        }
2225
 
 
2226
 
        {
2227
 
                struct rt_cipher_key *pSharedKey;
2228
 
 
2229
 
                /* set key material, TxMic and RxMic */
2230
 
                NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
2231
 
                pAd->StaCfg.DefaultKeyId = DefaultIdx;
2232
 
 
2233
 
                pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
2234
 
 
2235
 
                /* Prepare pair-wise key information into shared key table */
2236
 
                NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
2237
 
                pSharedKey->KeyLen = LEN_TKIP_EK;
2238
 
                NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
2239
 
                NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
2240
 
                               LEN_TKIP_RXMICK);
2241
 
                NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
2242
 
                               LEN_TKIP_TXMICK);
2243
 
 
2244
 
                /* Update Shared Key CipherAlg */
2245
 
                pSharedKey->CipherAlg = CIPHER_NONE;
2246
 
                if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
2247
 
                        pSharedKey->CipherAlg = CIPHER_TKIP;
2248
 
                else if (pAd->StaCfg.GroupCipher ==
2249
 
                         Ndis802_11Encryption3Enabled)
2250
 
                        pSharedKey->CipherAlg = CIPHER_AES;
2251
 
                else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
2252
 
                        pSharedKey->CipherAlg = CIPHER_WEP64;
2253
 
                else if (pAd->StaCfg.GroupCipher ==
2254
 
                         Ndis802_11GroupWEP104Enabled)
2255
 
                        pSharedKey->CipherAlg = CIPHER_WEP128;
2256
 
 
2257
 
                /* Update group key information to ASIC Shared Key Table */
2258
 
                AsicAddSharedKeyEntry(pAd,
2259
 
                                      BSS0,
2260
 
                                      pAd->StaCfg.DefaultKeyId,
2261
 
                                      pSharedKey->CipherAlg,
2262
 
                                      pSharedKey->Key,
2263
 
                                      pSharedKey->TxMic, pSharedKey->RxMic);
2264
 
 
2265
 
                /* Update ASIC WCID attribute table and IVEIV table */
2266
 
                RTMPAddWcidAttributeEntry(pAd,
2267
 
                                          BSS0,
2268
 
                                          pAd->StaCfg.DefaultKeyId,
2269
 
                                          pSharedKey->CipherAlg, NULL);
2270
 
        }
2271
 
 
2272
 
        return TRUE;
2273
 
 
2274
 
}
2275
 
 
2276
 
/*
2277
 
        ========================================================================
2278
 
 
2279
 
        Routine Description:
2280
 
                Construct EAPoL message for WPA handshaking
2281
 
                Its format is below,
2282
 
 
2283
 
                +--------------------+
2284
 
                | Protocol Version       |  1 octet
2285
 
                +--------------------+
2286
 
                | Protocol Type          |      1 octet
2287
 
                +--------------------+
2288
 
                | Body Length            |  2 octets
2289
 
                +--------------------+
2290
 
                | Descriptor Type        |      1 octet
2291
 
                +--------------------+
2292
 
                | Key Information    |  2 octets
2293
 
                +--------------------+
2294
 
                | Key Length         |  1 octet
2295
 
                +--------------------+
2296
 
                | Key Repaly Counter |  8 octets
2297
 
                +--------------------+
2298
 
                | Key Nonce                  |  32 octets
2299
 
                +--------------------+
2300
 
                | Key IV                         |  16 octets
2301
 
                +--------------------+
2302
 
                | Key RSC                        |  8 octets
2303
 
                +--------------------+
2304
 
                | Key ID or Reserved |  8 octets
2305
 
                +--------------------+
2306
 
                | Key MIC                        |      16 octets
2307
 
                +--------------------+
2308
 
                | Key Data Length        |      2 octets
2309
 
                +--------------------+
2310
 
                | Key Data                       |      n octets
2311
 
                +--------------------+
2312
 
 
2313
 
        Arguments:
2314
 
                pAd                     Pointer to our adapter
2315
 
 
2316
 
        Return Value:
2317
 
                None
2318
 
 
2319
 
        Note:
2320
 
 
2321
 
        ========================================================================
2322
 
*/
2323
 
void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
2324
 
                       u8 GroupKeyWepStatus,
2325
 
                       u8 MsgType,
2326
 
                       u8 DefaultKeyIdx,
2327
 
                       u8 * KeyNonce,
2328
 
                       u8 * TxRSC,
2329
 
                       u8 * GTK,
2330
 
                       u8 * RSNIE,
2331
 
                       u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
2332
 
{
2333
 
        BOOLEAN bWPA2 = FALSE;
2334
 
        u8 KeyDescVer;
2335
 
 
2336
 
        /* Choose WPA2 or not */
2337
 
        if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2338
 
            (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2339
 
                bWPA2 = TRUE;
2340
 
 
2341
 
        /* Init Packet and Fill header */
2342
 
        pMsg->ProVer = EAPOL_VER;
2343
 
        pMsg->ProType = EAPOLKey;
2344
 
 
2345
 
        /* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
2346
 
        SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
2347
 
 
2348
 
        /* Fill in EAPoL descriptor */
2349
 
        if (bWPA2)
2350
 
                pMsg->KeyDesc.Type = WPA2_KEY_DESC;
2351
 
        else
2352
 
                pMsg->KeyDesc.Type = WPA1_KEY_DESC;
2353
 
 
2354
 
        /* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
2355
 
        {
2356
 
                /* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */
2357
 
                /* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */
2358
 
                KeyDescVer =
2359
 
                    (((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
2360
 
                      || (GroupKeyWepStatus ==
2361
 
                          Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
2362
 
                     : (DESC_TYPE_TKIP));
2363
 
        }
2364
 
 
2365
 
        pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
2366
 
 
2367
 
        /* Specify Key Type as Group(0) or Pairwise(1) */
2368
 
        if (MsgType >= EAPOL_GROUP_MSG_1)
2369
 
                pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
2370
 
        else
2371
 
                pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
2372
 
 
2373
 
        /* Specify Key Index, only group_msg1_WPA1 */
2374
 
        if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
2375
 
                pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
2376
 
 
2377
 
        if (MsgType == EAPOL_PAIR_MSG_3)
2378
 
                pMsg->KeyDesc.KeyInfo.Install = 1;
2379
 
 
2380
 
        if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
2381
 
            || (MsgType == EAPOL_GROUP_MSG_1))
2382
 
                pMsg->KeyDesc.KeyInfo.KeyAck = 1;
2383
 
 
2384
 
        if (MsgType != EAPOL_PAIR_MSG_1)
2385
 
                pMsg->KeyDesc.KeyInfo.KeyMic = 1;
2386
 
 
2387
 
        if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
2388
 
            (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
2389
 
                pMsg->KeyDesc.KeyInfo.Secure = 1;
2390
 
        }
2391
 
 
2392
 
        if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
2393
 
                      (MsgType == EAPOL_GROUP_MSG_1))) {
2394
 
                pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
2395
 
        }
2396
 
        /* key Information element has done. */
2397
 
        *(u16 *) (&pMsg->KeyDesc.KeyInfo) =
2398
 
            cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));
2399
 
 
2400
 
        /* Fill in Key Length */
2401
 
        {
2402
 
                if (MsgType >= EAPOL_GROUP_MSG_1) {
2403
 
                        /* the length of group key cipher */
2404
 
                        pMsg->KeyDesc.KeyLength[1] =
2405
 
                            ((GroupKeyWepStatus ==
2406
 
                              Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH :
2407
 
                             LEN_AES_KEY);
2408
 
                } else {
2409
 
                        /* the length of pairwise key cipher */
2410
 
                        pMsg->KeyDesc.KeyLength[1] =
2411
 
                            ((pEntry->WepStatus ==
2412
 
                              Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
2413
 
                             LEN_AES_KEY);
2414
 
                }
2415
 
        }
2416
 
 
2417
 
        /* Fill in replay counter */
2418
 
        NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
2419
 
                       LEN_KEY_DESC_REPLAY);
2420
 
 
2421
 
        /* Fill Key Nonce field */
2422
 
        /* ANonce : pairwise_msg1 & pairwise_msg3 */
2423
 
        /* SNonce : pairwise_msg2 */
2424
 
        /* GNonce : group_msg1_wpa1 */
2425
 
        if ((MsgType <= EAPOL_PAIR_MSG_3)
2426
 
            || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
2427
 
                NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce,
2428
 
                               LEN_KEY_DESC_NONCE);
2429
 
 
2430
 
        /* Fill key IV - WPA2 as 0, WPA1 as random */
2431
 
        if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) {
2432
 
                /* Suggest IV be random number plus some number, */
2433
 
                NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16],
2434
 
                               LEN_KEY_DESC_IV);
2435
 
                pMsg->KeyDesc.KeyIv[15] += 2;
2436
 
        }
2437
 
        /* Fill Key RSC field */
2438
 
        /* It contains the RSC for the GTK being installed. */
2439
 
        if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
2440
 
            || (MsgType == EAPOL_GROUP_MSG_1)) {
2441
 
                NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
2442
 
        }
2443
 
        /* Clear Key MIC field for MIC calculation later */
2444
 
        NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
2445
 
 
2446
 
        ConstructEapolKeyData(pEntry,
2447
 
                              GroupKeyWepStatus,
2448
 
                              KeyDescVer,
2449
 
                              MsgType,
2450
 
                              DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);
2451
 
 
2452
 
        /* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */
2453
 
        if (MsgType != EAPOL_PAIR_MSG_1) {
2454
 
                CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
2455
 
        }
2456
 
 
2457
 
        DBGPRINT(RT_DEBUG_TRACE,
2458
 
                 ("===> ConstructEapolMsg for %s %s\n",
2459
 
                  ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
2460
 
        DBGPRINT(RT_DEBUG_TRACE,
2461
 
                 ("          Body length = %d \n",
2462
 
                  CONV_ARRARY_TO_u16(pMsg->Body_Len)));
2463
 
        DBGPRINT(RT_DEBUG_TRACE,
2464
 
                 ("          Key length  = %d \n",
2465
 
                  CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength)));
2466
 
 
2467
 
}
2468
 
 
2469
 
/*
2470
 
        ========================================================================
2471
 
 
2472
 
        Routine Description:
2473
 
                Construct the Key Data field of EAPoL message
2474
 
 
2475
 
        Arguments:
2476
 
                pAd                     Pointer to our adapter
2477
 
                Elem            Message body
2478
 
 
2479
 
        Return Value:
2480
 
                None
2481
 
 
2482
 
        Note:
2483
 
 
2484
 
        ========================================================================
2485
 
*/
2486
 
void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
2487
 
                           u8 GroupKeyWepStatus,
2488
 
                           u8 keyDescVer,
2489
 
                           u8 MsgType,
2490
 
                           u8 DefaultKeyIdx,
2491
 
                           u8 * GTK,
2492
 
                           u8 * RSNIE,
2493
 
                           u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
2494
 
{
2495
 
        u8 *mpool, *Key_Data, *Rc4GTK;
2496
 
        u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)];
2497
 
        unsigned long data_offset;
2498
 
        BOOLEAN bWPA2Capable = FALSE;
2499
 
        struct rt_rtmp_adapter *pAd = pEntry->pAd;
2500
 
        BOOLEAN GTK_Included = FALSE;
2501
 
 
2502
 
        /* Choose WPA2 or not */
2503
 
        if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2504
 
            (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2505
 
                bWPA2Capable = TRUE;
2506
 
 
2507
 
        if (MsgType == EAPOL_PAIR_MSG_1 ||
2508
 
            MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
2509
 
                return;
2510
 
 
2511
 
        /* allocate memory pool */
2512
 
        os_alloc_mem(NULL, (u8 **) & mpool, 1500);
2513
 
 
2514
 
        if (mpool == NULL)
2515
 
                return;
2516
 
 
2517
 
        /* Rc4GTK Len = 512 */
2518
 
        Rc4GTK = (u8 *) ROUND_UP(mpool, 4);
2519
 
        /* Key_Data Len = 512 */
2520
 
        Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4);
2521
 
 
2522
 
        NdisZeroMemory(Key_Data, 512);
2523
 
        SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
2524
 
        data_offset = 0;
2525
 
 
2526
 
        /* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
2527
 
        if (RSNIE_LEN
2528
 
            && ((MsgType == EAPOL_PAIR_MSG_2)
2529
 
                || (MsgType == EAPOL_PAIR_MSG_3))) {
2530
 
                u8 *pmkid_ptr = NULL;
2531
 
                u8 pmkid_len = 0;
2532
 
 
2533
 
                RTMPInsertRSNIE(&Key_Data[data_offset],
2534
 
                                &data_offset,
2535
 
                                RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
2536
 
        }
2537
 
 
2538
 
        /* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
2539
 
        if (bWPA2Capable
2540
 
            && ((MsgType == EAPOL_PAIR_MSG_3)
2541
 
                || (MsgType == EAPOL_GROUP_MSG_1))) {
2542
 
                /* Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h */
2543
 
                Key_Data[data_offset + 0] = 0xDD;
2544
 
 
2545
 
                if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2546
 
                        Key_Data[data_offset + 1] = 0x16;       /* 4+2+16(OUI+DataType+DataField) */
2547
 
                } else {
2548
 
                        Key_Data[data_offset + 1] = 0x26;       /* 4+2+32(OUI+DataType+DataField) */
2549
 
                }
2550
 
 
2551
 
                Key_Data[data_offset + 2] = 0x00;
2552
 
                Key_Data[data_offset + 3] = 0x0F;
2553
 
                Key_Data[data_offset + 4] = 0xAC;
2554
 
                Key_Data[data_offset + 5] = 0x01;
2555
 
 
2556
 
                /* GTK KDE format - 802.11i-2004  Figure-43x */
2557
 
                Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
2558
 
                Key_Data[data_offset + 7] = 0x00;       /* Reserved Byte */
2559
 
 
2560
 
                data_offset += 8;
2561
 
        }
2562
 
 
2563
 
        /* Encapsulate GTK */
2564
 
        /* Only for pairwise_msg3_WPA2 and group_msg1 */
2565
 
        if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
2566
 
            || (MsgType == EAPOL_GROUP_MSG_1)) {
2567
 
                /* Fill in GTK */
2568
 
                if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2569
 
                        NdisMoveMemory(&Key_Data[data_offset], GTK,
2570
 
                                       LEN_AES_KEY);
2571
 
                        data_offset += LEN_AES_KEY;
2572
 
                } else {
2573
 
                        NdisMoveMemory(&Key_Data[data_offset], GTK,
2574
 
                                       TKIP_GTK_LENGTH);
2575
 
                        data_offset += TKIP_GTK_LENGTH;
2576
 
                }
2577
 
 
2578
 
                GTK_Included = TRUE;
2579
 
        }
2580
 
 
2581
 
        /* This whole key-data field shall be encrypted if a GTK is included. */
2582
 
        /* Encrypt the data material in key data field with KEK */
2583
 
        if (GTK_Included) {
2584
 
                /*hex_dump("GTK_Included", Key_Data, data_offset); */
2585
 
 
2586
 
                if ((keyDescVer == DESC_TYPE_AES)) {
2587
 
                        u8 remainder = 0;
2588
 
                        u8 pad_len = 0;
2589
 
 
2590
 
                        /* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */
2591
 
                        /* shall be used to encrypt the Key Data field using the KEK field from */
2592
 
                        /* the derived PTK. */
2593
 
 
2594
 
                        /* If the Key Data field uses the NIST AES key wrap, then the Key Data field */
2595
 
                        /* shall be padded before encrypting if the key data length is less than 16 */
2596
 
                        /* octets or if it is not a multiple of 8. The padding consists of appending */
2597
 
                        /* a single octet 0xdd followed by zero or more 0x00 octets. */
2598
 
                        if ((remainder = data_offset & 0x07) != 0) {
2599
 
                                int i;
2600
 
 
2601
 
                                pad_len = (8 - remainder);
2602
 
                                Key_Data[data_offset] = 0xDD;
2603
 
                                for (i = 1; i < pad_len; i++)
2604
 
                                        Key_Data[data_offset + i] = 0;
2605
 
 
2606
 
                                data_offset += pad_len;
2607
 
                        }
2608
 
 
2609
 
                        AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
2610
 
                                         data_offset, Rc4GTK);
2611
 
                        /* AES wrap function will grow 8 bytes in length */
2612
 
                        data_offset += 8;
2613
 
                } else {
2614
 
                        /*      Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
2615
 
                           using the KEK field from the derived PTK. */
2616
 
 
2617
 
                        /* PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */
2618
 
                        /* put TxTsc in Key RSC field */
2619
 
                        pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;       /*Init crc32. */
2620
 
 
2621
 
                        /* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
2622
 
                        NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
2623
 
                                       LEN_KEY_DESC_IV);
2624
 
                        NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
2625
 
                                       LEN_EAP_EK);
2626
 
                        ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); /*INIT SBOX, KEYLEN+3(IV) */
2627
 
                        pAd->PrivateInfo.FCSCRC32 =
2628
 
                            RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data,
2629
 
                                            data_offset);
2630
 
                        WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
2631
 
                                           Key_Data, data_offset);
2632
 
                }
2633
 
 
2634
 
                NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
2635
 
        } else {
2636
 
                NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
2637
 
        }
2638
 
 
2639
 
        /* Update key data length field and total body length */
2640
 
        SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
2641
 
        INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset);
2642
 
 
2643
 
        os_free_mem(NULL, mpool);
2644
 
 
2645
 
}
2646
 
 
2647
 
/*
2648
 
        ========================================================================
2649
 
 
2650
 
        Routine Description:
2651
 
                Calcaulate MIC. It is used during 4-ways handsharking.
2652
 
 
2653
 
        Arguments:
2654
 
                pAd                     -       pointer to our pAdapter context
2655
 
        PeerWepStatus   -       indicate the encryption type
2656
 
 
2657
 
        Return Value:
2658
 
 
2659
 
        Note:
2660
 
 
2661
 
        ========================================================================
2662
 
*/
2663
 
static void CalculateMIC(u8 KeyDescVer,
2664
 
                         u8 * PTK, struct rt_eapol_packet * pMsg)
2665
 
{
2666
 
        u8 *OutBuffer;
2667
 
        unsigned long FrameLen = 0;
2668
 
        u8 mic[LEN_KEY_DESC_MIC];
2669
 
        u8 digest[80];
2670
 
 
2671
 
        /* allocate memory for MIC calculation */
2672
 
        os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);
2673
 
 
2674
 
        if (OutBuffer == NULL) {
2675
 
                DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
2676
 
                return;
2677
 
        }
2678
 
        /* make a frame for calculating MIC. */
2679
 
        MakeOutgoingFrame(OutBuffer, &FrameLen,
2680
 
                          CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
2681
 
                          END_OF_ARGS);
2682
 
 
2683
 
        NdisZeroMemory(mic, sizeof(mic));
2684
 
 
2685
 
        /* Calculate MIC */
2686
 
        if (KeyDescVer == DESC_TYPE_AES) {
2687
 
                HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
2688
 
                          SHA1_DIGEST_SIZE);
2689
 
                NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
2690
 
        } else {
2691
 
                HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
2692
 
                         MD5_DIGEST_SIZE);
2693
 
        }
2694
 
 
2695
 
        /* store the calculated MIC */
2696
 
        NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
2697
 
 
2698
 
        os_free_mem(NULL, OutBuffer);
2699
 
}
2700
 
 
2701
 
/*
2702
 
        ========================================================================
2703
 
 
2704
 
        Routine Description:
2705
 
                Some received frames can't decrypt by Asic, so decrypt them by software.
2706
 
 
2707
 
        Arguments:
2708
 
                pAd                     -       pointer to our pAdapter context
2709
 
        PeerWepStatus   -       indicate the encryption type
2710
 
 
2711
 
        Return Value:
2712
 
                NDIS_STATUS_SUCCESS             -       decryption successful
2713
 
                NDIS_STATUS_FAILURE             -       decryption failure
2714
 
 
2715
 
        ========================================================================
2716
 
*/
2717
 
int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
2718
 
                                         struct rt_rx_blk *pRxBlk,
2719
 
                                         IN NDIS_802_11_ENCRYPTION_STATUS
2720
 
                                         GroupCipher, struct rt_cipher_key *pShard_key)
2721
 
{
2722
 
        struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
2723
 
 
2724
 
        /* handle WEP decryption */
2725
 
        if (GroupCipher == Ndis802_11Encryption1Enabled) {
2726
 
                if (RTMPSoftDecryptWEP
2727
 
                    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2728
 
                     pShard_key)) {
2729
 
 
2730
 
                        /*Minus IV[4] & ICV[4] */
2731
 
                        pRxWI->MPDUtotalByteCount -= 8;
2732
 
                } else {
2733
 
                        DBGPRINT(RT_DEBUG_ERROR,
2734
 
                                 ("ERROR : Software decrypt WEP data fails.\n"));
2735
 
                        /* give up this frame */
2736
 
                        return NDIS_STATUS_FAILURE;
2737
 
                }
2738
 
        }
2739
 
        /* handle TKIP decryption */
2740
 
        else if (GroupCipher == Ndis802_11Encryption2Enabled) {
2741
 
                if (RTMPSoftDecryptTKIP
2742
 
                    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
2743
 
                     pShard_key)) {
2744
 
 
2745
 
                        /*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
2746
 
                        pRxWI->MPDUtotalByteCount -= 20;
2747
 
                } else {
2748
 
                        DBGPRINT(RT_DEBUG_ERROR,
2749
 
                                 ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
2750
 
                        /* give up this frame */
2751
 
                        return NDIS_STATUS_FAILURE;
2752
 
                }
2753
 
        }
2754
 
        /* handle AES decryption */
2755
 
        else if (GroupCipher == Ndis802_11Encryption3Enabled) {
2756
 
                if (RTMPSoftDecryptAES
2757
 
                    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2758
 
                     pShard_key)) {
2759
 
 
2760
 
                        /*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
2761
 
                        pRxWI->MPDUtotalByteCount -= 16;
2762
 
                } else {
2763
 
                        DBGPRINT(RT_DEBUG_ERROR,
2764
 
                                 ("ERROR : RTMPSoftDecryptAES Failed\n"));
2765
 
                        /* give up this frame */
2766
 
                        return NDIS_STATUS_FAILURE;
2767
 
                }
2768
 
        } else {
2769
 
                /* give up this frame */
2770
 
                return NDIS_STATUS_FAILURE;
2771
 
        }
2772
 
 
2773
 
        return NDIS_STATUS_SUCCESS;
2774
 
 
2775
 
}
2776
 
 
2777
 
u8 *GetSuiteFromRSNIE(u8 *rsnie,
2778
 
                         u32 rsnie_len, u8 type, u8 * count)
2779
 
{
2780
 
        struct rt_eid * pEid;
2781
 
        int len;
2782
 
        u8 *pBuf;
2783
 
        int offset = 0;
2784
 
        struct rt_rsnie_auth *pAkm;
2785
 
        u16 acount;
2786
 
        BOOLEAN isWPA2 = FALSE;
2787
 
 
2788
 
        pEid = (struct rt_eid *) rsnie;
2789
 
        len = rsnie_len - 2;    /* exclude IE and length */
2790
 
        pBuf = (u8 *)& pEid->Octet[0];
2791
 
 
2792
 
        /* set default value */
2793
 
        *count = 0;
2794
 
 
2795
 
        /* Check length */
2796
 
        if ((len <= 0) || (pEid->Len != len)) {
2797
 
                DBGPRINT_ERR("%s : The length is invalid\n", __func__);
2798
 
                return NULL;
2799
 
        }
2800
 
        /* Check WPA or WPA2 */
2801
 
        if (pEid->Eid == IE_WPA) {
2802
 
                struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
2803
 
                u16 ucount;
2804
 
 
2805
 
                if (len < sizeof(struct rt_rsnie)) {
2806
 
                        DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__);
2807
 
                        return NULL;
2808
 
                }
2809
 
                /* Get the count of pairwise cipher */
2810
 
                ucount = cpu2le16(pRsnie->ucount);
2811
 
                if (ucount > 2) {
2812
 
                        DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2813
 
                        return NULL;
2814
 
                }
2815
 
                /* Get the group cipher */
2816
 
                if (type == GROUP_SUITE) {
2817
 
                        *count = 1;
2818
 
                        return pRsnie->mcast;
2819
 
                }
2820
 
                /* Get the pairwise cipher suite */
2821
 
                else if (type == PAIRWISE_SUITE) {
2822
 
                        DBGPRINT(RT_DEBUG_TRACE,
2823
 
                                 ("%s : The count of pairwise cipher is %d\n",
2824
 
                                  __func__, ucount));
2825
 
                        *count = ucount;
2826
 
                        return pRsnie->ucast[0].oui;
2827
 
                }
2828
 
 
2829
 
                offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));
2830
 
 
2831
 
        } else if (pEid->Eid == IE_RSN) {
2832
 
                struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
2833
 
                u16 ucount;
2834
 
 
2835
 
                isWPA2 = TRUE;
2836
 
 
2837
 
                if (len < sizeof(struct rt_rsnie2)) {
2838
 
                        DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__);
2839
 
                        return NULL;
2840
 
                }
2841
 
                /* Get the count of pairwise cipher */
2842
 
                ucount = cpu2le16(pRsnie->ucount);
2843
 
                if (ucount > 2) {
2844
 
                        DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2845
 
                        return NULL;
2846
 
                }
2847
 
                /* Get the group cipher */
2848
 
                if (type == GROUP_SUITE) {
2849
 
                        *count = 1;
2850
 
                        return pRsnie->mcast;
2851
 
                }
2852
 
                /* Get the pairwise cipher suite */
2853
 
                else if (type == PAIRWISE_SUITE) {
2854
 
                        DBGPRINT(RT_DEBUG_TRACE,
2855
 
                                 ("%s : The count of pairwise cipher is %d\n",
2856
 
                                  __func__, ucount));
2857
 
                        *count = ucount;
2858
 
                        return pRsnie->ucast[0].oui;
2859
 
                }
2860
 
 
2861
 
                offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));
2862
 
 
2863
 
        } else {
2864
 
                DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid);
2865
 
                return NULL;
2866
 
        }
2867
 
 
2868
 
        /* skip group cipher and pairwise cipher suite */
2869
 
        pBuf += offset;
2870
 
        len -= offset;
2871
 
 
2872
 
        if (len < sizeof(struct rt_rsnie_auth)) {
2873
 
                DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__);
2874
 
                return NULL;
2875
 
        }
2876
 
        /* pointer to AKM count */
2877
 
        pAkm = (struct rt_rsnie_auth *)pBuf;
2878
 
 
2879
 
        /* Get the count of pairwise cipher */
2880
 
        acount = cpu2le16(pAkm->acount);
2881
 
        if (acount > 2) {
2882
 
                DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount);
2883
 
                return NULL;
2884
 
        }
2885
 
        /* Get the AKM suite */
2886
 
        if (type == AKM_SUITE) {
2887
 
                DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
2888
 
                                          __func__, acount));
2889
 
                *count = acount;
2890
 
                return pAkm->auth[0].oui;
2891
 
        }
2892
 
        offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));
2893
 
 
2894
 
        pBuf += offset;
2895
 
        len -= offset;
2896
 
 
2897
 
        /* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */
2898
 
        if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) {
2899
 
                /* Skip RSN capability and PMKID-Count */
2900
 
                pBuf += (sizeof(RSN_CAPABILITIES) + 2);
2901
 
                len -= (sizeof(RSN_CAPABILITIES) + 2);
2902
 
 
2903
 
                /* Get PMKID */
2904
 
                if (type == PMKID_LIST) {
2905
 
                        *count = 1;
2906
 
                        return pBuf;
2907
 
                }
2908
 
        } else {
2909
 
                DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__);
2910
 
                return NULL;
2911
 
        }
2912
 
 
2913
 
        *count = 0;
2914
 
        /*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
2915
 
        return NULL;
2916
 
 
2917
 
}
2918
 
 
2919
 
void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
2920
 
{
2921
 
        u8 *pSuite = NULL;
2922
 
        u8 count;
2923
 
 
2924
 
        hex_dump("RSNIE", rsnie, rsnie_len);
2925
 
 
2926
 
        /* group cipher */
2927
 
        pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count);
2928
 
        if (pSuite != NULL) {
2929
 
                hex_dump("group cipher", pSuite, 4 * count);
2930
 
        }
2931
 
        /* pairwise cipher */
2932
 
        pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count);
2933
 
        if (pSuite != NULL) {
2934
 
                hex_dump("pairwise cipher", pSuite, 4 * count);
2935
 
        }
2936
 
        /* AKM */
2937
 
        pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count);
2938
 
        if (pSuite != NULL) {
2939
 
                hex_dump("AKM suite", pSuite, 4 * count);
2940
 
        }
2941
 
        /* PMKID */
2942
 
        pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count);
2943
 
        if (pSuite != NULL) {
2944
 
                hex_dump("PMKID", pSuite, LEN_PMKID);
2945
 
        }
2946
 
 
2947
 
}
2948
 
 
2949
 
void RTMPInsertRSNIE(u8 *pFrameBuf,
2950
 
                     unsigned long *pFrameLen,
2951
 
                     u8 *rsnie_ptr,
2952
 
                     u8 rsnie_len,
2953
 
                     u8 *pmkid_ptr, u8 pmkid_len)
2954
 
{
2955
 
        u8 *pTmpBuf;
2956
 
        unsigned long TempLen = 0;
2957
 
        u8 extra_len = 0;
2958
 
        u16 pmk_count = 0;
2959
 
        u8 ie_num;
2960
 
        u8 total_len = 0;
2961
 
        u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
2962
 
 
2963
 
        pTmpBuf = pFrameBuf;
2964
 
 
2965
 
        /* PMKID-List Must larger than 0 and the multiple of 16. */
2966
 
        if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) {
2967
 
                extra_len = sizeof(u16)+ pmkid_len;
2968
 
 
2969
 
                pmk_count = (pmkid_len >> 4);
2970
 
                pmk_count = cpu2le16(pmk_count);
2971
 
        } else {
2972
 
                DBGPRINT(RT_DEBUG_WARN,
2973
 
                         ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
2974
 
                          __func__, pmkid_len));
2975
 
        }
2976
 
 
2977
 
        if (rsnie_len != 0) {
2978
 
                ie_num = IE_WPA;
2979
 
                total_len = rsnie_len;
2980
 
 
2981
 
                if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
2982
 
                        ie_num = IE_RSN;
2983
 
                        total_len += extra_len;
2984
 
                }
2985
 
 
2986
 
                /* construct RSNIE body */
2987
 
                MakeOutgoingFrame(pTmpBuf, &TempLen,
2988
 
                                  1, &ie_num,
2989
 
                                  1, &total_len,
2990
 
                                  rsnie_len, rsnie_ptr, END_OF_ARGS);
2991
 
 
2992
 
                pTmpBuf += TempLen;
2993
 
                *pFrameLen = *pFrameLen + TempLen;
2994
 
 
2995
 
                if (ie_num == IE_RSN) {
2996
 
                        /* Insert PMKID-List field */
2997
 
                        if (extra_len > 0) {
2998
 
                                MakeOutgoingFrame(pTmpBuf, &TempLen,
2999
 
                                                  2, &pmk_count,
3000
 
                                                  pmkid_len, pmkid_ptr,
3001
 
                                                  END_OF_ARGS);
3002
 
 
3003
 
                                pTmpBuf += TempLen;
3004
 
                                *pFrameLen = *pFrameLen + TempLen;
3005
 
                        }
3006
 
                }
3007
 
        }
3008
 
 
3009
 
        return;
3010
 
}