/*
 *************************************************************************
 * Ralink Tech Inc.
 * 5F., No.36, Taiyuan St., Jhubei City,
 * Hsinchu County 302,
 * Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2007, Ralink Technology, Inc.
 *
 * 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.             *
 *                                                                       *
 *************************************************************************

	Module Name:
	wpa.c

	Abstract:

	Revision History:
	Who			When			What
	--------	----------		----------------------------------------------
	Jan	Lee		03-07-22		Initial
	Paul Lin	03-11-28		Modify for supplicant
*/
#include "../rt_config.h"
/* WPA OUI */
u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 };
u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 };
u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 };
u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 };
u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 };
u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 };
u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 };
u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 };

/* WPA2 OUI */
u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 };
u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 };
u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };

static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
				  u8 GroupKeyWepStatus,
				  u8 keyDescVer,
				  u8 MsgType,
				  u8 DefaultKeyIdx,
				  u8 * GTK,
				  u8 * RSNIE,
				  u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);

static void CalculateMIC(u8 KeyDescVer,
			 u8 * PTK, struct rt_eapol_packet * pMsg);

static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);

static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
				   struct rt_mlme_queue_elem *Elem);

static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
				 struct rt_mlme_queue_elem *Elem);

static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
				struct rt_mlme_queue_elem *Elem);

static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);

/*
    ==========================================================================
    Description:
        association state machine init, including state transition and timer init
    Parameters:
        S - pointer to the association state machine
    ==========================================================================
 */
void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
			 struct rt_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, MT2_EAPPacket,
			      (STATE_MACHINE_FUNC) WpaEAPPacketAction);
	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart,
			      (STATE_MACHINE_FUNC) WpaEAPOLStartAction);
	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff,
			      (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction);
	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey,
			      (STATE_MACHINE_FUNC) WpaEAPOLKeyAction);
	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert,
			      (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction);
}

/*
    ==========================================================================
    Description:
        this is state machine function.
        When receiving EAP packets which is  for 802.1x authentication use.
        Not use in PSK case
    Return:
    ==========================================================================
*/
void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
}

void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
}

void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
}

/*
    ==========================================================================
    Description:
       Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
    Return:
    ==========================================================================
*/
void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
	struct rt_mac_table_entry *pEntry;
	struct rt_header_802_11 * pHeader;

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

	pHeader = (struct rt_header_802_11 *) Elem->Msg;

	/*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */
	if (Elem->MsgLen == 6)
		pEntry = MacTableLookup(pAd, Elem->Msg);
	else {
		pEntry = MacTableLookup(pAd, pHeader->Addr2);
	}

	if (pEntry) {
		DBGPRINT(RT_DEBUG_TRACE,
			 (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n",
			  pEntry->PortSecured, pEntry->WpaState,
			  pEntry->AuthMode, pEntry->PMKID_CacheIdx));

		if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
		    && (pEntry->WpaState < AS_PTKSTART)
		    && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
			|| (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
			|| ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
			    && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) {
			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
			pEntry->WpaState = AS_INITPSK;
			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
			NdisZeroMemory(pEntry->R_Counter,
				       sizeof(pEntry->R_Counter));
			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;

			WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
		}
	}
}

/*
    ==========================================================================
    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(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
	struct rt_mac_table_entry *pEntry;
	struct rt_header_802_11 * pHeader;
	struct rt_eapol_packet * pEapol_packet;
	struct rt_key_info peerKeyInfo;

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

	pHeader = (struct rt_header_802_11 *) Elem->Msg;
	pEapol_packet =
	    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];

	NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
	NdisMoveMemory((u8 *)& peerKeyInfo,
		       (u8 *)& pEapol_packet->KeyDesc.KeyInfo,
		       sizeof(struct rt_key_info));

	hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
		 (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));

	*((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));

	do {
		pEntry = MacTableLookup(pAd, pHeader->Addr2);

		if (!pEntry
		    || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
			break;

		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
			break;

		DBGPRINT(RT_DEBUG_TRACE,
			 ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n",
			  PRINT_MAC(pEntry->Addr)));

		if (((pEapol_packet->ProVer != EAPOL_VER)
		     && (pEapol_packet->ProVer != EAPOL_VER2))
		    || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC)
			&& (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("Key descripter does not match with WPA rule\n"));
			break;
		}
		/* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */
		/* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */
		if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
		    && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("Key descripter version not match(TKIP) \n"));
			break;
		}
		/* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */
		/* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */
		else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
			 && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("Key descripter version not match(AES) \n"));
			break;
		}
		/* Check if this STA is in class 3 state and the WPA state is started */
		if ((pEntry->Sst == SST_ASSOC)
		    && (pEntry->WpaState >= AS_INITPSK)) {
			/* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */
			/* or not. */
			/* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */
			/* Key frame from the Authenticator must not have the Ack bit set. */
			if (peerKeyInfo.KeyAck == 1) {
				/* The frame is snet by Authenticator. */
				/* So the Supplicant side shall handle this. */

				if ((peerKeyInfo.Secure == 0)
				    && (peerKeyInfo.Request == 0)
				    && (peerKeyInfo.Error == 0)
				    && (peerKeyInfo.KeyType == PAIRWISEKEY)) {
					/* Process 1. the message 1 of 4-way HS in WPA or WPA2 */
					/*                        EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
					/*                 2. the message 3 of 4-way HS in WPA */
					/*                        EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
					if (peerKeyInfo.KeyMic == 0)
						PeerPairMsg1Action(pAd, pEntry,
								   Elem);
					else
						PeerPairMsg3Action(pAd, pEntry,
								   Elem);
				} else if ((peerKeyInfo.Secure == 1)
					   && (peerKeyInfo.KeyMic == 1)
					   && (peerKeyInfo.Request == 0)
					   && (peerKeyInfo.Error == 0)) {
					/* Process 1. the message 3 of 4-way HS in WPA2 */
					/*                        EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
					/*                 2. the message 1 of group KS in WPA or WPA2 */
					/*                        EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */
					if (peerKeyInfo.KeyType == PAIRWISEKEY)
						PeerPairMsg3Action(pAd, pEntry,
								   Elem);
					else
						PeerGroupMsg1Action(pAd, pEntry,
								    Elem);
				}
			} else {
				/* The frame is snet by Supplicant. */
				/* So the Authenticator side shall handle this. */
				if ((peerKeyInfo.Request == 0) &&
				    (peerKeyInfo.Error == 0) &&
				    (peerKeyInfo.KeyMic == 1)) {
					if (peerKeyInfo.Secure == 0
					    && peerKeyInfo.KeyType ==
					    PAIRWISEKEY) {
						/* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */
						/* Process 1. message 2 of 4-way HS in WPA or WPA2 */
						/*                 2. message 4 of 4-way HS in WPA */
						if (CONV_ARRARY_TO_u16
						    (pEapol_packet->KeyDesc.
						     KeyDataLen) == 0) {
							PeerPairMsg4Action(pAd,
									   pEntry,
									   Elem);
						} else {
							PeerPairMsg2Action(pAd,
									   pEntry,
									   Elem);
						}
					} else if (peerKeyInfo.Secure == 1
						   && peerKeyInfo.KeyType ==
						   PAIRWISEKEY) {
						/* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */
						/* Process message 4 of 4-way HS in WPA2 */
						PeerPairMsg4Action(pAd, pEntry,
								   Elem);
					} else if (peerKeyInfo.Secure == 1
						   && peerKeyInfo.KeyType ==
						   GROUPKEY) {
						/* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */
						/* Process message 2 of Group key HS in WPA or WPA2 */
						PeerGroupMsg2Action(pAd, pEntry,
								    &Elem->
								    Msg
								    [LENGTH_802_11],
								    (Elem->
								     MsgLen -
								     LENGTH_802_11));
					}
				}
			}
		}
	} while (FALSE);
}

