⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wpa.c

📁 华硕无线网卡 167G linux 驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************  * RT2x00 SourceForge Project - http://rt2x00.sourceforge.net              *  *                                                                         *  *   This program is free software; you can redistribute it and/or modify  *  *   it under the terms of the GNU General Public License as published by  *  *   the Free Software Foundation; either version 2 of the License, or     *  *   (at your option) any later version.                                   *  *                                                                         *  *   This program is distributed in the hope that it will be useful,       *  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *  *   GNU General Public License for more details.                          *  *                                                                         *  *   You should have received a copy of the GNU General Public License     *  *   along with this program; if not, write to the                         *  *   Free Software Foundation, Inc.,                                       *  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *  *                                                                         *  *   Licensed under the GNU GPL                                            *  *   Original code supplied under license from RaLink Inc, 2004.           *  ***************************************************************************//***************************************************************************  *	Module Name:	wpa.c * *	Abstract: * *	Revision History: *	Who		When		What *	--------	----------	------------------------------- *	Name		Date		Modification logs *	Jan Lee		2005-06-01	Release ***************************************************************************/#include "rt_config.h"UCHAR   CipherWpaPskTkip[] = {        0xDD, 0x16,             // RSN IE        0x00, 0x50, 0xf2, 0x01, // oui        0x01, 0x00,             // Version        0x00, 0x50, 0xf2, 0x02, // Multicast        0x01, 0x00,             // Number of unicast        0x00, 0x50, 0xf2, 0x02, // unicast        0x01, 0x00,             // number of authentication method        0x00, 0x50, 0xf2, 0x02  // authentication        };UCHAR   CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));UCHAR   CipherWpaPskAes[] = {        0xDD, 0x16,             // RSN IE        0x00, 0x50, 0xf2, 0x01, // oui        0x01, 0x00,             // Version        0x00, 0x50, 0xf2, 0x04, // Multicast        0x01, 0x00,             // Number of unicast        0x00, 0x50, 0xf2, 0x04, // unicast        0x01, 0x00,             // number of authentication method        0x00, 0x50, 0xf2, 0x02  // authentication        };UCHAR   CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));/*    ========================================================================        Routine Description:        Classify WPA EAP message type    Arguments:        EAPType     Value of EAP message type        MsgType     Internal Message definition for MLME state machine            Return Value:        TRUE        Found appropriate message type        FALSE       No appropriate message type    Note:        All these constants are defined in wpa.h        For supplicant, there is only EAPOL Key message avaliable            ========================================================================*/BOOLEAN WpaMsgTypeSubst(    IN  UCHAR   EAPType,    OUT ULONG   *MsgType)   {    switch (EAPType)    {        case EAPPacket:            *MsgType = EAP_MSG_TYPE_EAPPacket;            break;        case EAPOLStart:            *MsgType = EAP_MSG_TYPE_EAPOLStart;            break;        case EAPOLLogoff:            *MsgType = EAP_MSG_TYPE_EAPOLLogoff;            break;        case EAPOLKey:            *MsgType = EAP_MSG_TYPE_EAPOLKey;            break;        case EAPOLASFAlert:            *MsgType = EAP_MSG_TYPE_EAPOLASFAlert;            break;        default:            DBGPRINT(RT_DEBUG_ERROR, "WpaMsgTypeSubst : return FALSE; \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 WpaPskStateMachineInit(    IN  PRT2570ADAPTER   pAd,     IN  STATE_MACHINE *S,     OUT STATE_MACHINE_FUNC Trans[]) {    StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);    StateMachineSetAction(S, WPA_PSK_IDLE, EAP_MSG_TYPE_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);}/*    ==========================================================================    Description:        This is state machine function.         When receiving EAPOL packets which is  for 802.1x key management.         Use both in WPA, and WPAPSK case.         In this function, further dispatch to different functions according to the received packet.  3 categories are :           1.  normal 4-way pairwisekey and 2-way groupkey handshake          2.  MIC error (Countermeasures attack)  report packet from STA.          3.  Request for pairwise/group key update from STA    Return:    ==========================================================================*/VOID WpaEAPOLKeyAction(    IN  PRT2570ADAPTER   pAdapter,     IN  MLME_QUEUE_ELEM *Elem) {    INT             MsgType;    PKEY_DESCRIPTER pKeyDesc;    PHEADER_802_11 pHeader; //red        DBGPRINT(RT_DEBUG_TRACE, "-----> WpaEAPOLKeyAction\n");    pHeader	= (PHEADER_802_11) &Elem->Msg[0];//red	    // Get 802.11 header first    if( (pAdapter->PortCfg.CipherAlg == CIPHER_TKIP || pAdapter->PortCfg.CipherAlg == CIPHER_AES) && pHeader->Controlhead.Frame.Wep)	    pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + 8 + LENGTH_EAPOL_H)];    else		   pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];    // Sanity check, this should only happen in WPA-PSK mode    if (pAdapter->PortCfg.AuthMode != Ndis802_11AuthModeWPAPSK)        return;    // 0. Debug print all bit information    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Key Description Version %d\n", pKeyDesc->KeyInfo.KeyDescVer);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Key Type %d\n", pKeyDesc->KeyInfo.KeyType);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Key Index %d\n", pKeyDesc->KeyInfo.KeyIndex);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Install %d\n", pKeyDesc->KeyInfo.Install);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Key Ack %d\n", pKeyDesc->KeyInfo.KeyAck);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Key MIC %d\n", pKeyDesc->KeyInfo.KeyMic);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Secure %d\n", pKeyDesc->KeyInfo.Secure);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Error %d\n", pKeyDesc->KeyInfo.Error);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo Request %d\n", pKeyDesc->KeyInfo.Request);    DBGPRINT(RT_DEBUG_INFO, "KeyInfo DL %d\n", pKeyDesc->KeyInfo.DL);        // 1. Check EAPOL frame version and type    if( (pAdapter->PortCfg.CipherAlg == CIPHER_TKIP || pAdapter->PortCfg.CipherAlg == CIPHER_AES) && pHeader->Controlhead.Frame.Wep)//red    {    		if ((Elem->Msg[LENGTH_802_11+LENGTH_802_1_H + 8] != EAPOL_VER) || (pKeyDesc->Type != RSN_KEY_DESC))		{		        DBGPRINT(RT_DEBUG_ERROR, "   Key descripter does not match with WPA rule \n");		        return;    		}    }    else    {    		if ((Elem->Msg[LENGTH_802_11+LENGTH_802_1_H] != EAPOL_VER) || (pKeyDesc->Type != RSN_KEY_DESC))    		{		        DBGPRINT(RT_DEBUG_ERROR, "   Key descripter does not match with WPA rule \n");		        return;		}    }        // 2.Check Version for AES & TKIP    if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pKeyDesc->KeyInfo.KeyDescVer != DESC_TYPE_AES))    {        DBGPRINT(RT_DEBUG_ERROR, "   Key descripter version not match AES \n");        return;    }    else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pKeyDesc->KeyInfo.KeyDescVer != DESC_TYPE_TKIP))    {        DBGPRINT(RT_DEBUG_ERROR, "   Key descripter version not match TKIP \n");        return;    }    // First validate replay counter, only accept message with larger replay counter    if (memcmp(pKeyDesc->ReplayCounter, pAdapter->PortCfg.ReplayCounter, (size_t)LEN_KEY_DESC_REPLAY) <= 0)        return;    // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant    MsgType = EAPOL_MSG_INVALID;    if ((pKeyDesc->KeyInfo.KeyType == 1) &&        (pKeyDesc->KeyInfo.KeyIndex == 0) &&        (pKeyDesc->KeyInfo.KeyAck == 1) &&        (pKeyDesc->KeyInfo.KeyMic == 0) &&        (pKeyDesc->KeyInfo.Secure == 0) &&        (pKeyDesc->KeyInfo.Error == 0) &&        (pKeyDesc->KeyInfo.Request == 0))    {        MsgType = EAPOL_PAIR_MSG_1;        DBGPRINT(RT_DEBUG_ERROR, "Receive EAPOL Key Pairwise Message 1\n");    }    else if ((pKeyDesc->KeyInfo.KeyType == 1) &&        (pKeyDesc->KeyInfo.KeyIndex == 0) &&        (pKeyDesc->KeyInfo.KeyAck == 1) &&        (pKeyDesc->KeyInfo.KeyMic == 1) &&        (pKeyDesc->KeyInfo.Secure == 0) &&        (pKeyDesc->KeyInfo.Error == 0) &&        (pKeyDesc->KeyInfo.Request == 0))    {        MsgType = EAPOL_PAIR_MSG_3;        DBGPRINT(RT_DEBUG_ERROR, "Receive EAPOL Key Pairwise Message 3\n");    }    else if ((pKeyDesc->KeyInfo.KeyType == 0) &&        (pKeyDesc->KeyInfo.KeyIndex != 0) &&        (pKeyDesc->KeyInfo.KeyAck == 1) &&        (pKeyDesc->KeyInfo.KeyMic == 1) &&        (pKeyDesc->KeyInfo.Secure == 1) &&        (pKeyDesc->KeyInfo.Error == 0) &&        (pKeyDesc->KeyInfo.Request == 0))    {        MsgType = EAPOL_GROUP_MSG_1;        DBGPRINT(RT_DEBUG_ERROR, "Receive EAPOL Key Group Message 1\n");    }        // We will assume link is up (assoc suceess and port not secured).    // All state has to be able to process message from previous state    switch (pAdapter->PortCfg.WpaState)    {        case SS_START:            if (MsgType == EAPOL_PAIR_MSG_1)            {                WpaPairMsg1Action(pAdapter, Elem);                pAdapter->PortCfg.WpaState = SS_WAIT_MSG_3;            }            break;                        case SS_WAIT_MSG_3:            if (MsgType == EAPOL_PAIR_MSG_1)            {                WpaPairMsg1Action(pAdapter, Elem);                pAdapter->PortCfg.WpaState = SS_WAIT_MSG_3;            }            else if (MsgType == EAPOL_PAIR_MSG_3)            {                WpaPairMsg3Action(pAdapter, Elem);                pAdapter->PortCfg.WpaState = SS_WAIT_GROUP;            }            break;                        case SS_WAIT_GROUP:     // When doing group key exchange        case SS_FINISH:         // This happened when update group key            if (MsgType == EAPOL_PAIR_MSG_1)            {                WpaPairMsg1Action(pAdapter, Elem);                pAdapter->PortCfg.WpaState = SS_WAIT_MSG_3;                // Reset port secured variable                pAdapter->PortCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;            }            else if (MsgType == EAPOL_PAIR_MSG_3)            {                WpaPairMsg3Action(pAdapter, Elem);                pAdapter->PortCfg.WpaState = SS_WAIT_GROUP;                // Reset port secured variable                pAdapter->PortCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;            }            else if (MsgType == EAPOL_GROUP_MSG_1)            {                WpaGroupMsg1Action(pAdapter, Elem);                pAdapter->PortCfg.WpaState = SS_FINISH;            }            break;                        default:            break;                  }        DBGPRINT(RT_DEBUG_TRACE, "<----- WpaEAPOLKeyAction\n");}/*    ========================================================================        Routine Description:        Process Pairwise key 4-way handshaking    Arguments:        pAdapter    Pointer to our adapter        Elem        Message body            Return Value:        None            Note:            ========================================================================*/VOID    WpaPairMsg1Action(    IN  PRT2570ADAPTER   pAdapter,     IN  MLME_QUEUE_ELEM *Elem) {    PHEADER_802_11      pHeader;    UCHAR               PTK[80];    UCHAR               *OutBuffer = NULL;    HEADER_802_11       Header_802_11;    NDIS_STATUS         NStatus;    UCHAR               AckRate = RATE_2;    USHORT              AckDuration = 0;     ULONG               FrameLen = 0;    UCHAR               EAPHEAD[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};    PEAPOL_PACKET       pMsg1;    EAPOL_PACKET        Packet;    UCHAR               Mic[16];               DBGPRINT(RT_DEBUG_ERROR, "WpaPairMsg1Action ----->\n");        pHeader = (PHEADER_802_11) Elem->Msg;        // Save Data Length to pDesc for receiving packet, then put in outgoing frame   Data Len fields.    pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];        // Process message 1 from authenticator    // Key must be Pairwise key, already verified at callee.    // 1. Save Replay counter, it will use to verify message 3 and construct message 2    memcpy(pAdapter->PortCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);    // 2. Save ANonce    memcpy(pAdapter->PortCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);            // TSNonce <--- SNonce    // Generate random SNonce    GenRandom(pAdapter, pAdapter->PortCfg.SNonce);      // TPTK <--- Calc PTK(ANonce, TSNonce)    WpaCountPTK(pAdapter->PortCfg.PskKey.Key,           pAdapter->PortCfg.ANonce,        pAdapter->PortCfg.Bssid.Octet,         pAdapter->PortCfg.SNonce,         pAdapter->CurrentAddress,            PTK,         LEN_PTK);       // Save key to PTK entry    memcpy(pAdapter->PortCfg.PTK, PTK, LEN_PTK);        // =====================================    // Use Priority Ring & MiniportMMRequest    // =====================================    pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);    WpaMacHeaderInit(pAdapter, &Header_802_11, 0, &pAdapter->PortCfg.Bssid);    // ACK size is 14 include CRC, and its rate is based on real time information    AckRate = pAdapter->PortCfg.ExpectedACKRate[pAdapter->PortCfg.TxRate];    AckDuration = RTUSBCalcDuration(pAdapter, AckRate, 14);    Header_802_11.Controlhead.Duration = pAdapter->PortCfg.Dsifs + AckDuration;        // Zero message 2 body    memset(&Packet, 0, sizeof(Packet));    Packet.Version = EAPOL_VER;    Packet.Type    = EAPOLKey;    //    // Message 2 as  EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)    //    Packet.KeyDesc.Type = RSN_KEY_DESC;    // 1. Key descriptor version and appropriate RSN IE    if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)    {        Packet.KeyDesc.KeyInfo.KeyDescVer = 2;        Packet.KeyDesc.KeyDataLen[1] = CipherWpaPskAesLen;        memcpy(Packet.KeyDesc.KeyData, CipherWpaPskAes, CipherWpaPskAesLen);    }    else    // TKIP    {        Packet.KeyDesc.KeyInfo.KeyDescVer = 1;        Packet.KeyDesc.KeyDataLen[1] = CipherWpaPskTkipLen;        memcpy(Packet.KeyDesc.KeyData, CipherWpaPskTkip, CipherWpaPskTkipLen);    }    // Update packet length after decide Key data payload    Packet.Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];    // 2. Key Type PeerKey    Packet.KeyDesc.KeyInfo.KeyType = 1;    // 3. KeyMic field presented    Packet.KeyDesc.KeyInfo.KeyMic  = 1;    // 4. Fill SNonce    memcpy(Packet.KeyDesc.KeyNonce, pAdapter->PortCfg.SNonce, LEN_KEY_DESC_NONCE);    // 5. Key Replay Count    memcpy(Packet.KeyDesc.ReplayCounter, pAdapter->PortCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);        // Send EAPOL(0, 1, 0, 0, 0, K, 0, TSNonce, 0, MIC(TPTK), 0)    // Out buffer for transmitting message 2            NStatus = MlmeAllocateMemory(pAdapter, (PVOID)&OutBuffer);  //Get an unused nonpaged memory    if (NStatus != NDIS_STATUS_SUCCESS)         return;                     // Prepare EAPOL frame for MIC calculation    // Be careful, only EAPOL frame is counted for MIC calculation    MakeOutgoingFrame(OutBuffer, &FrameLen,        Packet.Len[1] + 4, &Packet,        END_OF_ARGS);	    // 5. Prepare and Fill MIC value    memset(Mic, 0, sizeof(Mic));    if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)    {        // AES        UCHAR digest[80];                    HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);        memcpy(Mic, digest, LEN_KEY_DESC_MIC);    }    else    {        INT i;#if 0        DBGPRINT_RAW(RT_DEBUG_TRACE, " PMK = ");        for (i = 0; i < 16; i++)            DBGPRINT_RAW(RT_DEBUG_TRACE, "%2x-", pAdapter->PortCfg.PskKey.Key[i]);        #endif        DBGPRINT_RAW(RT_DEBUG_INFO, "\n PTK = ");        for (i = 0; i < 64; i++)            DBGPRINT_RAW(RT_DEBUG_INFO, "%2x-", pAdapter->PortCfg.PTK[i]);        DBGPRINT_RAW(RT_DEBUG_INFO, "\n FrameLen = %d\n", FrameLen);                hmac_md5(PTK,  LEN_EAP_MICK, OutBuffer, FrameLen, Mic);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -