wpa.c

来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,629 行 · 第 1/5 页

C
1,629
字号
}            
//            *(USHORT *)&pMsg->KeyDesc.Keyinfo = SWAP16(*(USHORT *)&pMsg->KeyDesc.Keyinfo);
#endif
            // SECURE=1, REQUEST=0, ERROR=0
            if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
            PeerGroupMsg2Action(pAdapter, pEntry, &Elem->Msg[LENGTH_802_11+Offset], (Elem->MsgLen-LENGTH_802_11-Offset));
	    else if (((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || 
		      (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) 
		     && (pEntry->WpaState >=AS_PTKINITDONE) && (pEntry->GTKState == REKEY_NEGOTIATING))
                PeerGroupMsg2Action(pAdapter, pEntry, &Elem->Msg[LENGTH_802_11+Offset], (Elem->MsgLen-LENGTH_802_11-Offset));
            else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
            	Wpa2PeerPairMsg4Action(pAdapter, pEntry, Elem);
        }
        else if (!(pKeyDesc->Keyinfo.Secure) && !(pKeyDesc->Keyinfo.Error) && !(pKeyDesc->Keyinfo.Request))
        {
#ifdef BIG_ENDIAN
            // recovery original byte order, before forward Elem to another routine
{
			USHORT	tmpKeyinfo;

			NdisMoveMemory(&tmpKeyinfo, &pMsg->KeyDesc.Keyinfo, sizeof(USHORT)); 
			tmpKeyinfo = SWAP16(tmpKeyinfo);
			NdisMoveMemory(&pMsg->KeyDesc.Keyinfo, &tmpKeyinfo, sizeof(USHORT)); 
}

//            *(USHORT *)&pMsg->KeyDesc.Keyinfo = SWAP16(*(USHORT *)&pMsg->KeyDesc.Keyinfo);
#endif
            // general 4-way handshake step // SECURE=0, REQUEST=0 ,  ERROR= 0
            // Category 1
            if (pEntry->WpaState == AS_PTKSTART)
                PeerPairMsg2Action(pAdapter, pEntry, Elem);
            else if (pEntry->WpaState == AS_PTKINIT_NEGOTIATING)
                Wpa1PeerPairMsg4Action(pAdapter, pEntry, Elem);
        }
        else if (!(pKeyDesc->Keyinfo.Error) && (pKeyDesc->Keyinfo.Request))
        {
            // Category 3
            if (pKeyDesc->Keyinfo.KeyType == GROUPKEY)
            {
                DBGPRINT(RT_DEBUG_TRACE, "REQUEST=1, ERROR=0, update group key\n");
                GenRandom(pAdapter, pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GNonce, pEntry->ApIdx);
                for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
                {
                    if ((pAdapter->MacTab.Content[i].Valid == TRUE) && (pAdapter->MacTab.Content[i].WpaState == AS_PTKINITDONE)
                    	&& (pAdapter->MacTab.Content[i].ApIdx == pEntry->ApIdx))
                    {
                        pAdapter->MacTab.Content[i].GTKState = REKEY_NEGOTIATING;
                        WPAHardTransmit(pAdapter, &pAdapter->MacTab.Content[i]);
                    }
                }
            }
            else
            {
                DBGPRINT(RT_DEBUG_TRACE, "REQUEST=1, ERROR= 0, update pairwise key\n");
                pEntry->PairwiseKey.KeyLen = 0;
                pEntry->Sst = SST_ASSOC;
                if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2))
                    pEntry->WpaState = AS_INITPMK;  
                else if ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
                    pEntry->WpaState = AS_INITPSK;  
                pEntry->GTKState = REKEY_NEGOTIATING;
                
				pEntry->RetryTimer.expires = jiffies + WPA_RETRY_EXEC_INTV;
				pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
				WPAStart4WayHS(pAdapter, pEntry);
            }
        }
        else
        {
                //
        }
    }
}

