2
*************************************************************************
4
* 5F., No.36, Taiyuan St., Jhubei City,
8
* (c) Copyright 2002-2007, Ralink Technology, Inc.
10
* This program is free software; you can redistribute it and/or modify *
11
* it under the terms of the GNU General Public License as published by *
12
* the Free Software Foundation; either version 2 of the License, or *
13
* (at your option) any later version. *
15
* This program is distributed in the hope that it will be useful, *
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18
* GNU General Public License for more details. *
20
* You should have received a copy of the GNU General Public License *
21
* along with this program; if not, write to the *
22
* Free Software Foundation, Inc., *
23
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25
*************************************************************************
34
-------- ---------- ----------------------------------------------
35
Jan Lee 03-07-22 Initial
36
Paul Lin 03-11-28 Modify for supplicant
38
#include "../rt_config.h"
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 };
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 };
57
static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
64
u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);
66
static void CalculateMIC(u8 KeyDescVer,
67
u8 * PTK, struct rt_eapol_packet * pMsg);
69
static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
71
static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
72
struct rt_mlme_queue_elem *Elem);
74
static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
75
struct rt_mlme_queue_elem *Elem);
77
static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
78
struct rt_mlme_queue_elem *Elem);
80
static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
83
==========================================================================
85
association state machine init, including state transition and timer init
87
S - pointer to the association state machine
88
==========================================================================
90
void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
91
struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
93
StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE,
94
MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK,
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);
110
==========================================================================
112
this is state machine function.
113
When receiving EAP packets which is for 802.1x authentication use.
116
==========================================================================
118
void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
122
void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
126
void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
131
==========================================================================
133
Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
135
==========================================================================
137
void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
139
struct rt_mac_table_entry *pEntry;
140
struct rt_header_802_11 * pHeader;
142
DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
144
pHeader = (struct rt_header_802_11 *) Elem->Msg;
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);
150
pEntry = MacTableLookup(pAd, pHeader->Addr2);
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));
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;
172
WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
178
==========================================================================
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
188
==========================================================================
190
void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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;
197
DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
199
pHeader = (struct rt_header_802_11 *) Elem->Msg;
201
(struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
203
NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
204
NdisMoveMemory((u8 *)& peerKeyInfo,
205
(u8 *)& pEapol_packet->KeyDesc.KeyInfo,
206
sizeof(struct rt_key_info));
208
hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
209
(Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
211
*((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));
214
pEntry = MacTableLookup(pAd, pHeader->Addr2);
217
|| ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
220
if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
223
DBGPRINT(RT_DEBUG_TRACE,
224
("Receive EAPoL-Key frame from STA %pMF\n",
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"));
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"));
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"));
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 */
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. */
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,
274
PeerPairMsg3Action(pAd, pEntry,
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,
288
PeerGroupMsg1Action(pAd, pEntry,
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 ==
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.
306
PeerPairMsg4Action(pAd,
310
PeerPairMsg2Action(pAd,
314
} else if (peerKeyInfo.Secure == 1
315
&& peerKeyInfo.KeyType ==
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,
321
} else if (peerKeyInfo.Secure == 1
322
&& peerKeyInfo.KeyType ==
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,
341
========================================================================
344
Copy frame from waiting queue into relative ring buffer and set
345
appropriate ASIC register to kick hardware encryption before really
349
pAd Pointer to our adapter
350
void * Pointer to outgoing Ndis frame
351
NumberOfFrag Number of fragment required
358
========================================================================
360
void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
361
struct rt_mac_table_entry *pEntry,
364
u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
369
if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
373
/* build a NDIS packet */
375
RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
377
if (Status != NDIS_STATUS_SUCCESS)
381
RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
383
RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
385
RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
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,
393
RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
394
RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
398
/* send out the packet */
399
Status = STASendPacket(pAd, pPacket);
400
if (Status == NDIS_STATUS_SUCCESS) {
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 */
409
(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
412
(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
413
for (Index = 0; Index < 5; Index++)
414
if (pAd->TxSwQueue[Index].
416
RTMPDeQueuePacket(pAd,
428
==========================================================================
430
This is a function to initialize 4-way handshake
434
==========================================================================
436
void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
437
struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
440
struct rt_eapol_packet EAPOLPKT;
442
u8 group_cipher = Ndis802_11WEPDisabled;
444
DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
448
fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
450
DBGPRINT(RT_DEBUG_ERROR,
451
("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
455
if (pBssid == NULL) {
456
DBGPRINT(RT_DEBUG_ERROR,
457
("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
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"));
467
/* Increment replay counter by 1 */
468
ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
470
/* Randomly generate ANonce */
471
GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);
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 */
480
0, /* RSNIE length */
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);
491
/* Trigger Retry Timer */
492
RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
495
pEntry->WpaState = AS_PTKSTART;
497
DBGPRINT(RT_DEBUG_TRACE,
498
("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
503
========================================================================
506
Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
509
pAd Pointer to our adapter
517
========================================================================
519
void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
520
struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
524
struct rt_eapol_packet * pMsg1;
526
struct rt_eapol_packet EAPOLPKT;
527
u8 *pCurrentAddr = NULL;
529
u8 group_cipher = Ndis802_11WEPDisabled;
530
u8 *rsnie_ptr = NULL;
533
DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
535
if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
539
(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
540
sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
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;
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;
555
/* Sanity Check peer Pairwise message 1 - Replay Counter */
556
if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
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);
565
NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
568
/* Generate random SNonce */
569
GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);
572
/* Calculate PTK(ANonce, SNonce) */
577
pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);
579
/* Save key to PTK entry */
580
NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
583
/* Update WpaState */
584
pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
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 */
592
(u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
594
/* Make outgoing frame */
595
MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
597
RTMPToWirelessSta(pAd, pEntry,
598
Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
599
CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
601
DBGPRINT(RT_DEBUG_TRACE,
602
("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
606
==========================================================================
608
When receiving the second packet of 4-way pairwisekey handshake.
610
==========================================================================
612
void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
613
struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
617
struct rt_header_802_11 * pHeader;
618
struct rt_eapol_packet EAPOLPKT;
619
struct rt_eapol_packet * pMsg2;
621
u8 Header802_3[LENGTH_802_3];
627
u8 group_cipher = Ndis802_11WEPDisabled;
628
u8 *rsnie_ptr = NULL;
631
DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
633
if ((!pEntry) || (!pEntry->ValidAsCLI))
637
(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
638
sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
641
/* check Entry in valid State */
642
if (pEntry->WpaState < AS_PTKSTART)
645
/* pointer to 802.11 header */
646
pHeader = (struct rt_header_802_11 *) Elem->Msg;
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;
653
NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
658
WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce, /* ANONCE */
659
(u8 *) pBssid, pEntry->SNonce, /* SNONCE */
660
pEntry->Addr, PTK, LEN_PTK);
662
NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
665
/* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
666
if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
671
/* delete retry timer */
672
RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
675
pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
677
/* Increment replay counter by 1 */
678
ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
680
/* Construct EAPoL message - Pairwise Msg 3 */
681
NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
682
ConstructEapolMsg(pEntry,
689
(u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
691
/* Make outgoing frame */
692
MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
693
RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
695
CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
696
(pEntry->PortSecured ==
697
WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
699
pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
700
RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
703
pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
706
DBGPRINT(RT_DEBUG_TRACE,
707
("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
711
========================================================================
714
Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
717
pAd Pointer to our adapter
725
========================================================================
727
void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
728
struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
730
struct rt_header_802_11 * pHeader;
732
struct rt_eapol_packet EAPOLPKT;
733
struct rt_eapol_packet * pMsg3;
735
u8 *pCurrentAddr = NULL;
736
u8 group_cipher = Ndis802_11WEPDisabled;
738
DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
740
if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
744
(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
745
sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
749
pCurrentAddr = pAd->CurrentAddress;
750
group_cipher = pAd->StaCfg.GroupCipher;
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;
759
/* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
760
if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
764
/* Save Replay counter, it will use construct message 4 */
765
NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
766
LEN_KEY_DESC_REPLAY);
768
/* Double check ANonce */
770
(pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
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 */
782
/* Update WpaState */
783
pEntry->WpaState = AS_PTKINITDONE;
785
/* Update pairwise key */
787
struct rt_cipher_key *pSharedKey;
789
pSharedKey = &pAd->SharedKey[BSS0][0];
791
NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
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],
798
NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
800
NdisMoveMemory(pSharedKey->TxMic,
801
&pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
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;
810
pSharedKey->CipherAlg = CIPHER_NONE;
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],
816
NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
818
NdisMoveMemory(pEntry->PairwiseKey.TxMic,
819
&pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
821
pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
823
/* Update pairwise key information to ASIC Shared Key Table */
824
AsicAddSharedKeyEntry(pAd,
827
pSharedKey->CipherAlg,
829
pSharedKey->TxMic, pSharedKey->RxMic);
831
/* Update ASIC WCID attribute table and IVEIV table */
832
RTMPAddWcidAttributeEntry(pAd,
834
0, pSharedKey->CipherAlg, pEntry);
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;
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)));
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),
860
CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
862
DBGPRINT(RT_DEBUG_TRACE,
863
("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
867
==========================================================================
869
When receiving the last packet of 4-way pairwisekey handshake.
870
Initialize 2-way groupkey handshake following.
872
==========================================================================
874
void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
875
struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
877
struct rt_eapol_packet * pMsg4;
878
struct rt_header_802_11 * pHeader;
881
u8 group_cipher = Ndis802_11WEPDisabled;
883
DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
886
if ((!pEntry) || (!pEntry->ValidAsCLI))
890
(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
891
sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
894
if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
897
/* pointer to 802.11 header */
898
pHeader = (struct rt_header_802_11 *) Elem->Msg;
900
/* skip 802.11_header(24-byte) and LLC_header(8) */
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;
905
/* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
906
if (PeerWpaMessageSanity
907
(pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
910
/* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
911
NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));
913
/* reset IVEIV in Asic */
914
AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
916
pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
917
NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
919
NdisMoveMemory(pEntry->PairwiseKey.RxMic,
920
&pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
922
NdisMoveMemory(pEntry->PairwiseKey.TxMic,
923
&pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
926
/* Set pairwise key to Asic */
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;
935
/* Add Pair-wise key to Asic */
936
AsicAddPairwiseKeyEntry(pAd,
939
&pEntry->PairwiseKey);
941
/* update WCID attribute table and IVEIV table for this entry */
942
RTMPAddWcidAttributeEntry(pAd,
945
pEntry->PairwiseKey.CipherAlg,
949
/* 4. upgrade state */
950
pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
951
pEntry->WpaState = AS_PTKINITDONE;
952
pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
954
if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
955
pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
956
pEntry->GTKState = REKEY_ESTABLISHED;
957
RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
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,
966
DBGPRINT(RT_DEBUG_OFF,
967
("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
969
GetAuthMode(pEntry->AuthMode),
971
GetEncryptType(pEntry->WepStatus),
972
group_cipher, GetEncryptType(group_cipher)));
974
/* 5. init Group 2-way handshake if necessary. */
975
WPAStart2WayGroupHS(pAd, pEntry);
977
pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
978
RTMPModTimer(&pEntry->RetryTimer,
979
PEER_MSG3_RETRY_EXEC_INTV);
986
==========================================================================
988
This is a function to send the first packet of 2-way groupkey handshake
991
==========================================================================
993
void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
997
struct rt_eapol_packet EAPOLPKT;
998
u8 group_cipher = Ndis802_11WEPDisabled;
1000
u8 *gnonce_ptr = NULL;
1004
DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
1006
if ((!pEntry) || (!pEntry->ValidAsCLI))
1010
/* Increment replay counter by 1 */
1011
ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
1013
/* Construct EAPoL message - Group Msg 1 */
1014
NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
1015
ConstructEapolMsg(pEntry,
1020
TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);
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,
1027
CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
1032
DBGPRINT(RT_DEBUG_TRACE,
1033
("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
1039
========================================================================
1041
Routine Description:
1042
Process Group key 2-way handshaking
1045
pAd Pointer to our adapter
1053
========================================================================
1055
void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
1056
struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
1059
struct rt_eapol_packet EAPOLPKT;
1060
struct rt_eapol_packet * pGroup;
1064
u8 group_cipher = Ndis802_11WEPDisabled;
1065
u8 *pCurrentAddr = NULL;
1067
DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
1069
if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
1073
pCurrentAddr = pAd->CurrentAddress;
1074
group_cipher = pAd->StaCfg.GroupCipher;
1075
default_key = pAd->StaCfg.DefaultKeyId;
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;
1082
/* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
1083
if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
1087
/* delete retry timer */
1088
RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1090
/* Save Replay counter, it will use to construct message 2 */
1091
NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
1092
LEN_KEY_DESC_REPLAY);
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 */
1102
/* open 802.1x port control and privacy filter */
1103
pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1104
pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1106
STA_PORT_SECURED(pAd);
1107
/* Indicate Connected for GUI */
1108
pAd->IndicateMediaState = NdisMediaStateConnected;
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)));
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),
1121
CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);
1123
DBGPRINT(RT_DEBUG_TRACE,
1124
("<=== PeerGroupMsg1Action: sned group message 2\n"));
1128
==========================================================================
1130
When receiving the last packet of 2-way groupkey handshake.
1132
==========================================================================
1134
void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
1135
struct rt_mac_table_entry *pEntry,
1136
void * Msg, u32 MsgLen)
1141
struct rt_eapol_packet * pMsg2;
1142
u8 group_cipher = Ndis802_11WEPDisabled;
1144
DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
1147
if ((!pEntry) || (!pEntry->ValidAsCLI))
1151
(LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
1152
MAX_LEN_OF_RSNIE - 2))
1155
if (pEntry->WpaState != AS_PTKINITDONE)
1159
pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
1160
Len = MsgLen - LENGTH_802_1_H;
1162
/* Sanity Check peer group message 2 - Replay Counter, MIC */
1163
if (PeerWpaMessageSanity
1164
(pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
1167
/* 3. upgrade state */
1169
RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1170
pEntry->GTKState = REKEY_ESTABLISHED;
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,
1181
DBGPRINT(RT_DEBUG_OFF,
1182
("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1184
GetAuthMode(pEntry->AuthMode),
1186
GetEncryptType(pEntry->WepStatus),
1187
group_cipher, GetEncryptType(group_cipher)));
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,
1196
DBGPRINT(RT_DEBUG_OFF,
1197
("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1199
GetAuthMode(pEntry->AuthMode),
1201
GetEncryptType(pEntry->WepStatus),
1202
group_cipher, GetEncryptType(group_cipher)));
1208
========================================================================
1210
Routine Description:
1211
Classify WPA EAP message type
1214
EAPType Value of EAP message type
1215
MsgType Internal Message definition for MLME state machine
1218
TRUE Found appropriate message type
1219
FALSE No appropriate message type
1221
IRQL = DISPATCH_LEVEL
1224
All these constants are defined in wpa.h
1225
For supplicant, there is only EAPOL Key message available
1227
========================================================================
1229
BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
1233
*MsgType = MT2_EAPPacket;
1236
*MsgType = MT2_EAPOLStart;
1239
*MsgType = MT2_EAPOLLogoff;
1242
*MsgType = MT2_EAPOLKey;
1245
*MsgType = MT2_EAPOLASFAlert;
1254
========================================================================
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.
1261
It is used to generate PTK, GTK or some specific random value.
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
1273
u8 *output - the calculated result
1276
802.11i-2004 Annex H.3
1278
========================================================================
1284
u8 * data, int data_len, u8 * output, int len)
1288
int currentindex = 0;
1291
/* Allocate memory for input */
1292
os_alloc_mem(NULL, (u8 **) & input, 1024);
1294
if (input == NULL) {
1295
DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
1298
/* Generate concatenation input */
1299
NdisMoveMemory(input, prefix, prefix_len);
1301
/* Concatenate a single octet containing 0 */
1302
input[prefix_len] = 0;
1304
/* Concatenate specific data */
1305
NdisMoveMemory(&input[prefix_len + 1], data, data_len);
1306
total_len = prefix_len + 1 + data_len;
1308
/* Concatenate a single octet containing 0 */
1309
/* This octet shall be update later */
1310
input[total_len] = 0;
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],
1320
/* update the last octet */
1321
input[total_len - 1]++;
1323
os_free_mem(NULL, input);
1327
* F(P, S, c, i) = U1 xor U2 xor ... Uc
1328
* U1 = PRF(P, S || Int(i))
1333
static void F(char *password, unsigned char *ssid, int ssidlength,
1334
int iterations, int count, unsigned char *output)
1336
unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
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 */
1348
memcpy(output, digest1, SHA1_DIGEST_SIZE);
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);
1355
/* output = output xor Un */
1356
for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1357
output[j] ^= digest[j];
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
1368
int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
1370
if ((strlen(password) > 63) || (ssidlength > 32))
1373
F(password, ssid, ssidlength, 4096, 1, output);
1374
F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
1379
========================================================================
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.
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)
1395
Output pointer to the PTK
1398
Refer to IEEE 802.11i-2004 8.5.1.2
1400
========================================================================
1402
void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
1407
u8 * SA, u8 * output, u32 len)
1409
u8 concatenation[76];
1413
{ 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
1414
'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
1417
/* initiate the concatenation input */
1418
NdisZeroMemory(temp, sizeof(temp));
1419
NdisZeroMemory(concatenation, 76);
1421
/* Get smaller address */
1422
if (RTMPCompareMemory(SA, AA, 6) == 1)
1423
NdisMoveMemory(concatenation, AA, 6);
1425
NdisMoveMemory(concatenation, SA, 6);
1428
/* Get larger address */
1429
if (RTMPCompareMemory(SA, AA, 6) == 1)
1430
NdisMoveMemory(&concatenation[CurrPos], SA, 6);
1432
NdisMoveMemory(&concatenation[CurrPos], AA, 6);
1434
/* store the larger mac address for backward compatible of */
1435
/* ralink proprietary STA-key issue */
1436
NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
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);
1445
NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
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);
1454
NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
1457
hex_dump("concatenation=", concatenation, 76);
1459
/* Use PRF to generate PTK */
1460
PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
1465
========================================================================
1467
Routine Description:
1468
Generate random number by software.
1471
pAd - pointer to our pAdapter context
1472
macAddr - pointer to local MAC address
1477
802.1ii-2004 Annex H.5
1479
========================================================================
1481
void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
1484
u8 local[80], KeyCounter[32];
1486
unsigned long CurrentTime;
1488
{ 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };
1490
/* Zero the related information */
1491
NdisZeroMemory(result, 80);
1492
NdisZeroMemory(local, 80);
1493
NdisZeroMemory(KeyCounter, 32);
1495
for (i = 0; i < 32; i++) {
1496
/* copy the local MAC address */
1497
COPY_MAC_ADDR(local, macAddr);
1498
curr = MAC_ADDR_LEN;
1500
/* concatenate the current time */
1501
NdisGetSystemUpTime(&CurrentTime);
1502
NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
1503
curr += sizeof(CurrentTime);
1505
/* concatenate the last result */
1506
NdisMoveMemory(&local[curr], result, 32);
1509
/* concatenate a variable */
1510
NdisMoveMemory(&local[curr], &i, 2);
1513
/* calculate the result */
1514
PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
1517
NdisMoveMemory(random, result, 32);
1521
========================================================================
1523
Routine Description:
1524
Build cipher suite in RSN-IE.
1525
It only shall be called by RTMPMakeRSNIE.
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
1538
========================================================================
1540
static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
1543
IN BOOLEAN bMixCipher,
1545
u8 *pRsnIe, u8 * rsn_len)
1551
/* decide WPA2 or WPA1 */
1552
if (ElementID == Wpa2Ie) {
1553
struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;
1555
/* Assign the verson as 1 */
1556
pRsnie_cipher->version = 1;
1558
switch (WepStatus) {
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,
1565
*rsn_len = sizeof(struct rt_rsnie2);
1569
case Ndis802_11Encryption3Enabled:
1571
NdisMoveMemory(pRsnie_cipher->mcast,
1574
NdisMoveMemory(pRsnie_cipher->mcast,
1576
pRsnie_cipher->ucount = 1;
1577
NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1579
*rsn_len = sizeof(struct rt_rsnie2);
1582
/* TKIP-AES mix mode */
1583
case Ndis802_11Encryption4Enabled:
1584
NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
1587
/* Insert WPA2 TKIP as the first pairwise cipher */
1588
if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
1589
NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
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,
1599
/* Insert WPA2 AES as the first pairwise cipher */
1600
NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1604
pRsnie_cipher->ucount = PairwiseCnt;
1605
*rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
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,
1618
case Ndis802_11GroupWEP104Enabled:
1619
NdisMoveMemory(pRsnie_cipher->mcast,
1620
OUI_WPA2_WEP104, 4);
1624
/* swap for big-endian platform */
1625
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1626
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1628
struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;
1630
/* Assign OUI and version */
1631
NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
1632
pRsnie_cipher->version = 1;
1634
switch (WepStatus) {
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,
1641
*rsn_len = sizeof(struct rt_rsnie);
1645
case Ndis802_11Encryption3Enabled:
1647
NdisMoveMemory(pRsnie_cipher->mcast,
1650
NdisMoveMemory(pRsnie_cipher->mcast,
1652
pRsnie_cipher->ucount = 1;
1653
NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1655
*rsn_len = sizeof(struct rt_rsnie);
1658
/* TKIP-AES mix mode */
1659
case Ndis802_11Encryption4Enabled:
1660
NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
1663
/* Insert WPA TKIP as the first pairwise cipher */
1664
if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
1665
NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
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,
1675
/* Insert WPA AES as the first pairwise cipher */
1676
NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1680
pRsnie_cipher->ucount = PairwiseCnt;
1681
*rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
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,
1694
case Ndis802_11GroupWEP104Enabled:
1695
NdisMoveMemory(pRsnie_cipher->mcast,
1700
/* swap for big-endian platform */
1701
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1702
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1707
========================================================================
1709
Routine Description:
1710
Build AKM suite in RSN-IE.
1711
It only shall be called by RTMPMakeRSNIE.
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
1723
========================================================================
1725
static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
1729
u8 *pRsnIe, u8 * rsn_len)
1731
struct rt_rsnie_auth *pRsnie_auth;
1732
u8 AkmCnt = 1; /* default as 1 */
1734
pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));
1736
/* decide WPA2 or WPA1 */
1737
if (ElementID == Wpa2Ie) {
1740
case Ndis802_11AuthModeWPA2:
1741
case Ndis802_11AuthModeWPA1WPA2:
1742
NdisMoveMemory(pRsnie_auth->auth[0].oui,
1743
OUI_WPA2_8021X_AKM, 4);
1746
case Ndis802_11AuthModeWPA2PSK:
1747
case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1748
NdisMoveMemory(pRsnie_auth->auth[0].oui,
1749
OUI_WPA2_PSK_AKM, 4);
1758
case Ndis802_11AuthModeWPA:
1759
case Ndis802_11AuthModeWPA1WPA2:
1760
NdisMoveMemory(pRsnie_auth->auth[0].oui,
1761
OUI_WPA_8021X_AKM, 4);
1764
case Ndis802_11AuthModeWPAPSK:
1765
case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1766
NdisMoveMemory(pRsnie_auth->auth[0].oui,
1767
OUI_WPA_PSK_AKM, 4);
1770
case Ndis802_11AuthModeWPANone:
1771
NdisMoveMemory(pRsnie_auth->auth[0].oui,
1772
OUI_WPA_NONE_AKM, 4);
1780
pRsnie_auth->acount = AkmCnt;
1781
pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
1783
/* update current RSNIE length */
1784
(*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));
1789
========================================================================
1791
Routine Description:
1792
Build capability in RSN-IE.
1793
It only shall be called by RTMPMakeRSNIE.
1796
pAd - pointer to our pAdapter context
1797
ElementID - indicate the WPA1 or WPA2
1798
apidx - indicate the interface index
1804
========================================================================
1806
static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
1809
u8 *pRsnIe, u8 * rsn_len)
1811
RSN_CAPABILITIES *pRSN_Cap;
1813
/* it could be ignored in WPA1 mode */
1814
if (ElementID == WpaIe)
1817
pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));
1819
pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
1821
(*rsn_len) += sizeof(RSN_CAPABILITIES); /* update current RSNIE length */
1826
========================================================================
1828
Routine Description:
1829
Build RSN IE context. It is not included element-ID and length.
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
1841
========================================================================
1843
void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
1844
u32 AuthMode, u32 WepStatus, u8 apidx)
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 */
1850
BOOLEAN bMixCipher = FALSE; /* indicate the pairwise and group cipher are different */
1852
WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES; /* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */
1854
rsnielen_cur_p = NULL;
1855
rsnielen_ex_cur_p = NULL;
1859
if (pAd->StaCfg.WpaSupplicantUP !=
1860
WPA_SUPPLICANT_DISABLE) {
1861
if (AuthMode < Ndis802_11AuthModeWPA)
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)
1873
DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));
1875
/* Zero RSNIE context */
1876
pAd->StaCfg.RSNIE_Len = 0;
1877
NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
1879
/* Pointer to RSNIE */
1880
rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
1881
pRsnIe = pAd->StaCfg.RSN_IE;
1883
bMixCipher = pAd->StaCfg.bMixCipher;
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;
1895
PrimaryRsnie = Wpa2Ie;
1898
/* Build the primary RSNIE */
1899
/* 1. insert cipher suite */
1900
RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
1901
FlexibleCipher, pRsnIe, &p_offset);
1904
RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
1907
/* 3. insert capability */
1908
RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
1911
/* 4. update the RSNIE length */
1912
*rsnielen_cur_p = p_offset;
1914
hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
1919
==========================================================================
1921
Check whether the received frame is EAP frame.
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
1931
TRUE - This frame is EAP frame
1933
==========================================================================
1935
BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
1936
struct rt_mac_table_entry *pEntry,
1938
unsigned long DataByteCount, u8 FromWhichBSSID)
1940
unsigned long Body_len;
1943
if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
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)) {
1952
/* Skip 2-bytes EAPoL type */
1953
if (NdisEqualMemory(EAPOL, pData, 2)) {
1958
switch (*(pData + 1)) {
1960
Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1961
DBGPRINT(RT_DEBUG_TRACE,
1962
("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
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,
1974
pEntry->EnqueueEapolStartTimerRunning =
1975
EAPOL_START_DISABLE;
1979
DBGPRINT(RT_DEBUG_TRACE,
1980
("Receive EAPOLLogoff frame, TYPE = 2 \n"));
1983
Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1984
DBGPRINT(RT_DEBUG_TRACE,
1985
("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
1989
DBGPRINT(RT_DEBUG_TRACE,
1990
("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
2000
==========================================================================
2002
Report the EAP message type
2005
msg - EAPOL_PAIR_MSG_1
2015
==========================================================================
2017
char *GetEapolMsgType(char msg)
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";
2032
return "Invalid Message";
2036
========================================================================
2038
Routine Description:
2039
Check Sanity RSN IE of EAPoL message
2045
========================================================================
2047
BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
2050
struct rt_mac_table_entry *pEntry, u8 * Offset)
2054
struct rt_eid * pEid;
2055
BOOLEAN result = FALSE;
2061
while (len > sizeof(struct rt_rsnie2)) {
2062
pEid = (struct rt_eid *) pVIE;
2064
if ((pEid->Eid == IE_WPA)
2065
&& (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
2066
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
2067
|| pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
2070
(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
2071
&& (pEntry->RSNIE_Len == (pEid->Len + 2))) {
2075
*Offset += (pEid->Len + 2);
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)
2086
(pEid->Octet, &pEntry->RSN_IE[2],
2087
pEntry->RSNIE_Len - 2))) {
2092
*Offset += (pEid->Len + 2);
2097
pVIE += (pEid->Len + 2);
2098
len -= (pEid->Len + 2);
2106
========================================================================
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
2119
========================================================================
2121
BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
2126
IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
2128
struct rt_kde_encap * pKDE = NULL;
2129
u8 *pMyKeyData = pKeyData;
2130
u8 KeyDataLength = KeyDataLen;
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 */
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,
2147
DBGPRINT(RT_DEBUG_ERROR,
2148
("RSN_IE Different in msg %d of 4-way handshake!\n",
2150
hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
2151
hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
2156
if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
2157
WpaShowAllsuite(pMyKeyData, skip_offset);
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",
2170
DBGPRINT(RT_DEBUG_TRACE,
2171
("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
2173
/*hex_dump("remain data", pMyKeyData, KeyDataLength); */
2175
/* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
2177
&& (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
2178
if (KeyDataLength >= 8) /* KDE format exclude GTK length */
2180
pKDE = (struct rt_kde_encap *) pMyKeyData;
2182
DefaultIdx = pKDE->GTKEncap.Kid;
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"));
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",
2200
DBGPRINT(RT_DEBUG_ERROR,
2201
("ERROR: KDE format length is too short \n"));
2205
DBGPRINT(RT_DEBUG_TRACE,
2206
("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
2207
DefaultIdx, GTKLEN));
2212
} else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
2213
DefaultIdx = GroupKeyIndex;
2214
DBGPRINT(RT_DEBUG_TRACE,
2215
("GTK DefaultKeyID=%d \n", DefaultIdx));
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)));
2227
struct rt_cipher_key *pSharedKey;
2229
/* set key material, TxMic and RxMic */
2230
NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
2231
pAd->StaCfg.DefaultKeyId = DefaultIdx;
2233
pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
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],
2241
NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
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;
2257
/* Update group key information to ASIC Shared Key Table */
2258
AsicAddSharedKeyEntry(pAd,
2260
pAd->StaCfg.DefaultKeyId,
2261
pSharedKey->CipherAlg,
2263
pSharedKey->TxMic, pSharedKey->RxMic);
2265
/* Update ASIC WCID attribute table and IVEIV table */
2266
RTMPAddWcidAttributeEntry(pAd,
2268
pAd->StaCfg.DefaultKeyId,
2269
pSharedKey->CipherAlg, NULL);
2277
========================================================================
2279
Routine Description:
2280
Construct EAPoL message for WPA handshaking
2281
Its format is below,
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
+--------------------+
2314
pAd Pointer to our adapter
2321
========================================================================
2323
void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
2324
u8 GroupKeyWepStatus,
2331
u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
2333
BOOLEAN bWPA2 = FALSE;
2336
/* Choose WPA2 or not */
2337
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2338
(pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2341
/* Init Packet and Fill header */
2342
pMsg->ProVer = EAPOL_VER;
2343
pMsg->ProType = EAPOLKey;
2345
/* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
2346
SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
2348
/* Fill in EAPoL descriptor */
2350
pMsg->KeyDesc.Type = WPA2_KEY_DESC;
2352
pMsg->KeyDesc.Type = WPA1_KEY_DESC;
2354
/* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
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. */
2359
(((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
2360
|| (GroupKeyWepStatus ==
2361
Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
2362
: (DESC_TYPE_TKIP));
2365
pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
2367
/* Specify Key Type as Group(0) or Pairwise(1) */
2368
if (MsgType >= EAPOL_GROUP_MSG_1)
2369
pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
2371
pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
2373
/* Specify Key Index, only group_msg1_WPA1 */
2374
if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
2375
pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
2377
if (MsgType == EAPOL_PAIR_MSG_3)
2378
pMsg->KeyDesc.KeyInfo.Install = 1;
2380
if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
2381
|| (MsgType == EAPOL_GROUP_MSG_1))
2382
pMsg->KeyDesc.KeyInfo.KeyAck = 1;
2384
if (MsgType != EAPOL_PAIR_MSG_1)
2385
pMsg->KeyDesc.KeyInfo.KeyMic = 1;
2387
if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
2388
(!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
2389
pMsg->KeyDesc.KeyInfo.Secure = 1;
2392
if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
2393
(MsgType == EAPOL_GROUP_MSG_1))) {
2394
pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
2396
/* key Information element has done. */
2397
*(u16 *) (&pMsg->KeyDesc.KeyInfo) =
2398
cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));
2400
/* Fill in Key Length */
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 :
2409
/* the length of pairwise key cipher */
2410
pMsg->KeyDesc.KeyLength[1] =
2411
((pEntry->WepStatus ==
2412
Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
2417
/* Fill in replay counter */
2418
NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
2419
LEN_KEY_DESC_REPLAY);
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);
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],
2435
pMsg->KeyDesc.KeyIv[15] += 2;
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);
2443
/* Clear Key MIC field for MIC calculation later */
2444
NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
2446
ConstructEapolKeyData(pEntry,
2450
DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);
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);
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)));
2470
========================================================================
2472
Routine Description:
2473
Construct the Key Data field of EAPoL message
2476
pAd Pointer to our adapter
2484
========================================================================
2486
void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
2487
u8 GroupKeyWepStatus,
2493
u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
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;
2502
/* Choose WPA2 or not */
2503
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2504
(pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2505
bWPA2Capable = TRUE;
2507
if (MsgType == EAPOL_PAIR_MSG_1 ||
2508
MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
2511
/* allocate memory pool */
2512
os_alloc_mem(NULL, (u8 **) & mpool, 1500);
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);
2522
NdisZeroMemory(Key_Data, 512);
2523
SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
2526
/* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
2528
&& ((MsgType == EAPOL_PAIR_MSG_2)
2529
|| (MsgType == EAPOL_PAIR_MSG_3))) {
2530
u8 *pmkid_ptr = NULL;
2533
RTMPInsertRSNIE(&Key_Data[data_offset],
2535
RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
2538
/* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
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;
2545
if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2546
Key_Data[data_offset + 1] = 0x16; /* 4+2+16(OUI+DataType+DataField) */
2548
Key_Data[data_offset + 1] = 0x26; /* 4+2+32(OUI+DataType+DataField) */
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;
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 */
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)) {
2568
if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2569
NdisMoveMemory(&Key_Data[data_offset], GTK,
2571
data_offset += LEN_AES_KEY;
2573
NdisMoveMemory(&Key_Data[data_offset], GTK,
2575
data_offset += TKIP_GTK_LENGTH;
2578
GTK_Included = TRUE;
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 */
2584
/*hex_dump("GTK_Included", Key_Data, data_offset); */
2586
if ((keyDescVer == DESC_TYPE_AES)) {
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. */
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) {
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;
2606
data_offset += pad_len;
2609
AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
2610
data_offset, Rc4GTK);
2611
/* AES wrap function will grow 8 bytes in length */
2614
/* Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
2615
using the KEK field from the derived PTK. */
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. */
2621
/* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
2622
NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
2624
NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
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,
2630
WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
2631
Key_Data, data_offset);
2634
NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
2636
NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
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);
2643
os_free_mem(NULL, mpool);
2648
========================================================================
2650
Routine Description:
2651
Calcaulate MIC. It is used during 4-ways handsharking.
2654
pAd - pointer to our pAdapter context
2655
PeerWepStatus - indicate the encryption type
2661
========================================================================
2663
static void CalculateMIC(u8 KeyDescVer,
2664
u8 * PTK, struct rt_eapol_packet * pMsg)
2667
unsigned long FrameLen = 0;
2668
u8 mic[LEN_KEY_DESC_MIC];
2671
/* allocate memory for MIC calculation */
2672
os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);
2674
if (OutBuffer == NULL) {
2675
DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
2678
/* make a frame for calculating MIC. */
2679
MakeOutgoingFrame(OutBuffer, &FrameLen,
2680
CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
2683
NdisZeroMemory(mic, sizeof(mic));
2686
if (KeyDescVer == DESC_TYPE_AES) {
2687
HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
2689
NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
2691
HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
2695
/* store the calculated MIC */
2696
NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
2698
os_free_mem(NULL, OutBuffer);
2702
========================================================================
2704
Routine Description:
2705
Some received frames can't decrypt by Asic, so decrypt them by software.
2708
pAd - pointer to our pAdapter context
2709
PeerWepStatus - indicate the encryption type
2712
NDIS_STATUS_SUCCESS - decryption successful
2713
NDIS_STATUS_FAILURE - decryption failure
2715
========================================================================
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)
2722
struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
2724
/* handle WEP decryption */
2725
if (GroupCipher == Ndis802_11Encryption1Enabled) {
2726
if (RTMPSoftDecryptWEP
2727
(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2730
/*Minus IV[4] & ICV[4] */
2731
pRxWI->MPDUtotalByteCount -= 8;
2733
DBGPRINT(RT_DEBUG_ERROR,
2734
("ERROR : Software decrypt WEP data fails.\n"));
2735
/* give up this frame */
2736
return NDIS_STATUS_FAILURE;
2739
/* handle TKIP decryption */
2740
else if (GroupCipher == Ndis802_11Encryption2Enabled) {
2741
if (RTMPSoftDecryptTKIP
2742
(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
2745
/*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
2746
pRxWI->MPDUtotalByteCount -= 20;
2748
DBGPRINT(RT_DEBUG_ERROR,
2749
("ERROR : RTMPSoftDecryptTKIP Failed\n"));
2750
/* give up this frame */
2751
return NDIS_STATUS_FAILURE;
2754
/* handle AES decryption */
2755
else if (GroupCipher == Ndis802_11Encryption3Enabled) {
2756
if (RTMPSoftDecryptAES
2757
(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2760
/*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
2761
pRxWI->MPDUtotalByteCount -= 16;
2763
DBGPRINT(RT_DEBUG_ERROR,
2764
("ERROR : RTMPSoftDecryptAES Failed\n"));
2765
/* give up this frame */
2766
return NDIS_STATUS_FAILURE;
2769
/* give up this frame */
2770
return NDIS_STATUS_FAILURE;
2773
return NDIS_STATUS_SUCCESS;
2777
u8 *GetSuiteFromRSNIE(u8 *rsnie,
2778
u32 rsnie_len, u8 type, u8 * count)
2780
struct rt_eid * pEid;
2784
struct rt_rsnie_auth *pAkm;
2786
BOOLEAN isWPA2 = FALSE;
2788
pEid = (struct rt_eid *) rsnie;
2789
len = rsnie_len - 2; /* exclude IE and length */
2790
pBuf = (u8 *)& pEid->Octet[0];
2792
/* set default value */
2796
if ((len <= 0) || (pEid->Len != len)) {
2797
DBGPRINT_ERR("%s : The length is invalid\n", __func__);
2800
/* Check WPA or WPA2 */
2801
if (pEid->Eid == IE_WPA) {
2802
struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
2805
if (len < sizeof(struct rt_rsnie)) {
2806
DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__);
2809
/* Get the count of pairwise cipher */
2810
ucount = cpu2le16(pRsnie->ucount);
2812
DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2815
/* Get the group cipher */
2816
if (type == GROUP_SUITE) {
2818
return pRsnie->mcast;
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",
2826
return pRsnie->ucast[0].oui;
2829
offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));
2831
} else if (pEid->Eid == IE_RSN) {
2832
struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
2837
if (len < sizeof(struct rt_rsnie2)) {
2838
DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__);
2841
/* Get the count of pairwise cipher */
2842
ucount = cpu2le16(pRsnie->ucount);
2844
DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2847
/* Get the group cipher */
2848
if (type == GROUP_SUITE) {
2850
return pRsnie->mcast;
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",
2858
return pRsnie->ucast[0].oui;
2861
offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));
2864
DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid);
2868
/* skip group cipher and pairwise cipher suite */
2872
if (len < sizeof(struct rt_rsnie_auth)) {
2873
DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__);
2876
/* pointer to AKM count */
2877
pAkm = (struct rt_rsnie_auth *)pBuf;
2879
/* Get the count of pairwise cipher */
2880
acount = cpu2le16(pAkm->acount);
2882
DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount);
2885
/* Get the AKM suite */
2886
if (type == AKM_SUITE) {
2887
DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
2890
return pAkm->auth[0].oui;
2892
offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));
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);
2904
if (type == PMKID_LIST) {
2909
DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__);
2914
/*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
2919
void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
2924
hex_dump("RSNIE", rsnie, rsnie_len);
2927
pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count);
2928
if (pSuite != NULL) {
2929
hex_dump("group cipher", pSuite, 4 * count);
2931
/* pairwise cipher */
2932
pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count);
2933
if (pSuite != NULL) {
2934
hex_dump("pairwise cipher", pSuite, 4 * count);
2937
pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count);
2938
if (pSuite != NULL) {
2939
hex_dump("AKM suite", pSuite, 4 * count);
2942
pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count);
2943
if (pSuite != NULL) {
2944
hex_dump("PMKID", pSuite, LEN_PMKID);
2949
void RTMPInsertRSNIE(u8 *pFrameBuf,
2950
unsigned long *pFrameLen,
2953
u8 *pmkid_ptr, u8 pmkid_len)
2956
unsigned long TempLen = 0;
2961
u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
2963
pTmpBuf = pFrameBuf;
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;
2969
pmk_count = (pmkid_len >> 4);
2970
pmk_count = cpu2le16(pmk_count);
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));
2977
if (rsnie_len != 0) {
2979
total_len = rsnie_len;
2981
if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
2983
total_len += extra_len;
2986
/* construct RSNIE body */
2987
MakeOutgoingFrame(pTmpBuf, &TempLen,
2990
rsnie_len, rsnie_ptr, END_OF_ARGS);
2993
*pFrameLen = *pFrameLen + TempLen;
2995
if (ie_num == IE_RSN) {
2996
/* Insert PMKID-List field */
2997
if (extra_len > 0) {
2998
MakeOutgoingFrame(pTmpBuf, &TempLen,
3000
pmkid_len, pmkid_ptr,
3004
*pFrameLen = *pFrameLen + TempLen;