wpa.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,629 行 · 第 1/5 页
C
1,629 行
/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2005, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
Module Name:
wpa.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Jan Lee 03-07-22 Initial
*/
#include "rt_config.h"
static UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};
static UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
static UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
static UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
static UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
static UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
static UCHAR prf_input[1024];
#ifdef RTL865X_SOC
static inline VOID ApCliWpaMacHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN UCHAR wep,
IN PUCHAR pAddr1,
IN PUCHAR pAddr2);
static inline VOID Wpa2PairMsg3Action(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem,
IN INT IfIndex);
static inline BOOLEAN ParseKeyData(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKeyData,
IN UCHAR KeyDataLen,
IN INT IfIndex,
IN UCHAR bPairewise);
#endif /* endif ifdef RTL865X_SOC */
#define ROUND_UP(__x, __y) \
(((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))\
BOOLEAN WPAMsgTypeSubst(
IN UCHAR EAPType,
OUT ULONG *MsgType)
{
DBGPRINT(RT_DEBUG_TRACE, "WPAMsgTypeSubst (EAPType=%d)\n", EAPType);
switch(EAPType)
{
case EAPPacket:
*MsgType = MACHINE_TYPE_EAPPacket;
break;
case EAPOLStart:
*MsgType = MACHINE_TYPE_EAPOLStart;
break;
case EAPOLLogoff:
*MsgType = MACHINE_TYPE_EAPOLLogoff;
break;
case EAPOLKey:
*MsgType = MACHINE_TYPE_EAPOLKey;
break;
case EAPOLASFAlert:
*MsgType = MACHINE_TYPE_EAPOLASFAlert;
break;
default:
DBGPRINT(RT_DEBUG_TRACE, "Unknown WPA MsgType\n");
return FALSE;
}
return TRUE;
}
/*
==========================================================================
Description:
association state machine init, including state transition and timer init
Parameters:
S - pointer to the association state machine
==========================================================================
*/
VOID WpaStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE *S,
OUT STATE_MACHINE_FUNC Trans[])
{
StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_WPA_PTK_STATE, MAX_WPA_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PTK, WPA_MACHINE_BASE);
StateMachineSetAction(S, WPA_PTK, MACHINE_TYPE_EAPPacket, (STATE_MACHINE_FUNC)WpaEAPPacketAction);
StateMachineSetAction(S, WPA_PTK, MACHINE_TYPE_EAPOLStart, (STATE_MACHINE_FUNC)WpaEAPOLStartAction);
StateMachineSetAction(S, WPA_PTK, MACHINE_TYPE_EAPOLLogoff, (STATE_MACHINE_FUNC)WpaEAPOLLogoffAction);
StateMachineSetAction(S, WPA_PTK, MACHINE_TYPE_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
StateMachineSetAction(S, WPA_PTK, MACHINE_TYPE_EAPOLASFAlert, (STATE_MACHINE_FUNC)WpaEAPOLASFAlertAction);
}
/*
==========================================================================
Description:
Port Access Control Inquiry function. Return entry's Privacy and Wpastate.
Also check if AP needs to initilize 4-way handshake.
Return:
pEntry
==========================================================================
*/
MAC_TABLE_ENTRY *PACInquiry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
OUT NDIS_802_11_PRIVACY_FILTER *Privacy,
OUT WPA_STATE *WpaState)
{
MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY*)NULL;
*Privacy = Ndis802_11PrivFilterAcceptAll;
*WpaState = AS_NOTUSE;
if (MAC_ADDR_IS_GROUP(pAddr))
{// mcast & broadcast address
}
else
{// unicast address
pEntry = MacTableLookup(pAd, pAddr);
if (pEntry)
{
*Privacy = pEntry->PrivacyFilter;
*WpaState = pEntry->WpaState;
}
}
return pEntry;
}
/*
==========================================================================
Description:
Return:
TRUE if this is EAP frame
FALSE otherwise
==========================================================================
*/
BOOLEAN RTMPCheckWPAframe(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR pHeader,
IN ULONG DataByteCount,
IN UCHAR Offset)
{
PUCHAR pData;
DBGPRINT(RT_DEBUG_INFO, "RTMPCheckWPAframe ===>\n");
if (DataByteCount < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + Offset))
return FALSE;
pData = pHeader + LENGTH_802_11 + Offset;
DataByteCount -= (LENGTH_802_11 + Offset);
if (RTMPEqualMemory(SNAP_802_1H, pData, 6))
{
pData += 6;
}
if (RTMPEqualMemory(EAPOL, pData, 2))
{
pData += 2;
}
else
return FALSE;
switch (*(pData+1))
{
case EAPPacket:
DBGPRINT(RT_DEBUG_INFO, "Receive EAP-Packet frame, TYPE = 0 \n");
break;
case EAPOLStart:
DBGPRINT(RT_DEBUG_INFO, "Receive EAPOL-Start frame, TYPE = 1 \n");
break;
case EAPOLLogoff:
DBGPRINT(RT_DEBUG_INFO, "Receive EAPOLLogoff frame, TYPE = 2 \n");
break;
case EAPOLKey:
DBGPRINT(RT_DEBUG_INFO, "Receive EAPOL-Key frame, TYPE = 3, Length =%x\n", *(pData+2));
break;
case EAPOLASFAlert:
DBGPRINT(RT_DEBUG_INFO, "Receive EAPOLASFAlert frame, TYPE = 4 \n");
break;
default:
return FALSE;
}
return TRUE;
}
/*
==========================================================================
Description:
Check invalidity of multicast cipher selection in RSN IE.
Return:
TRUE if match
FALSE otherwise
==========================================================================
*/
BOOLEAN RTMPCheckMcast(
IN PRTMP_ADAPTER pAdapter,
IN PEID_STRUCT eid_ptr,
IN MAC_TABLE_ENTRY *pEntry)
{
pEntry->AuthMode = pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode;
if (eid_ptr->Len >= 6)
{
// WPA and WPA2 format not the same in RSN_IE
if (eid_ptr->Eid == IE_WPA)
{
if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPA1WPA2)
pEntry->AuthMode = Ndis802_11AuthModeWPA;
else if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK)
pEntry->AuthMode = Ndis802_11AuthModeWPAPSK;
if (RTMPEqualMemory(&eid_ptr->Octet[6], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[0][6], 4))
return TRUE;
}
else if (eid_ptr->Eid == IE_WPA2)
{
UCHAR IE_Idx = 0;
// When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure
if ((pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK))
IE_Idx = 1;
if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPA1WPA2)
pEntry->AuthMode = Ndis802_11AuthModeWPA2;
else if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK)
pEntry->AuthMode = Ndis802_11AuthModeWPA2PSK;
if (RTMPEqualMemory(&eid_ptr->Octet[2], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[IE_Idx][2], 4))
return TRUE;
}
}
DBGPRINT(RT_DEBUG_ERROR, "RTMPCheckMcast ==> WPAIE parsing error, WPAIE=%d\n", eid_ptr->Eid);
return FALSE;
}
/*
==========================================================================
Description:
Check invalidity of unicast cipher selection in RSN IE.
Return:
TRUE if match
FALSE otherwise
==========================================================================
*/
BOOLEAN RTMPCheckUcast(
IN PRTMP_ADAPTER pAdapter,
IN PEID_STRUCT eid_ptr,
IN MAC_TABLE_ENTRY *pEntry)
{
pEntry->WepStatus = pAdapter->PortCfg.MBSSID[pEntry->ApIdx].WepStatus;
if (eid_ptr->Len >= 16)
{
if (eid_ptr->Eid == IE_WPA)
{
if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].WepStatus == Ndis802_11Encryption4Enabled)
{// multiple cipher (TKIP/CCMP)
if (RTMPEqualMemory(&eid_ptr->Octet[12], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[0][12], 4))
{
pEntry->WepStatus = Ndis802_11Encryption2Enabled;
return TRUE;
}
else if (RTMPEqualMemory(&eid_ptr->Octet[12], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[0][16], 4))
{
pEntry->WepStatus = Ndis802_11Encryption3Enabled;
return TRUE;
}
}
else
{// single cipher
if (RTMPEqualMemory(&eid_ptr->Octet[12], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[0][12], 4))
return TRUE;
}
}
else if (eid_ptr->Eid == IE_WPA2)
{
UCHAR IE_Idx = 0;
// When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure
if ((pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK))
IE_Idx = 1;
if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].WepStatus == Ndis802_11Encryption4Enabled)
{// multiple cipher (TKIP/CCMP)
if (RTMPEqualMemory(&eid_ptr->Octet[8], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[IE_Idx][8], 4))
{
pEntry->WepStatus = Ndis802_11Encryption2Enabled;
return TRUE;
}
else if (RTMPEqualMemory(&eid_ptr->Octet[8], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[IE_Idx][12], 4))
{
pEntry->WepStatus = Ndis802_11Encryption3Enabled;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?