VOID RTMPHandleSTAKey(
    IN PRTMP_ADAPTER    pAd, 
    IN PMAC_TABLE_ENTRY	pEntry,
    IN MLME_QUEUE_ELEM  *Elem) 
{
	ULONG				FrameLen = 0;
	PUCHAR				pOutBuffer = NULL;
	UCHAR				Header802_3[14];
	EAPOL_PACKET		Packet, EAPOLPKT;
	PEAPOL_PACKET		pSTAKey;
	PHEADER_802_11		pHeader;
	UCHAR				Offset = 0;
	ULONG				MICMsgLen;
	UCHAR				DA[MAC_ADDR_LEN];
	UCHAR				Key_Data[512];
	UCHAR				key_length;
	UCHAR				mic[LEN_KEY_DESC_MIC];
	UCHAR				digest[80];
	UCHAR				temp[64];
	PMAC_TABLE_ENTRY	pDaEntry;

    DBGPRINT(RT_DEBUG_TRACE, "==> RTMPHandleSTAKey\n");

    if (!pEntry)
		return;
	
	if ((pEntry->WpaState != AS_PTKINITDONE))
    {
        DBGPRINT(RT_DEBUG_ERROR, "Not expect calling STAKey hand shaking here");
        return;
    }

    pHeader = (PHEADER_802_11) Elem->Msg;

    if (pHeader->FC.SubType & 0x08)
        Offset += 2;
    
    pSTAKey = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset];	

    // Check Replay Counter
    if (!RTMPEqualMemory(pSTAKey->KeyDesc.RCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
    {
        DBGPRINT(RT_DEBUG_ERROR, "Replay Counter Different in STAKey handshake!! \n");
        DBGPRINT(RT_DEBUG_ERROR, "Receive : %d %d %d %d  \n", pSTAKey->KeyDesc.RCounter[0],pSTAKey->KeyDesc.RCounter[1],pSTAKey->KeyDesc.RCounter[2],pSTAKey->KeyDesc.RCounter[3]);
        DBGPRINT(RT_DEBUG_ERROR, "Current : %d %d %d %d  \n", pEntry->R_Counter[4],pEntry->R_Counter[5],pEntry->R_Counter[6],pEntry->R_Counter[7]);
        return;
    }

    // Check MIC, if not valid, discard silently
    NdisMoveMemory(DA, &pSTAKey->KeyDesc.Data[6], MAC_ADDR_LEN);
	if (pSTAKey->KeyDesc.Keyinfo.KeyMic && pSTAKey->KeyDesc.Keyinfo.Secure && pSTAKey->KeyDesc.Keyinfo.Request)
	{
		pEntry->bDlsInit = TRUE;
		DBGPRINT(RT_DEBUG_TRACE, "STAKey Initiator: %02x:%02x:%02x:%02x:%02x:%02x\n",
			pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
	}
    MICMsgLen = pSTAKey->Body_Len[1] | ((pSTAKey->Body_Len[0]<<8) && 0xff00);
    MICMsgLen += LENGTH_EAPOL_H;
    if (MICMsgLen > (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H))
    {
        DBGPRINT(RT_DEBUG_ERROR, "Receive wrong format EAPOL packets \n");
        return;        
    }

	// This is proprietary DLS protocol, it will be adhered when spec. is finished.
	NdisZeroMemory(temp, 64);
	NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
	CountPTK(temp, temp, pAd->PortCfg.MBSSID[pEntry->ApIdx].Bssid, temp, pEntry->Addr, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_PTK);
	DBGPRINT(RT_DEBUG_INFO, "PTK-%x %x %x %x %x %x %x %x \n",pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[0],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[1],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[2],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[3],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[4],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[5],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[6],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[7]);

    NdisMoveMemory((PUCHAR)&EAPOLPKT, pSTAKey, MICMsgLen);
    NdisZeroMemory(EAPOLPKT.KeyDesc.MIC, LEN_KEY_DESC_MIC);
    if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
    {
        hmac_md5(pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, (PUCHAR)&EAPOLPKT, MICMsgLen, mic);
    }
    else
    {
        HMAC_SHA1((PUCHAR)&EAPOLPKT,  MICMsgLen, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, mic);
    }
    if (!RTMPEqualMemory(pSTAKey->KeyDesc.MIC, mic, LEN_KEY_DESC_MIC))
    {
        DBGPRINT(RT_DEBUG_ERROR, "MIC Different in STAKey handshake!! \n");
        return;
    }
    else
        DBGPRINT(RT_DEBUG_TRACE, "MIC VALID in STAKey handshake!! \n");

	// Receive init STA's STAKey Message-2, and terminate the handshake
	if (pEntry->bDlsInit && !pSTAKey->KeyDesc.Keyinfo.Request)
	{
		pEntry->bDlsInit = FALSE;
		DBGPRINT(RT_DEBUG_TRACE, "Receive init STA's STAKey Message-2, STAKey handshake finished \n");
		return;
	}

	// Receive init STA's STAKey Message-2, and terminate the handshake
	if (RTMPEqualMemory(&pSTAKey->KeyDesc.Data[2], OUI_WPA2_WEP40, 3))
	{
		DBGPRINT(RT_DEBUG_WARN, "Receive a STAKey message which not support currently, just drop it \n");
		return;
	}
	
    do
    {
    	pDaEntry = MacTableLookup(pAd, DA);
    	if (!pDaEntry)
    		break;

    	if ((pDaEntry->WpaState != AS_PTKINITDONE))
	    {
	        DBGPRINT(RT_DEBUG_ERROR, "Not expect calling STAKey hand shaking here \n");
	        break;
	    }
    	
        pOutBuffer = kmalloc(MAX_LEN_OF_EAP_HS, MEM_ALLOC_FLAG);
        if(pOutBuffer == NULL)
            break;

        WPAMake8023Hdr(pAd, pDaEntry, Header802_3);

        // Increment replay counter by 1  
        ADD_ONE_To_64BIT_VAR(pAd->PortCfg.R_Counter);
        
        // 0. init Packet and Fill header
        NdisZeroMemory(&Packet, sizeof(Packet));

        Packet.ProVer = EAPOL_VER;
        Packet.ProType = EAPOLKey;
        Packet.Body_Len[1] = 0x5f;
        
        // 1. Fill replay counter
        NdisMoveMemory(pDaEntry->R_Counter, pAd->PortCfg.R_Counter, sizeof(pDaEntry->R_Counter));
        NdisMoveMemory(Packet.KeyDesc.RCounter, pDaEntry->R_Counter, sizeof(pDaEntry->R_Counter));
        
        // 2. Fill key version, keyinfo, key len
        Packet.KeyDesc.Keyinfo.KeyDescVer= GROUP_KEY;
        Packet.KeyDesc.Keyinfo.KeyType	= GROUP_KEY;
        Packet.KeyDesc.Keyinfo.Install	= 1;
        Packet.KeyDesc.Keyinfo.KeyAck	= 1;
        Packet.KeyDesc.Keyinfo.KeyMic	= 1;
        Packet.KeyDesc.Keyinfo.Secure	= 1;
        Packet.KeyDesc.Keyinfo.EKD		= 1;
		DBGPRINT(RT_DEBUG_TRACE, "STAKey handshake for peer STA %02x:%02x:%02x:%02x:%02x:%02x\n",
			DA[0], DA[1], DA[2], DA[3], DA[4], DA[5]);
        
        if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
        {
        	Packet.KeyDesc.Type = WPA1_KEY_DESC;

        	DBGPRINT(RT_DEBUG_TRACE, "pDaEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n");
        }
        else if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
        {
        	Packet.KeyDesc.Type = WPA2_KEY_DESC;
        	Packet.KeyDesc.DataLen[1] = 0;

        	DBGPRINT(RT_DEBUG_TRACE, "pDaEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n");
        }

        Packet.KeyDesc.KeyLength[1] = LEN_TKIP_KEY;
        Packet.KeyDesc.DataLen[1] = LEN_TKIP_KEY;
        Packet.KeyDesc.Keyinfo.KeyDescVer = DESC_TYPE_TKIP;
        if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
        {
            Packet.KeyDesc.KeyLength[1] = LEN_AES_KEY;
            Packet.KeyDesc.DataLen[1] = LEN_AES_KEY;
            Packet.KeyDesc.Keyinfo.KeyDescVer = DESC_TYPE_AES;
        }

		// Key Data Encapsulation format, use Ralink OUI to distinguish proprietary and standard.
    	Key_Data[0] = 0xDD;
		Key_Data[1] = 0x00;		// Length (This field will be filled later)
    	Key_Data[2] = 0x00;		// OUI
    	Key_Data[3] = 0x0C;		// OUI
    	Key_Data[4] = 0x43;		// OUI
    	Key_Data[5] = 0x02;		// Data Type (STAKey Key Data Encryption)

		// STAKey Data Encapsulation format
    	Key_Data[6] = 0x00;		//Reserved
		Key_Data[7] = 0x00;		//Reserved

		// STAKey MAC address
		NdisMoveMemory(&Key_Data[8], pEntry->Addr, MAC_ADDR_LEN);		// initiator MAC address

		// STAKey (Handle the difference between TKIP and AES-CCMP)
		if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
        {
        	Key_Data[1] = 0x1E;	// 4+2+6+16(OUI+Reserved+STAKey_MAC_Addr+STAKey)
        	NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_AES_KEY);
		}
		else
		{
			Key_Data[1] = 0x2E;	// 4+2+6+32(OUI+Reserved+STAKey_MAC_Addr+STAKey)
			NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_TKIP_EK);
			NdisMoveMemory(&Key_Data[14+LEN_TKIP_EK], pEntry->PairwiseKey.TxMic, LEN_TKIP_TXMICK);
			NdisMoveMemory(&Key_Data[14+LEN_TKIP_EK+LEN_TKIP_TXMICK], pEntry->PairwiseKey.RxMic, LEN_TKIP_RXMICK);
		}

		key_length = Key_Data[1];
		Packet.Body_Len[1] = key_length + 0x5f;

		// This is proprietary DLS protocol, it will be adhered when spec. is finished.
		NdisZeroMemory(temp, 64);
		NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
		CountPTK(temp, temp, pAd->PortCfg.MBSSID[pEntry->ApIdx].Bssid, temp, DA, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_PTK);
		
		DBGPRINT(RT_DEBUG_TRACE, "PTK-0-%x %x %x %x %x %x %x %x \n",pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[0],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[1],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[2],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[3],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[4],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[5],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[6],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[7]);

       	NdisMoveMemory(Packet.KeyDesc.Data, Key_Data, key_length);
		NdisZeroMemory(mic, sizeof(mic));

		MakeOutgoingFrame(pOutBuffer,			&FrameLen,
                        Packet.Body_Len[1] + 4,	&Packet,
                        END_OF_ARGS);
	    
		// Calculate MIC
        if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
        {
            HMAC_SHA1(pOutBuffer, FrameLen, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, digest);
            NdisMoveMemory(Packet.KeyDesc.MIC, digest, LEN_KEY_DESC_MIC);
	    }
        else
        {
            hmac_md5(pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, mic);
            NdisMoveMemory(Packet.KeyDesc.MIC, mic, LEN_KEY_DESC_MIC);
        }

#ifdef BIG_ENDIAN
		{
			USHORT	tmpKeyinfo;

			NdisMoveMemory(&tmpKeyinfo, &Packet.KeyDesc.Keyinfo, sizeof(USHORT)); 
			tmpKeyinfo = SWAP16(tmpKeyinfo);
			NdisMoveMemory(&Packet.KeyDesc.Keyinfo, &tmpKeyinfo, sizeof(USHORT)); 
		}
#endif

        // Fill frame
        MakeOutgoingFrame(pOutBuffer,				&FrameLen,
                            sizeof(Header802_3),	Header802_3,
                            Packet.Body_Len[1] + 4,	&Packet,
                            END_OF_ARGS);

        RTMPToWirelessSta(pAd, pOutBuffer, FrameLen);

        kfree(pOutBuffer);
    }while(FALSE);
    
    DBGPRINT(RT_DEBUG_TRACE, "<== RTMPHandleSTAKey: FrameLen=%d\n", FrameLen);
}

⌨️ 快捷键说明

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