/*
	========================================================================

	Routine	Description:
		Copy frame from waiting queue into relative ring buffer and set
	appropriate ASIC register to kick hardware encryption before really
	sent out to air.

	Arguments:
		pAd		Pointer	to our adapter
		void *	Pointer to outgoing Ndis frame
		NumberOfFrag	Number of fragment required

	Return Value:
		None

	Note:

	========================================================================
*/
void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
		       struct rt_mac_table_entry *pEntry,
		       u8 *pHeader802_3,
		       u32 HdrLen,
		       u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
{
	void *pPacket;
	int Status;

	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
		return;

	do {
		/* build a NDIS packet */
		Status =
		    RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
					   pData, DataLen);
		if (Status != NDIS_STATUS_SUCCESS)
			break;

		if (bClearFrame)
			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
		else
			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
		{
			RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);

			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);	/* set a default value */
			if (pEntry->apidx != 0)
				RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket,
								  pEntry->
								  apidx);

			RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
			RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
		}

		{
			/* send out the packet */
			Status = STASendPacket(pAd, pPacket);
			if (Status == NDIS_STATUS_SUCCESS) {
				u8 Index;

				/* Dequeue one frame from TxSwQueue0..3 queue and process it */
				/* There are three place calling dequeue for TX ring. */
				/* 1. Here, right after queueing the frame. */
				/* 2. At the end of TxRingTxDone service routine. */
				/* 3. Upon NDIS call RTMPSendPackets */
				if ((!RTMP_TEST_FLAG
				     (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
				    &&
				    (!RTMP_TEST_FLAG
				     (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
					for (Index = 0; Index < 5; Index++)
						if (pAd->TxSwQueue[Index].
						    Number > 0)
							RTMPDeQueuePacket(pAd,
									  FALSE,
									  Index,
									  MAX_TX_PROCESS);
				}
			}
		}

	} while (FALSE);
}

/*
    ==========================================================================
    Description:
        This is a function to initialize 4-way handshake

    Return:

    ==========================================================================
*/
void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
		    struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
{
	u8 Header802_3[14];
	struct rt_eapol_packet EAPOLPKT;
	u8 *pBssid = NULL;
	u8 group_cipher = Ndis802_11WEPDisabled;

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

	if (RTMP_TEST_FLAG
	    (pAd,
	     fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
	{
		DBGPRINT(RT_DEBUG_ERROR,
			 ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
		return;
	}

	if (pBssid == NULL) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
		return;
	}
	/* Check the status */
	if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
		return;
	}

	/* Increment replay counter by 1 */
	ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);

	/* Randomly generate ANonce */
	GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);

	/* Construct EAPoL message - Pairwise Msg 1 */
	/* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0,	/* Default key index */
			  pEntry->ANonce, NULL,	/* TxRSC */
			  NULL,	/* GTK */
			  NULL,	/* RSNIE */
			  0,	/* RSNIE length */
			  &EAPOLPKT);

	/* Make outgoing frame */
	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
	RTMPToWirelessSta(pAd, pEntry, Header802_3,
			  LENGTH_802_3, (u8 *)& EAPOLPKT,
			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
			  (pEntry->PortSecured ==
			   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);

	/* Trigger Retry Timer */
	RTMPModTimer(&pEntry->RetryTimer, TimeInterval);

	/* Update State */
	pEntry->WpaState = AS_PTKSTART;

	DBGPRINT(RT_DEBUG_TRACE,
		 ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));

}

/*
	========================================================================

	Routine Description:
		Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2

	Arguments:
		pAd			Pointer	to our adapter
		Elem		Message body

	Return Value:
		None

	Note:

	========================================================================
*/
void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
{
	u8 PTK[80];
	u8 Header802_3[14];
	struct rt_eapol_packet * pMsg1;
	u32 MsgLen;
	struct rt_eapol_packet EAPOLPKT;
	u8 *pCurrentAddr = NULL;
	u8 *pmk_ptr = NULL;
	u8 group_cipher = Ndis802_11WEPDisabled;
	u8 *rsnie_ptr = NULL;
	u8 rsnie_len = 0;

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

	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
		return;

	if (Elem->MsgLen <
	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
		return;

	{
		pCurrentAddr = pAd->CurrentAddress;
		pmk_ptr = pAd->StaCfg.PMK;
		group_cipher = pAd->StaCfg.GroupCipher;
		rsnie_ptr = pAd->StaCfg.RSN_IE;
		rsnie_len = pAd->StaCfg.RSNIE_Len;
	}

	/* Store the received frame */
	pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;

	/* Sanity Check peer Pairwise message 1 - Replay Counter */
	if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
	    == FALSE)
		return;

	/* Store Replay counter, it will use to verify message 3 and construct message 2 */
	NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter,
		       LEN_KEY_DESC_REPLAY);

	/* Store ANonce */
	NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
		       LEN_KEY_DESC_NONCE);

	/* Generate random SNonce */
	GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);

	{
		/* Calculate PTK(ANonce, SNonce) */
		WpaDerivePTK(pAd,
			     pmk_ptr,
			     pEntry->ANonce,
			     pEntry->Addr,
			     pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);

		/* Save key to PTK entry */
		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
	}

	/* Update WpaState */
	pEntry->WpaState = AS_PTKINIT_NEGOTIATING;

	/* Construct EAPoL message - Pairwise Msg 2 */
	/*  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */
	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0,	/* DefaultKeyIdx */
			  pEntry->SNonce, NULL,	/* TxRsc */
			  NULL,	/* GTK */
			  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);

	/* Make outgoing frame */
	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);

	RTMPToWirelessSta(pAd, pEntry,
			  Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);

	DBGPRINT(RT_DEBUG_TRACE,
		 ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
}

/*
    ==========================================================================
    Description:
        When receiving the second packet of 4-way pairwisekey handshake.
    Return:
    ==========================================================================
*/
void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
{
	u8 PTK[80];
	BOOLEAN Cancelled;
	struct rt_header_802_11 * pHeader;
	struct rt_eapol_packet EAPOLPKT;
	struct rt_eapol_packet * pMsg2;
	u32 MsgLen;
	u8 Header802_3[LENGTH_802_3];
	u8 TxTsc[6];
	u8 *pBssid = NULL;
	u8 *pmk_ptr = NULL;
	u8 *gtk_ptr = NULL;
	u8 default_key = 0;
	u8 group_cipher = Ndis802_11WEPDisabled;
	u8 *rsnie_ptr = NULL;
	u8 rsnie_len = 0;

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

	if ((!pEntry) || (!pEntry->ValidAsCLI))
		return;

	if (Elem->MsgLen <
	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
		return;

	/* check Entry in valid State */
	if (pEntry->WpaState < AS_PTKSTART)
		return;

	/* pointer to 802.11 header */
	pHeader = (struct rt_header_802_11 *) Elem->Msg;

	/* skip 802.11_header(24-byte) and LLC_header(8) */
	pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;

	/* Store SNonce */
	NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
		       LEN_KEY_DESC_NONCE);

	{
		/* Derive PTK */
		WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce,	/* ANONCE */
			     (u8 *) pBssid, pEntry->SNonce,	/* SNONCE */
			     pEntry->Addr, PTK, LEN_PTK);

		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
	}

	/* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
	if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
	    == FALSE)
		return;

	do {
		/* delete retry timer */
		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);

		/* Change state */
		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;

		/* Increment replay counter by 1 */
		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);

		/* Construct EAPoL message - Pairwise Msg 3 */
		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
		ConstructEapolMsg(pEntry,
				  group_cipher,
				  EAPOL_PAIR_MSG_3,
				  default_key,
				  pEntry->ANonce,
				  TxTsc,
				  (u8 *) gtk_ptr,
				  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);

		/* Make outgoing frame */
		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
		RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
				  (u8 *)& EAPOLPKT,
				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
				  (pEntry->PortSecured ==
				   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);

		pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
		RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);

		/* Update State */
		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
	} while (FALSE);

	DBGPRINT(RT_DEBUG_TRACE,
		 ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
}

/*
	========================================================================

	Routine Description:
		Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4

	Arguments:
		pAd	Pointer	to our adapter
		Elem		Message body

	Return Value:
		None

	Note:

	========================================================================
*/
void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
{
	struct rt_header_802_11 * pHeader;
	u8 Header802_3[14];
	struct rt_eapol_packet EAPOLPKT;
	struct rt_eapol_packet * pMsg3;
	u32 MsgLen;
	u8 *pCurrentAddr = NULL;
	u8 group_cipher = Ndis802_11WEPDisabled;

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

	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
		return;

	if (Elem->MsgLen <
	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
		return;

	{
		pCurrentAddr = pAd->CurrentAddress;
		group_cipher = pAd->StaCfg.GroupCipher;

	}

	/* Record 802.11 header & the received EAPOL packet Msg3 */
	pHeader = (struct rt_header_802_11 *) Elem->Msg;
	pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;

	/* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
	if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
	    == FALSE)
		return;

	/* Save Replay counter, it will use construct message 4 */
	NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
		       LEN_KEY_DESC_REPLAY);

	/* Double check ANonce */
	if (!NdisEqualMemory
	    (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
		return;
	}
	/* Construct EAPoL message - Pairwise Msg 4 */
	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0,	/* group key index not used in message 4 */
			  NULL,	/* Nonce not used in message 4 */
			  NULL,	/* TxRSC not used in message 4 */
			  NULL,	/* GTK not used in message 4 */
			  NULL,	/* RSN IE not used in message 4 */
			  0, &EAPOLPKT);

	/* Update WpaState */
	pEntry->WpaState = AS_PTKINITDONE;

	/* Update pairwise key */
	{
		struct rt_cipher_key *pSharedKey;

		pSharedKey = &pAd->SharedKey[BSS0][0];

		NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);

		/* Prepare pair-wise key information into shared key table */
		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
		pSharedKey->KeyLen = LEN_TKIP_EK;
		NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32],
			       LEN_TKIP_EK);
		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
			       LEN_TKIP_RXMICK);
		NdisMoveMemory(pSharedKey->TxMic,
			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
			       LEN_TKIP_TXMICK);

		/* Decide its ChiperAlg */
		if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
			pSharedKey->CipherAlg = CIPHER_TKIP;
		else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
			pSharedKey->CipherAlg = CIPHER_AES;
		else
			pSharedKey->CipherAlg = CIPHER_NONE;

		/* Update these related information to struct rt_mac_table_entry */
		pEntry = &pAd->MacTab.Content[BSSID_WCID];
		NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
			       LEN_TKIP_EK);
		NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
			       LEN_TKIP_RXMICK);
		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
			       LEN_TKIP_TXMICK);
		pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;

		/* Update pairwise key information to ASIC Shared Key Table */
		AsicAddSharedKeyEntry(pAd,
				      BSS0,
				      0,
				      pSharedKey->CipherAlg,
				      pSharedKey->Key,
				      pSharedKey->TxMic, pSharedKey->RxMic);

		/* Update ASIC WCID attribute table and IVEIV table */
		RTMPAddWcidAttributeEntry(pAd,
					  BSS0,
					  0, pSharedKey->CipherAlg, pEntry);

	}

	/* open 802.1x port control and privacy filter */
	if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
	    pEntry->AuthMode == Ndis802_11AuthModeWPA2) {
		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;

		STA_PORT_SECURED(pAd);
		/* Indicate Connected for GUI */
		pAd->IndicateMediaState = NdisMediaStateConnected;
		DBGPRINT(RT_DEBUG_TRACE,
			 ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
			  GetAuthMode(pEntry->AuthMode),
			  GetEncryptType(pEntry->WepStatus),
			  GetEncryptType(group_cipher)));
	} else {
	}

	/* Init 802.3 header and send out */
	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
	RTMPToWirelessSta(pAd, pEntry,
			  Header802_3, sizeof(Header802_3),
			  (u8 *)& EAPOLPKT,
			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);

	DBGPRINT(RT_DEBUG_TRACE,
		 ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
}

/*
    ==========================================================================
    Description:
        When receiving the last packet of 4-way pairwisekey handshake.
        Initialize 2-way groupkey handshake following.
    Return:
    ==========================================================================
*/
void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
{
	struct rt_eapol_packet * pMsg4;
	struct rt_header_802_11 * pHeader;
	u32 MsgLen;
	BOOLEAN Cancelled;
	u8 group_cipher = Ndis802_11WEPDisabled;

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

	do {
		if ((!pEntry) || (!pEntry->ValidAsCLI))
			break;

		if (Elem->MsgLen <
		    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
		     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
			break;

		if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
			break;

		/* pointer to 802.11 header */
		pHeader = (struct rt_header_802_11 *) Elem->Msg;

		/* skip 802.11_header(24-byte) and LLC_header(8) */
		pMsg4 =
		    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
		MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;

		/* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
		if (PeerWpaMessageSanity
		    (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
			break;

		/* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
		NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));

		/* reset IVEIV in Asic */
		AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);

		pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
		NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
			       LEN_TKIP_EK);
		NdisMoveMemory(pEntry->PairwiseKey.RxMic,
			       &pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
			       LEN_TKIP_RXMICK);
		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
			       &pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
			       LEN_TKIP_TXMICK);

		/* Set pairwise key to Asic */
		{
			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
			if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
				pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
			else if (pEntry->WepStatus ==
				 Ndis802_11Encryption3Enabled)
				pEntry->PairwiseKey.CipherAlg = CIPHER_AES;

			/* Add Pair-wise key to Asic */
			AsicAddPairwiseKeyEntry(pAd,
						pEntry->Addr,
						(u8)pEntry->Aid,
						&pEntry->PairwiseKey);

			/* update WCID attribute table and IVEIV table for this entry */
			RTMPAddWcidAttributeEntry(pAd,
						  pEntry->apidx,
						  0,
						  pEntry->PairwiseKey.CipherAlg,
						  pEntry);
		}

		/* 4. upgrade state */
		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
		pEntry->WpaState = AS_PTKINITDONE;
		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;

		if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
		    pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
			pEntry->GTKState = REKEY_ESTABLISHED;
			RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);

			/* send wireless event - for set key done WPA2 */
			if (pAd->CommonCfg.bWirelessEvent)
				RTMPSendWirelessEvent(pAd,
						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
						      pEntry->Addr,
						      pEntry->apidx, 0);

			DBGPRINT(RT_DEBUG_OFF,
				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
				  pEntry->AuthMode,
				  GetAuthMode(pEntry->AuthMode),
				  pEntry->WepStatus,
				  GetEncryptType(pEntry->WepStatus),
				  group_cipher, GetEncryptType(group_cipher)));
		} else {
			/* 5. init Group 2-way handshake if necessary. */
			WPAStart2WayGroupHS(pAd, pEntry);

			pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
			RTMPModTimer(&pEntry->RetryTimer,
				     PEER_MSG3_RETRY_EXEC_INTV);
		}
	} while (FALSE);

}

/*
    ==========================================================================
    Description:
        This is a function to send the first packet of 2-way groupkey handshake
    Return:

    ==========================================================================
*/
void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
{
	u8 Header802_3[14];
	u8 TxTsc[6];
	struct rt_eapol_packet EAPOLPKT;
	u8 group_cipher = Ndis802_11WEPDisabled;
	u8 default_key = 0;
	u8 *gnonce_ptr = NULL;
	u8 *gtk_ptr = NULL;
	u8 *pBssid = NULL;

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

	if ((!pEntry) || (!pEntry->ValidAsCLI))
		return;

	do {
		/* Increment replay counter by 1 */
		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);

		/* Construct EAPoL message - Group Msg 1 */
		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
		ConstructEapolMsg(pEntry,
				  group_cipher,
				  EAPOL_GROUP_MSG_1,
				  default_key,
				  (u8 *) gnonce_ptr,
				  TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);

		/* Make outgoing frame */
		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
		RTMPToWirelessSta(pAd, pEntry,
				  Header802_3, LENGTH_802_3,
				  (u8 *)& EAPOLPKT,
				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
				  FALSE);

	} while (FALSE);

	DBGPRINT(RT_DEBUG_TRACE,
		 ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));

	return;
}

/*
	========================================================================

	Routine Description:
		Process Group key 2-way handshaking

	Arguments:
		pAd	Pointer	to our adapter
		Elem		Message body

	Return Value:
		None

	Note:

	========================================================================
*/
void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
			 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
{
	u8 Header802_3[14];
	struct rt_eapol_packet EAPOLPKT;
	struct rt_eapol_packet * pGroup;
	u32 MsgLen;
	BOOLEAN Cancelled;
	u8 default_key = 0;
	u8 group_cipher = Ndis802_11WEPDisabled;
	u8 *pCurrentAddr = NULL;

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

	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
		return;

	{
		pCurrentAddr = pAd->CurrentAddress;
		group_cipher = pAd->StaCfg.GroupCipher;
		default_key = pAd->StaCfg.DefaultKeyId;
	}

	/* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */
	pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;

	/* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
	if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
	    == FALSE)
		return;

	/* delete retry timer */
	RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);

	/* Save Replay counter, it will use to construct message 2 */
	NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
		       LEN_KEY_DESC_REPLAY);

	/* Construct EAPoL message - Group Msg 2 */
	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
	ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL,	/* Nonce not used */
			  NULL,	/* TxRSC not used */
			  NULL,	/* GTK not used */
			  NULL,	/* RSN IE not used */
			  0, &EAPOLPKT);

	/* open 802.1x port control and privacy filter */
	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
	pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;

	STA_PORT_SECURED(pAd);
	/* Indicate Connected for GUI */
	pAd->IndicateMediaState = NdisMediaStateConnected;

	DBGPRINT(RT_DEBUG_TRACE,
		 ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
		  GetAuthMode(pEntry->AuthMode),
		  GetEncryptType(pEntry->WepStatus),
		  GetEncryptType(group_cipher)));

	/* init header and Fill Packet and send Msg 2 to authenticator */
	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
	RTMPToWirelessSta(pAd, pEntry,
			  Header802_3, sizeof(Header802_3),
			  (u8 *)& EAPOLPKT,
			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);

	DBGPRINT(RT_DEBUG_TRACE,
		 ("<=== PeerGroupMsg1Action: sned group message 2\n"));
}

/*
    ==========================================================================
    Description:
        When receiving the last packet of 2-way groupkey handshake.
    Return:
    ==========================================================================
*/
void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
			 struct rt_mac_table_entry *pEntry,
			 void * Msg, u32 MsgLen)
{
	u32 Len;
	u8 *pData;
	BOOLEAN Cancelled;
	struct rt_eapol_packet * pMsg2;
	u8 group_cipher = Ndis802_11WEPDisabled;

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

	do {
		if ((!pEntry) || (!pEntry->ValidAsCLI))
			break;

		if (MsgLen <
		    (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
		     MAX_LEN_OF_RSNIE - 2))
			break;

		if (pEntry->WpaState != AS_PTKINITDONE)
			break;

		pData = (u8 *)Msg;
		pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
		Len = MsgLen - LENGTH_802_1_H;

		/* Sanity Check peer group message 2 - Replay Counter, MIC */
		if (PeerWpaMessageSanity
		    (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
			break;

		/* 3.  upgrade state */

		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
		pEntry->GTKState = REKEY_ESTABLISHED;

		if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
		    || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) {
			/* send wireless event - for set key done WPA2 */
			if (pAd->CommonCfg.bWirelessEvent)
				RTMPSendWirelessEvent(pAd,
						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
						      pEntry->Addr,
						      pEntry->apidx, 0);

			DBGPRINT(RT_DEBUG_OFF,
				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
				  pEntry->AuthMode,
				  GetAuthMode(pEntry->AuthMode),
				  pEntry->WepStatus,
				  GetEncryptType(pEntry->WepStatus),
				  group_cipher, GetEncryptType(group_cipher)));
		} else {
			/* send wireless event - for set key done WPA */
			if (pAd->CommonCfg.bWirelessEvent)
				RTMPSendWirelessEvent(pAd,
						      IW_SET_KEY_DONE_WPA1_EVENT_FLAG,
						      pEntry->Addr,
						      pEntry->apidx, 0);

			DBGPRINT(RT_DEBUG_OFF,
				 ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
				  pEntry->AuthMode,
				  GetAuthMode(pEntry->AuthMode),
				  pEntry->WepStatus,
				  GetEncryptType(pEntry->WepStatus),
				  group_cipher, GetEncryptType(group_cipher)));
		}
	} while (FALSE);
}

/*
	========================================================================

	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

	IRQL = DISPATCH_LEVEL

	Note:
		All these constants are defined in wpa.h
		For supplicant, there is only EAPOL Key message avaliable

	========================================================================
*/
BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
{
	switch (EAPType) {
	case EAPPacket:
		*MsgType = MT2_EAPPacket;
		break;
	case EAPOLStart:
		*MsgType = MT2_EAPOLStart;
		break;
	case EAPOLLogoff:
		*MsgType = MT2_EAPOLLogoff;
		break;
	case EAPOLKey:
		*MsgType = MT2_EAPOLKey;
		break;
	case EAPOLASFAlert:
		*MsgType = MT2_EAPOLASFAlert;
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

/*
	========================================================================

	Routine Description:
		The pseudo-random function(PRF) that hashes various inputs to
		derive a pseudo-random value. To add liveness to the pseudo-random
		value, a nonce should be one of the inputs.

		It is used to generate PTK, GTK or some specific random value.

	Arguments:
		u8	*key,		-	the key material for HMAC_SHA1 use
		int		key_len		-	the length of key
		u8	*prefix		-	a prefix label
		int		prefix_len	-	the length of the label
		u8	*data		-	a specific data with variable length
		int		data_len	-	the length of a specific data
		int		len			-	the output lenght

	Return Value:
		u8	*output		-	the calculated result

	Note:
		802.11i-2004	Annex H.3

	========================================================================
*/
void PRF(u8 * key,
	 int key_len,
	 u8 * prefix,
	 int prefix_len,
	 u8 * data, int data_len, u8 * output, int len)
{
	int i;
	u8 *input;
	int currentindex = 0;
	int total_len;

	/* Allocate memory for input */
	os_alloc_mem(NULL, (u8 **) & input, 1024);

	if (input == NULL) {
		DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
		return;
	}
	/* Generate concatenation input */
	NdisMoveMemory(input, prefix, prefix_len);

	/* Concatenate a single octet containing 0 */
	input[prefix_len] = 0;

	/* Concatenate specific data */
	NdisMoveMemory(&input[prefix_len + 1], data, data_len);
	total_len = prefix_len + 1 + data_len;

	/* Concatenate a single octet containing 0 */
	/* This octet shall be update later */
	input[total_len] = 0;
	total_len++;

	/* Iterate to calculate the result by hmac-sha-1 */
	/* Then concatenate to last result */
	for (i = 0; i < (len + 19) / 20; i++) {
		HMAC_SHA1(key, key_len, input, total_len, &output[currentindex],
			  SHA1_DIGEST_SIZE);
		currentindex += 20;

		/* update the last octet */
		input[total_len - 1]++;
	}
	os_free_mem(NULL, input);
}

/*
* F(P, S, c, i) = U1 xor U2 xor ... Uc
* U1 = PRF(P, S || Int(i))
* U2 = PRF(P, U1)
* Uc = PRF(P, Uc-1)
*/

static void F(char *password, unsigned char *ssid, int ssidlength,
	      int iterations, int count, unsigned char *output)
{
	unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
	int i, j;

	/* U1 = PRF(P, S || int(i)) */
	memcpy(digest, ssid, ssidlength);
	digest[ssidlength] = (unsigned char)((count >> 24) & 0xff);
	digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff);
	digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff);
	digest[ssidlength + 3] = (unsigned char)(count & 0xff);
	HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE);	/* for WPA update */

	/* output = U1 */
	memcpy(output, digest1, SHA1_DIGEST_SIZE);

	for (i = 1; i < iterations; i++) {
		/* Un = PRF(P, Un-1) */
		HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE);	/* for WPA update */
		memcpy(digest1, digest, SHA1_DIGEST_SIZE);

		/* output = output xor Un */
		for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
			output[j] ^= digest[j];
		}
	}
}

/*
* password - ascii string up to 63 characters in length
* ssid - octet string up to 32 octets
* ssidlength - length of ssid in octets
* output must be 40 octets in length and outputs 256 bits of key
*/
int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
{
	if ((strlen(password) > 63) || (ssidlength > 32))
		return 0;

	F(password, ssid, ssidlength, 4096, 1, output);
	F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
	return 1;
}

/*
	========================================================================

	Routine Description:
		It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
		It shall be called by 4-way handshake processing.

	Arguments:
		pAd	-	pointer to our pAdapter context
		PMK		-	pointer to PMK
		ANonce	-	pointer to ANonce
		AA		-	pointer to Authenticator Address
		SNonce	-	pointer to SNonce
		SA		-	pointer to Supplicant Address
		len		-	indicate the length of PTK (octet)

	Return Value:
		Output		pointer to the PTK

	Note:
		Refer to IEEE 802.11i-2004 8.5.1.2

	========================================================================
*/
void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
		  u8 * PMK,
		  u8 * ANonce,
		  u8 * AA,
		  u8 * SNonce,
		  u8 * SA, u8 * output, u32 len)
{
	u8 concatenation[76];
	u32 CurrPos = 0;
	u8 temp[32];
	u8 Prefix[] =
	    { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
		'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
	};

	/* initiate the concatenation input */
	NdisZeroMemory(temp, sizeof(temp));
	NdisZeroMemory(concatenation, 76);

	/* Get smaller address */
	if (RTMPCompareMemory(SA, AA, 6) == 1)
		NdisMoveMemory(concatenation, AA, 6);
	else
		NdisMoveMemory(concatenation, SA, 6);
	CurrPos += 6;

	/* Get larger address */
	if (RTMPCompareMemory(SA, AA, 6) == 1)
		NdisMoveMemory(&concatenation[CurrPos], SA, 6);
	else
		NdisMoveMemory(&concatenation[CurrPos], AA, 6);

	/* store the larger mac address for backward compatible of */
	/* ralink proprietary STA-key issue */
	NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
	CurrPos += 6;

	/* Get smaller Nonce */
	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
	else
		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
	CurrPos += 32;

	/* Get larger Nonce */
	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
	else
		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
	CurrPos += 32;

	hex_dump("concatenation=", concatenation, 76);

	/* Use PRF to generate PTK */
	PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);

}

/*
	========================================================================

	Routine Description:
		Generate random number by software.

	Arguments:
		pAd		-	pointer to our pAdapter context
		macAddr	-	pointer to local MAC address

	Return Value:

	Note:
		802.1ii-2004  Annex H.5

	========================================================================
*/
void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
{
	int i, curr;
	u8 local[80], KeyCounter[32];
	u8 result[80];
	unsigned long CurrentTime;
	u8 prefix[] =
	    { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };

	/* Zero the related information */
	NdisZeroMemory(result, 80);
	NdisZeroMemory(local, 80);
	NdisZeroMemory(KeyCounter, 32);

	for (i = 0; i < 32; i++) {
		/* copy the local MAC address */
		COPY_MAC_ADDR(local, macAddr);
		curr = MAC_ADDR_LEN;

		/* concatenate the current time */
		NdisGetSystemUpTime(&CurrentTime);
		NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
		curr += sizeof(CurrentTime);

		/* concatenate the last result */
		NdisMoveMemory(&local[curr], result, 32);
		curr += 32;

		/* concatenate a variable */
		NdisMoveMemory(&local[curr], &i, 2);
		curr += 2;

		/* calculate the result */
		PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
	}

	NdisMoveMemory(random, result, 32);
}

/*
	========================================================================

	Routine Description:
		Build cipher suite in RSN-IE.
		It only shall be called by RTMPMakeRSNIE.

	Arguments:
		pAd			-	pointer to our pAdapter context
	ElementID	-	indicate the WPA1 or WPA2
	WepStatus	-	indicate the encryption type
		bMixCipher	-	a boolean to indicate the pairwise cipher and group
						cipher are the same or not

	Return Value:

	Note:

	========================================================================
*/
static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
				u8 ElementID,
				u32 WepStatus,
				IN BOOLEAN bMixCipher,
				u8 FlexibleCipher,
				u8 *pRsnIe, u8 * rsn_len)
{
	u8 PairwiseCnt;

	*rsn_len = 0;

	/* decide WPA2 or WPA1 */
	if (ElementID == Wpa2Ie) {
		struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;

		/* Assign the verson as 1 */
		pRsnie_cipher->version = 1;

		switch (WepStatus) {
			/* TKIP mode */
		case Ndis802_11Encryption2Enabled:
			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
			pRsnie_cipher->ucount = 1;
			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
				       OUI_WPA2_TKIP, 4);
			*rsn_len = sizeof(struct rt_rsnie2);
			break;

			/* AES mode */
		case Ndis802_11Encryption3Enabled:
			if (bMixCipher)
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA2_TKIP, 4);
			else
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA2_CCMP, 4);
			pRsnie_cipher->ucount = 1;
			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
				       OUI_WPA2_CCMP, 4);
			*rsn_len = sizeof(struct rt_rsnie2);
			break;

			/* TKIP-AES mix mode */
		case Ndis802_11Encryption4Enabled:
			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);

			PairwiseCnt = 1;
			/* Insert WPA2 TKIP as the first pairwise cipher */
			if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
					       OUI_WPA2_TKIP, 4);
				/* Insert WPA2 AES as the secondary pairwise cipher */
				if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) {
					NdisMoveMemory(pRsnie_cipher->ucast[0].
						       oui + 4, OUI_WPA2_CCMP,
						       4);
					PairwiseCnt = 2;
				}
			} else {
				/* Insert WPA2 AES as the first pairwise cipher */
				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
					       OUI_WPA2_CCMP, 4);
			}

			pRsnie_cipher->ucount = PairwiseCnt;
			*rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
			break;
		}

		if ((pAd->OpMode == OPMODE_STA) &&
		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
			u32 GroupCipher = pAd->StaCfg.GroupCipher;
			switch (GroupCipher) {
			case Ndis802_11GroupWEP40Enabled:
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA2_WEP40, 4);
				break;
			case Ndis802_11GroupWEP104Enabled:
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA2_WEP104, 4);
				break;
			}
		}
		/* swap for big-endian platform */
		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
	} else {
		struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;

		/* Assign OUI and version */
		NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
		pRsnie_cipher->version = 1;

		switch (WepStatus) {
			/* TKIP mode */
		case Ndis802_11Encryption2Enabled:
			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
			pRsnie_cipher->ucount = 1;
			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
				       OUI_WPA_TKIP, 4);
			*rsn_len = sizeof(struct rt_rsnie);
			break;

			/* AES mode */
		case Ndis802_11Encryption3Enabled:
			if (bMixCipher)
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA_TKIP, 4);
			else
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA_CCMP, 4);
			pRsnie_cipher->ucount = 1;
			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
				       OUI_WPA_CCMP, 4);
			*rsn_len = sizeof(struct rt_rsnie);
			break;

			/* TKIP-AES mix mode */
		case Ndis802_11Encryption4Enabled:
			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);

			PairwiseCnt = 1;
			/* Insert WPA TKIP as the first pairwise cipher */
			if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
					       OUI_WPA_TKIP, 4);
				/* Insert WPA AES as the secondary pairwise cipher */
				if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) {
					NdisMoveMemory(pRsnie_cipher->ucast[0].
						       oui + 4, OUI_WPA_CCMP,
						       4);
					PairwiseCnt = 2;
				}
			} else {
				/* Insert WPA AES as the first pairwise cipher */
				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
					       OUI_WPA_CCMP, 4);
			}

			pRsnie_cipher->ucount = PairwiseCnt;
			*rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
			break;
		}

		if ((pAd->OpMode == OPMODE_STA) &&
		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
			u32 GroupCipher = pAd->StaCfg.GroupCipher;
			switch (GroupCipher) {
			case Ndis802_11GroupWEP40Enabled:
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA_WEP40, 4);
				break;
			case Ndis802_11GroupWEP104Enabled:
				NdisMoveMemory(pRsnie_cipher->mcast,
					       OUI_WPA_WEP104, 4);
				break;
			}
		}
		/* swap for big-endian platform */
		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
	}
}

/*
	========================================================================

	Routine Description:
		Build AKM suite in RSN-IE.
		It only shall be called by RTMPMakeRSNIE.

	Arguments:
		pAd			-	pointer to our pAdapter context
	ElementID	-	indicate the WPA1 or WPA2
	AuthMode	-	indicate the authentication mode
		apidx		-	indicate the interface index

	Return Value:

	Note:

	========================================================================
*/
static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
			     u8 ElementID,
			     u32 AuthMode,
			     u8 apidx,
			     u8 *pRsnIe, u8 * rsn_len)
{
	struct rt_rsnie_auth *pRsnie_auth;
	u8 AkmCnt = 1;	/* default as 1 */

	pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));

	/* decide WPA2 or WPA1 */
	if (ElementID == Wpa2Ie) {

		switch (AuthMode) {
		case Ndis802_11AuthModeWPA2:
		case Ndis802_11AuthModeWPA1WPA2:
			NdisMoveMemory(pRsnie_auth->auth[0].oui,
				       OUI_WPA2_8021X_AKM, 4);
			break;

		case Ndis802_11AuthModeWPA2PSK:
		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
			NdisMoveMemory(pRsnie_auth->auth[0].oui,
				       OUI_WPA2_PSK_AKM, 4);
			break;
		default:
			AkmCnt = 0;
			break;

		}
	} else {
		switch (AuthMode) {
		case Ndis802_11AuthModeWPA:
		case Ndis802_11AuthModeWPA1WPA2:
			NdisMoveMemory(pRsnie_auth->auth[0].oui,
				       OUI_WPA_8021X_AKM, 4);
			break;

		case Ndis802_11AuthModeWPAPSK:
		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
			NdisMoveMemory(pRsnie_auth->auth[0].oui,
				       OUI_WPA_PSK_AKM, 4);
			break;

		case Ndis802_11AuthModeWPANone:
			NdisMoveMemory(pRsnie_auth->auth[0].oui,
				       OUI_WPA_NONE_AKM, 4);
			break;
		default:
			AkmCnt = 0;
			break;
		}
	}

	pRsnie_auth->acount = AkmCnt;
	pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);

	/* update current RSNIE length */
	(*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));

}

/*
	========================================================================

	Routine Description:
		Build capability in RSN-IE.
		It only shall be called by RTMPMakeRSNIE.

	Arguments:
		pAd			-	pointer to our pAdapter context
	ElementID	-	indicate the WPA1 or WPA2
		apidx		-	indicate the interface index

	Return Value:

	Note:

	========================================================================
*/
static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
			     u8 ElementID,
			     u8 apidx,
			     u8 *pRsnIe, u8 * rsn_len)
{
	RSN_CAPABILITIES *pRSN_Cap;

	/* it could be ignored in WPA1 mode */
	if (ElementID == WpaIe)
		return;

	pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));

	pRSN_Cap->word = cpu2le16(pRSN_Cap->word);

	(*rsn_len) += sizeof(RSN_CAPABILITIES);	/* update current RSNIE length */

}

/*
	========================================================================

	Routine Description:
		Build RSN IE context. It is not included element-ID and length.

	Arguments:
		pAd			-	pointer to our pAdapter context
	AuthMode	-	indicate the authentication mode
	WepStatus	-	indicate the encryption type
		apidx		-	indicate the interface index

	Return Value:

	Note:

	========================================================================
*/
void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
		   u32 AuthMode, u32 WepStatus, u8 apidx)
{
	u8 *pRsnIe = NULL;	/* primary RSNIE */
	u8 *rsnielen_cur_p = 0;	/* the length of the primary RSNIE */
	u8 *rsnielen_ex_cur_p = 0;	/* the length of the secondary RSNIE */
	u8 PrimaryRsnie;
	BOOLEAN bMixCipher = FALSE;	/* indicate the pairwise and group cipher are different */
	u8 p_offset;
	WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;	/* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */

	rsnielen_cur_p = NULL;
	rsnielen_ex_cur_p = NULL;

	{
		{
			if (pAd->StaCfg.WpaSupplicantUP !=
			    WPA_SUPPLICANT_DISABLE) {
				if (AuthMode < Ndis802_11AuthModeWPA)
					return;
			} else {
				/* Support WPAPSK or WPA2PSK in STA-Infra mode */
				/* Support WPANone in STA-Adhoc mode */
				if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
				    (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
				    (AuthMode != Ndis802_11AuthModeWPANone)
				    )
					return;
			}

			DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));

			/* Zero RSNIE context */
			pAd->StaCfg.RSNIE_Len = 0;
			NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);

			/* Pointer to RSNIE */
			rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
			pRsnIe = pAd->StaCfg.RSN_IE;

			bMixCipher = pAd->StaCfg.bMixCipher;
		}
	}

	/* indicate primary RSNIE as WPA or WPA2 */
	if ((AuthMode == Ndis802_11AuthModeWPA) ||
	    (AuthMode == Ndis802_11AuthModeWPAPSK) ||
	    (AuthMode == Ndis802_11AuthModeWPANone) ||
	    (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
	    (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
		PrimaryRsnie = WpaIe;
	else
		PrimaryRsnie = Wpa2Ie;

	{
		/* Build the primary RSNIE */
		/* 1. insert cipher suite */
		RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
				    FlexibleCipher, pRsnIe, &p_offset);

		/* 2. insert AKM */
		RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
				 &p_offset);

		/* 3. insert capability */
		RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
	}

	/* 4. update the RSNIE length */
	*rsnielen_cur_p = p_offset;

	hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));

}

/*
    ==========================================================================
    Description:
		Check whether the received frame is EAP frame.

	Arguments:
		pAd				-	pointer to our pAdapter context
		pEntry			-	pointer to active entry
		pData			-	the received frame
		DataByteCount	-	the received frame's length
		FromWhichBSSID	-	indicate the interface index

    Return:
         TRUE			-	This frame is EAP frame
         FALSE			-	otherwise
    ==========================================================================
*/
BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
			  struct rt_mac_table_entry *pEntry,
			  u8 *pData,
			  unsigned long DataByteCount, u8 FromWhichBSSID)
{
	unsigned long Body_len;
	BOOLEAN Cancelled;

	if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
		return FALSE;

	/* Skip LLC header */
	if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
	    /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */
	    NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) {
		pData += 6;
	}
	/* Skip 2-bytes EAPoL type */
	if (NdisEqualMemory(EAPOL, pData, 2)) {
		pData += 2;
	} else
		return FALSE;

	switch (*(pData + 1)) {
	case EAPPacket:
		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
		DBGPRINT(RT_DEBUG_TRACE,
			 ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
			  Body_len));
		break;
	case EAPOLStart:
		DBGPRINT(RT_DEBUG_TRACE,
			 ("Receive EAPOL-Start frame, TYPE = 1 \n"));
		if (pEntry->EnqueueEapolStartTimerRunning !=
		    EAPOL_START_DISABLE) {
			DBGPRINT(RT_DEBUG_TRACE,
				 ("Cancel the EnqueueEapolStartTimerRunning \n"));
			RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer,
					&Cancelled);
			pEntry->EnqueueEapolStartTimerRunning =
			    EAPOL_START_DISABLE;
		}
		break;
	case EAPOLLogoff:
		DBGPRINT(RT_DEBUG_TRACE,
			 ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
		break;
	case EAPOLKey:
		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
		DBGPRINT(RT_DEBUG_TRACE,
			 ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
			  Body_len));
		break;
	case EAPOLASFAlert:
		DBGPRINT(RT_DEBUG_TRACE,
			 ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
		break;
	default:
		return FALSE;

	}
	return TRUE;
}

/*
    ==========================================================================
    Description:
		Report the EAP message type

	Arguments:
		msg		-	EAPOL_PAIR_MSG_1
					EAPOL_PAIR_MSG_2
					EAPOL_PAIR_MSG_3
					EAPOL_PAIR_MSG_4
					EAPOL_GROUP_MSG_1
					EAPOL_GROUP_MSG_2

    Return:
         message type string

    ==========================================================================
*/
char *GetEapolMsgType(char msg)
{
	if (msg == EAPOL_PAIR_MSG_1)
		return "Pairwise Message 1";
	else if (msg == EAPOL_PAIR_MSG_2)
		return "Pairwise Message 2";
	else if (msg == EAPOL_PAIR_MSG_3)
		return "Pairwise Message 3";
	else if (msg == EAPOL_PAIR_MSG_4)
		return "Pairwise Message 4";
	else if (msg == EAPOL_GROUP_MSG_1)
		return "Group Message 1";
	else if (msg == EAPOL_GROUP_MSG_2)
		return "Group Message 2";
	else
		return "Invalid Message";
}

/*
	========================================================================

	Routine Description:
    Check Sanity RSN IE of EAPoL message

	Arguments:

	Return Value:

	========================================================================
*/
BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
		       u8 *pData,
		       u8 DataLen,
		       struct rt_mac_table_entry *pEntry, u8 * Offset)
{
	u8 *pVIE;
	u8 len;
	struct rt_eid * pEid;
	BOOLEAN result = FALSE;

	pVIE = pData;
	len = DataLen;
	*Offset = 0;

	while (len > sizeof(struct rt_rsnie2)) {
		pEid = (struct rt_eid *) pVIE;
		/* WPA RSN IE */
		if ((pEid->Eid == IE_WPA)
		    && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
			     || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
			    &&
			    (NdisEqualMemory
			     (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
			    && (pEntry->RSNIE_Len == (pEid->Len + 2))) {
				result = TRUE;
			}

			*Offset += (pEid->Len + 2);
		}
		/* WPA2 RSN IE */
		else if ((pEid->Eid == IE_RSN)
			 && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) {
			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2
			     || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
			    && (pEid->Eid == pEntry->RSN_IE[0])
			    && ((pEid->Len + 2) >= pEntry->RSNIE_Len)
			    &&
			    (NdisEqualMemory
			     (pEid->Octet, &pEntry->RSN_IE[2],
			      pEntry->RSNIE_Len - 2))) {

				result = TRUE;
			}

			*Offset += (pEid->Len + 2);
		} else {
			break;
		}

		pVIE += (pEid->Len + 2);
		len -= (pEid->Len + 2);
	}

	return result;

}

/*
	========================================================================

	Routine Description:
    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
    GTK  is encaptulated in KDE format at  p.83 802.11i D10

	Arguments:

	Return Value:

	Note:
        802.11i D10

	========================================================================
*/
BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
			      u8 *pKeyData,
			      u8 KeyDataLen,
			      u8 GroupKeyIndex,
			      u8 MsgType,
			      IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
{
	struct rt_kde_encap * pKDE = NULL;
	u8 *pMyKeyData = pKeyData;
	u8 KeyDataLength = KeyDataLen;
	u8 GTKLEN = 0;
	u8 DefaultIdx = 0;
	u8 skip_offset;

	/* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */
	if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) {
		/* Check RSN IE whether it is WPA2/WPA2PSK */
		if (!RTMPCheckRSNIE
		    (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) {
			/* send wireless event - for RSN IE different */
			if (pAd->CommonCfg.bWirelessEvent)
				RTMPSendWirelessEvent(pAd,
						      IW_RSNIE_DIFF_EVENT_FLAG,
						      pEntry->Addr,
						      pEntry->apidx, 0);

			DBGPRINT(RT_DEBUG_ERROR,
				 ("RSN_IE Different in msg %d of 4-way handshake!\n",
				  MsgType));
			hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
			hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
				 pEntry->RSNIE_Len);

			return FALSE;
		} else {
			if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
				WpaShowAllsuite(pMyKeyData, skip_offset);

				/* skip RSN IE */
				pMyKeyData += skip_offset;
				KeyDataLength -= skip_offset;
				DBGPRINT(RT_DEBUG_TRACE,
					 ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n",
					  skip_offset));
			} else
				return TRUE;
		}
	}

	DBGPRINT(RT_DEBUG_TRACE,
		 ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
		  KeyDataLength));
	/*hex_dump("remain data", pMyKeyData, KeyDataLength); */

	/* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
	if (bWPA2
	    && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
		if (KeyDataLength >= 8)	/* KDE format exclude GTK length */
		{
			pKDE = (struct rt_kde_encap *) pMyKeyData;

			DefaultIdx = pKDE->GTKEncap.Kid;

			/* Sanity check - KED length */
			if (KeyDataLength < (pKDE->Len + 2)) {
				DBGPRINT(RT_DEBUG_ERROR,
					 ("ERROR: The len from KDE is too short \n"));
				return FALSE;
			}
			/* Get GTK length - refer to IEEE 802.11i-2004 p.82 */
			GTKLEN = pKDE->Len - 6;
			if (GTKLEN < LEN_AES_KEY) {
				DBGPRINT(RT_DEBUG_ERROR,
					 ("ERROR: GTK Key length is too short (%d) \n",
					  GTKLEN));
				return FALSE;
			}

		} else {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("ERROR: KDE format length is too short \n"));
			return FALSE;
		}

		DBGPRINT(RT_DEBUG_TRACE,
			 ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
			  DefaultIdx, GTKLEN));
		/* skip it */
		pMyKeyData += 8;
		KeyDataLength -= 8;

	} else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
		DefaultIdx = GroupKeyIndex;
		DBGPRINT(RT_DEBUG_TRACE,
			 ("GTK DefaultKeyID=%d \n", DefaultIdx));
	}
	/* Sanity check - shared key index must be 1 ~ 3 */
	if (DefaultIdx < 1 || DefaultIdx > 3) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("ERROR: GTK Key index(%d) is invalid in %s %s \n",
			  DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"),
			  GetEapolMsgType(MsgType)));
		return FALSE;
	}

	{
		struct rt_cipher_key *pSharedKey;

		/* set key material, TxMic and RxMic */
		NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
		pAd->StaCfg.DefaultKeyId = DefaultIdx;

		pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];

		/* Prepare pair-wise key information into shared key table */
		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
		pSharedKey->KeyLen = LEN_TKIP_EK;
		NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
			       LEN_TKIP_RXMICK);
		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
			       LEN_TKIP_TXMICK);

		/* Update Shared Key CipherAlg */
		pSharedKey->CipherAlg = CIPHER_NONE;
		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
			pSharedKey->CipherAlg = CIPHER_TKIP;
		else if (pAd->StaCfg.GroupCipher ==
			 Ndis802_11Encryption3Enabled)
			pSharedKey->CipherAlg = CIPHER_AES;
		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
			pSharedKey->CipherAlg = CIPHER_WEP64;
		else if (pAd->StaCfg.GroupCipher ==
			 Ndis802_11GroupWEP104Enabled)
			pSharedKey->CipherAlg = CIPHER_WEP128;

		/* Update group key information to ASIC Shared Key Table */
		AsicAddSharedKeyEntry(pAd,
				      BSS0,
				      pAd->StaCfg.DefaultKeyId,
				      pSharedKey->CipherAlg,
				      pSharedKey->Key,
				      pSharedKey->TxMic, pSharedKey->RxMic);

		/* Update ASIC WCID attribute table and IVEIV table */
		RTMPAddWcidAttributeEntry(pAd,
					  BSS0,
					  pAd->StaCfg.DefaultKeyId,
					  pSharedKey->CipherAlg, NULL);
	}

	return TRUE;

}

/*
	========================================================================

	Routine Description:
		Construct EAPoL message for WPA handshaking
		Its format is below,

		+--------------------+
		| Protocol Version	 |  1 octet
		+--------------------+
		| Protocol Type		 |	1 octet
		+--------------------+
		| Body Length		 |  2 octets
		+--------------------+
		| Descriptor Type	 |	1 octet
		+--------------------+
		| Key Information    |	2 octets
		+--------------------+
		| Key Length	     |  1 octet
		+--------------------+
		| Key Repaly Counter |	8 octets
		+--------------------+
		| Key Nonce		     |  32 octets
		+--------------------+
		| Key IV			 |  16 octets
		+--------------------+
		| Key RSC			 |  8 octets
		+--------------------+
		| Key ID or Reserved |	8 octets
		+--------------------+
		| Key MIC			 |	16 octets
		+--------------------+
		| Key Data Length	 |	2 octets
		+--------------------+
		| Key Data			 |	n octets
		+--------------------+

	Arguments:
		pAd			Pointer	to our adapter

	Return Value:
		None

	Note:

	========================================================================
*/
void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
		       u8 GroupKeyWepStatus,
		       u8 MsgType,
		       u8 DefaultKeyIdx,
		       u8 * KeyNonce,
		       u8 * TxRSC,
		       u8 * GTK,
		       u8 * RSNIE,
		       u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
{
	BOOLEAN bWPA2 = FALSE;
	u8 KeyDescVer;

	/* Choose WPA2 or not */
	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
		bWPA2 = TRUE;

	/* Init Packet and Fill header */
	pMsg->ProVer = EAPOL_VER;
	pMsg->ProType = EAPOLKey;

	/* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
	SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);

	/* Fill in EAPoL descriptor */
	if (bWPA2)
		pMsg->KeyDesc.Type = WPA2_KEY_DESC;
	else
		pMsg->KeyDesc.Type = WPA1_KEY_DESC;

	/* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
	{
		/* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */
		/* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */
		KeyDescVer =
		    (((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
		      || (GroupKeyWepStatus ==
			  Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
		     : (DESC_TYPE_TKIP));
	}

	pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;

	/* Specify Key Type as Group(0) or Pairwise(1) */
	if (MsgType >= EAPOL_GROUP_MSG_1)
		pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
	else
		pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;

	/* Specify Key Index, only group_msg1_WPA1 */
	if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
		pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;

	if (MsgType == EAPOL_PAIR_MSG_3)
		pMsg->KeyDesc.KeyInfo.Install = 1;

	if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
	    || (MsgType == EAPOL_GROUP_MSG_1))
		pMsg->KeyDesc.KeyInfo.KeyAck = 1;

	if (MsgType != EAPOL_PAIR_MSG_1)
		pMsg->KeyDesc.KeyInfo.KeyMic = 1;

	if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
	    (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
		pMsg->KeyDesc.KeyInfo.Secure = 1;
	}

	if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
		      (MsgType == EAPOL_GROUP_MSG_1))) {
		pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
	}
	/* key Information element has done. */
	*(u16 *) (&pMsg->KeyDesc.KeyInfo) =
	    cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));

	/* Fill in Key Length */
	{
		if (MsgType >= EAPOL_GROUP_MSG_1) {
			/* the length of group key cipher */
			pMsg->KeyDesc.KeyLength[1] =
			    ((GroupKeyWepStatus ==
			      Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH :
			     LEN_AES_KEY);
		} else {
			/* the length of pairwise key cipher */
			pMsg->KeyDesc.KeyLength[1] =
			    ((pEntry->WepStatus ==
			      Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
			     LEN_AES_KEY);
		}
	}

	/* Fill in replay counter */
	NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
		       LEN_KEY_DESC_REPLAY);

	/* Fill Key Nonce field */
	/* ANonce : pairwise_msg1 & pairwise_msg3 */
	/* SNonce : pairwise_msg2 */
	/* GNonce : group_msg1_wpa1 */
	if ((MsgType <= EAPOL_PAIR_MSG_3)
	    || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
		NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce,
			       LEN_KEY_DESC_NONCE);

	/* Fill key IV - WPA2 as 0, WPA1 as random */
	if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) {
		/* Suggest IV be random number plus some number, */
		NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16],
			       LEN_KEY_DESC_IV);
		pMsg->KeyDesc.KeyIv[15] += 2;
	}
	/* Fill Key RSC field */
	/* It contains the RSC for the GTK being installed. */
	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
	    || (MsgType == EAPOL_GROUP_MSG_1)) {
		NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
	}
	/* Clear Key MIC field for MIC calculation later */
	NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);

	ConstructEapolKeyData(pEntry,
			      GroupKeyWepStatus,
			      KeyDescVer,
			      MsgType,
			      DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);

	/* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */
	if (MsgType != EAPOL_PAIR_MSG_1) {
		CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
	}

	DBGPRINT(RT_DEBUG_TRACE,
		 ("===> ConstructEapolMsg for %s %s\n",
		  ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
	DBGPRINT(RT_DEBUG_TRACE,
		 ("	     Body length = %d \n",
		  CONV_ARRARY_TO_u16(pMsg->Body_Len)));
	DBGPRINT(RT_DEBUG_TRACE,
		 ("	     Key length  = %d \n",
		  CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength)));

}

/*
	========================================================================

	Routine Description:
		Construct the Key Data field of EAPoL message

	Arguments:
		pAd			Pointer	to our adapter
		Elem		Message body

	Return Value:
		None

	Note:

	========================================================================
*/
void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
			   u8 GroupKeyWepStatus,
			   u8 keyDescVer,
			   u8 MsgType,
			   u8 DefaultKeyIdx,
			   u8 * GTK,
			   u8 * RSNIE,
			   u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
{
	u8 *mpool, *Key_Data, *Rc4GTK;
	u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)];
	unsigned long data_offset;
	BOOLEAN bWPA2Capable = FALSE;
	struct rt_rtmp_adapter *pAd = pEntry->pAd;
	BOOLEAN GTK_Included = FALSE;

	/* Choose WPA2 or not */
	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
		bWPA2Capable = TRUE;

	if (MsgType == EAPOL_PAIR_MSG_1 ||
	    MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
		return;

	/* allocate memory pool */
	os_alloc_mem(NULL, (u8 **) & mpool, 1500);

	if (mpool == NULL)
		return;

	/* Rc4GTK Len = 512 */
	Rc4GTK = (u8 *) ROUND_UP(mpool, 4);
	/* Key_Data Len = 512 */
	Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4);

	NdisZeroMemory(Key_Data, 512);
	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
	data_offset = 0;

	/* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
	if (RSNIE_LEN
	    && ((MsgType == EAPOL_PAIR_MSG_2)
		|| (MsgType == EAPOL_PAIR_MSG_3))) {
		u8 *pmkid_ptr = NULL;
		u8 pmkid_len = 0;

		RTMPInsertRSNIE(&Key_Data[data_offset],
				&data_offset,
				RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
	}

	/* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
	if (bWPA2Capable
	    && ((MsgType == EAPOL_PAIR_MSG_3)
		|| (MsgType == EAPOL_GROUP_MSG_1))) {
		/* Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h */
		Key_Data[data_offset + 0] = 0xDD;

		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
			Key_Data[data_offset + 1] = 0x16;	/* 4+2+16(OUI+DataType+DataField) */
		} else {
			Key_Data[data_offset + 1] = 0x26;	/* 4+2+32(OUI+DataType+DataField) */
		}

		Key_Data[data_offset + 2] = 0x00;
		Key_Data[data_offset + 3] = 0x0F;
		Key_Data[data_offset + 4] = 0xAC;
		Key_Data[data_offset + 5] = 0x01;

		/* GTK KDE format - 802.11i-2004  Figure-43x */
		Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
		Key_Data[data_offset + 7] = 0x00;	/* Reserved Byte */

		data_offset += 8;
	}

	/* Encapsulate GTK */
	/* Only for pairwise_msg3_WPA2 and group_msg1 */
	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
	    || (MsgType == EAPOL_GROUP_MSG_1)) {
		/* Fill in GTK */
		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
			NdisMoveMemory(&Key_Data[data_offset], GTK,
				       LEN_AES_KEY);
			data_offset += LEN_AES_KEY;
		} else {
			NdisMoveMemory(&Key_Data[data_offset], GTK,
				       TKIP_GTK_LENGTH);
			data_offset += TKIP_GTK_LENGTH;
		}

		GTK_Included = TRUE;
	}

	/* This whole key-data field shall be encrypted if a GTK is included. */
	/* Encrypt the data material in key data field with KEK */
	if (GTK_Included) {
		/*hex_dump("GTK_Included", Key_Data, data_offset); */

		if ((keyDescVer == DESC_TYPE_AES)) {
			u8 remainder = 0;
			u8 pad_len = 0;

			/* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */
			/* shall be used to encrypt the Key Data field using the KEK field from */
			/* the derived PTK. */

			/* If the Key Data field uses the NIST AES key wrap, then the Key Data field */
			/* shall be padded before encrypting if the key data length is less than 16 */
			/* octets or if it is not a multiple of 8. The padding consists of appending */
			/* a single octet 0xdd followed by zero or more 0x00 octets. */
			if ((remainder = data_offset & 0x07) != 0) {
				int i;

				pad_len = (8 - remainder);
				Key_Data[data_offset] = 0xDD;
				for (i = 1; i < pad_len; i++)
					Key_Data[data_offset + i] = 0;

				data_offset += pad_len;
			}

			AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
					 data_offset, Rc4GTK);
			/* AES wrap function will grow 8 bytes in length */
			data_offset += 8;
		} else {
			/*      Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
			   using the KEK field from the derived PTK. */

			/* PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */
			/* put TxTsc in Key RSC field */
			pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;	/*Init crc32. */

			/* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
			NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
				       LEN_KEY_DESC_IV);
			NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
				       LEN_EAP_EK);
			ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));	/*INIT SBOX, KEYLEN+3(IV) */
			pAd->PrivateInfo.FCSCRC32 =
			    RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data,
					    data_offset);
			WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
					   Key_Data, data_offset);
		}

		NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
	} else {
		NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
	}

	/* Update key data length field and total body length */
	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
	INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset);

	os_free_mem(NULL, mpool);

}

/*
	========================================================================

	Routine Description:
		Calcaulate MIC. It is used during 4-ways handsharking.

	Arguments:
		pAd			-	pointer to our pAdapter context
	PeerWepStatus	-	indicate the encryption type

	Return Value:

	Note:

	========================================================================
*/
static void CalculateMIC(u8 KeyDescVer,
			 u8 * PTK, struct rt_eapol_packet * pMsg)
{
	u8 *OutBuffer;
	unsigned long FrameLen = 0;
	u8 mic[LEN_KEY_DESC_MIC];
	u8 digest[80];

	/* allocate memory for MIC calculation */
	os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);

	if (OutBuffer == NULL) {
		DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
		return;
	}
	/* make a frame for calculating MIC. */
	MakeOutgoingFrame(OutBuffer, &FrameLen,
			  CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
			  END_OF_ARGS);

	NdisZeroMemory(mic, sizeof(mic));

	/* Calculate MIC */
	if (KeyDescVer == DESC_TYPE_AES) {
		HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
			  SHA1_DIGEST_SIZE);
		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
	} else {
		HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
			 MD5_DIGEST_SIZE);
	}

	/* store the calculated MIC */
	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);

	os_free_mem(NULL, OutBuffer);
}

/*
	========================================================================

	Routine Description:
		Some received frames can't decrypt by Asic, so decrypt them by software.

	Arguments:
		pAd			-	pointer to our pAdapter context
	PeerWepStatus	-	indicate the encryption type

	Return Value:
		NDIS_STATUS_SUCCESS		-	decryption successful
		NDIS_STATUS_FAILURE		-	decryption failure

	========================================================================
*/
int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
					 struct rt_rx_blk *pRxBlk,
					 IN NDIS_802_11_ENCRYPTION_STATUS
					 GroupCipher, struct rt_cipher_key *pShard_key)
{
	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;

	/* handle WEP decryption */
	if (GroupCipher == Ndis802_11Encryption1Enabled) {
		if (RTMPSoftDecryptWEP
		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
		     pShard_key)) {

			/*Minus IV[4] & ICV[4] */
			pRxWI->MPDUtotalByteCount -= 8;
		} else {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("ERROR : Software decrypt WEP data fails.\n"));
			/* give up this frame */
			return NDIS_STATUS_FAILURE;
		}
	}
	/* handle TKIP decryption */
	else if (GroupCipher == Ndis802_11Encryption2Enabled) {
		if (RTMPSoftDecryptTKIP
		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
		     pShard_key)) {

			/*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
			pRxWI->MPDUtotalByteCount -= 20;
		} else {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
			/* give up this frame */
			return NDIS_STATUS_FAILURE;
		}
	}
	/* handle AES decryption */
	else if (GroupCipher == Ndis802_11Encryption3Enabled) {
		if (RTMPSoftDecryptAES
		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
		     pShard_key)) {

			/*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
			pRxWI->MPDUtotalByteCount -= 16;
		} else {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("ERROR : RTMPSoftDecryptAES Failed\n"));
			/* give up this frame */
			return NDIS_STATUS_FAILURE;
		}
	} else {
		/* give up this frame */
		return NDIS_STATUS_FAILURE;
	}

	return NDIS_STATUS_SUCCESS;

}

u8 *GetSuiteFromRSNIE(u8 *rsnie,
			 u32 rsnie_len, u8 type, u8 * count)
{
	struct rt_eid * pEid;
	int len;
	u8 *pBuf;
	int offset = 0;
	struct rt_rsnie_auth *pAkm;
	u16 acount;
	BOOLEAN isWPA2 = FALSE;

	pEid = (struct rt_eid *) rsnie;
	len = rsnie_len - 2;	/* exclude IE and length */
	pBuf = (u8 *)& pEid->Octet[0];

	/* set default value */
	*count = 0;

	/* Check length */
	if ((len <= 0) || (pEid->Len != len)) {
		DBGPRINT_ERR(("%s : The length is invalid\n", __func__));
		return NULL;
	}
	/* Check WPA or WPA2 */
	if (pEid->Eid == IE_WPA) {
		struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
		u16 ucount;

		if (len < sizeof(struct rt_rsnie)) {
			DBGPRINT_ERR(("%s : The length is too short for WPA\n",
				      __func__));
			return NULL;
		}
		/* Get the count of pairwise cipher */
		ucount = cpu2le16(pRsnie->ucount);
		if (ucount > 2) {
			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount));
			return NULL;
		}
		/* Get the group cipher */
		if (type == GROUP_SUITE) {
			*count = 1;
			return pRsnie->mcast;
		}
		/* Get the pairwise cipher suite */
		else if (type == PAIRWISE_SUITE) {
			DBGPRINT(RT_DEBUG_TRACE,
				 ("%s : The count of pairwise cipher is %d\n",
				  __func__, ucount));
			*count = ucount;
			return pRsnie->ucast[0].oui;
		}

		offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));

	} else if (pEid->Eid == IE_RSN) {
		struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
		u16 ucount;

		isWPA2 = TRUE;

		if (len < sizeof(struct rt_rsnie2)) {
			DBGPRINT_ERR(("%s : The length is too short for WPA2\n",
				      __func__));
			return NULL;
		}
		/* Get the count of pairwise cipher */
		ucount = cpu2le16(pRsnie->ucount);
		if (ucount > 2) {
			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount));
			return NULL;
		}
		/* Get the group cipher */
		if (type == GROUP_SUITE) {
			*count = 1;
			return pRsnie->mcast;
		}
		/* Get the pairwise cipher suite */
		else if (type == PAIRWISE_SUITE) {
			DBGPRINT(RT_DEBUG_TRACE,
				 ("%s : The count of pairwise cipher is %d\n",
				  __func__, ucount));
			*count = ucount;
			return pRsnie->ucast[0].oui;
		}

		offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));

	} else {
		DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __func__, pEid->Eid));
		return NULL;
	}

	/* skip group cipher and pairwise cipher suite */
	pBuf += offset;
	len -= offset;

	if (len < sizeof(struct rt_rsnie_auth)) {
		DBGPRINT_ERR(("%s : The length of RSNIE is too short\n",
			      __func__));
		return NULL;
	}
	/* pointer to AKM count */
	pAkm = (struct rt_rsnie_auth *)pBuf;

	/* Get the count of pairwise cipher */
	acount = cpu2le16(pAkm->acount);
	if (acount > 2) {
		DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n",
			      __func__, acount));
		return NULL;
	}
	/* Get the AKM suite */
	if (type == AKM_SUITE) {
		DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
					  __func__, acount));
		*count = acount;
		return pAkm->auth[0].oui;
	}
	offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));

	pBuf += offset;
	len -= offset;

	/* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */
	if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) {
		/* Skip RSN capability and PMKID-Count */
		pBuf += (sizeof(RSN_CAPABILITIES) + 2);
		len -= (sizeof(RSN_CAPABILITIES) + 2);

		/* Get PMKID */
		if (type == PMKID_LIST) {
			*count = 1;
			return pBuf;
		}
	} else {
		DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __func__));
		return NULL;
	}

	*count = 0;
	/*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
	return NULL;

}

void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
{
	u8 *pSuite = NULL;
	u8 count;

	hex_dump("RSNIE", rsnie, rsnie_len);

	/* group cipher */
	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count);
	if (pSuite != NULL) {
		hex_dump("group cipher", pSuite, 4 * count);
	}
	/* pairwise cipher */
	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count);
	if (pSuite != NULL) {
		hex_dump("pairwise cipher", pSuite, 4 * count);
	}
	/* AKM */
	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count);
	if (pSuite != NULL) {
		hex_dump("AKM suite", pSuite, 4 * count);
	}
	/* PMKID */
	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count);
	if (pSuite != NULL) {
		hex_dump("PMKID", pSuite, LEN_PMKID);
	}

}

void RTMPInsertRSNIE(u8 *pFrameBuf,
		     unsigned long *pFrameLen,
		     u8 *rsnie_ptr,
		     u8 rsnie_len,
		     u8 *pmkid_ptr, u8 pmkid_len)
{
	u8 *pTmpBuf;
	unsigned long TempLen = 0;
	u8 extra_len = 0;
	u16 pmk_count = 0;
	u8 ie_num;
	u8 total_len = 0;
	u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };

	pTmpBuf = pFrameBuf;

	/* PMKID-List Must larger than 0 and the multiple of 16. */
	if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) {
		extra_len = sizeof(u16)+ pmkid_len;

		pmk_count = (pmkid_len >> 4);
		pmk_count = cpu2le16(pmk_count);
	} else {
		DBGPRINT(RT_DEBUG_WARN,
			 ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
			  __func__, pmkid_len));
	}

	if (rsnie_len != 0) {
		ie_num = IE_WPA;
		total_len = rsnie_len;

		if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
			ie_num = IE_RSN;
			total_len += extra_len;
		}

		/* construct RSNIE body */
		MakeOutgoingFrame(pTmpBuf, &TempLen,
				  1, &ie_num,
				  1, &total_len,
				  rsnie_len, rsnie_ptr, END_OF_ARGS);

		pTmpBuf += TempLen;
		*pFrameLen = *pFrameLen + TempLen;

		if (ie_num == IE_RSN) {
			/* Insert PMKID-List field */
			if (extra_len > 0) {
				MakeOutgoingFrame(pTmpBuf, &TempLen,
						  2, &pmk_count,
						  pmkid_len, pmkid_ptr,
						  END_OF_ARGS);

				pTmpBuf += TempLen;
				*pFrameLen = *pFrameLen + TempLen;
			}
		}
	}

	return;
}
